This builds hq ADR 0358 (accepted, version 11) for hq issue 704, and fixes hq issue 709. Issue 709: mesh-lab's replays could run code a pull request wrote, while holding the container runtime's socket. This delivers together with mesh-catalog#297, which gives the build agent its judge cache. Both use the branch name fix/704-release-branch-judge, which makes them one delivery group.
§1 Which base is a release branch.releaseBranchOf asks the forge nothing for a base that is the repository's own trunk (the branch its module follows, or main when it records none) or mesh-controller's trunk. For any other base it asks the forge one question: does mesh-controller have a branch of that name? A 404 means no release branch. An answer that names no branch, names another branch, or cannot be read is an error.
§2 The release branch's controller judges.releaseJudge builds mesh-controller at the release branch. It uses mesh-host's validator from mesh-host's same-named branch, or the copy the judge vendors when there is none. A mesh-host pull request is judged with its own validator. A controller pull request judges itself.
§3 What is read beside the check. The controller, the node-engine, mesh-tools, the catalogue and mesh-sdk are read at the release branch, else at their trunk. mesh-controller-main stays at main. mesh-lab is always read at its trunk, and both the controller and the build seat enforce that.
§4 The verdict says it:release, judged-by, validator and beside-at. Both status summaries open with [release <branch>, judged by its controller <commit>].
§5 A release branch's move puts its verdicts out of date. This already held. mesh-catalog#297 adds the test, and this pull request asserts that the trunk commit is the release branch's head.
§6 Built and run where no pull request can reach. This covers every judge and mesh-lab's replays, with or without a judge cache:
Each run gets a fresh HOME and XDG_CONFIG_HOME, with GIT_CONFIG_GLOBAL=/dev/null, GIT_CONFIG_NOSYSTEM=1, GOENV=off, -buildvcs=false, and GOWORK=off for the replays.
Judges are built before anything of the change runs.
The replays run from a copy of mesh-lab's trunk made right after its clone, before anything of the change runs. Whether that copy holds replays is read at the same moment, so nothing written later decides it.
With a judge cache (MESH_JUDGE_CACHE): the copy and the homes are under its homes/, and the caches are its warm Go build cache and module cache. Only judge builds and the replays mount it. The replays may share it because their build is as trusted as a judge's: they run mesh-lab's trunk, which is reviewed code, against this check's judge, and nothing of the pull request except its catalogue, which they read as data.
Without a judge cache: the copy, the home and throwaway Go caches live in a container volume the check makes for itself. A container that mounts the workspace read-only fills the volume, before anything of the change runs. Only the replays mount the volume afterwards, and the check removes it at the end. Judges are built cold under the check's root, which is emptied before the clones. Nothing ever falls back to the workspace or to a temporary directory on the host.
§7 A release branch's pull request into its trunk is checked as any trunk pull request.
Trunk checks
The judge and the replays of a trunk check now run in the same isolated environment, which is stricter than before and closes issues 482 and 709 for them.
With the judge cache, a judge build stays warm: about 1 s, the reviewer's measurement.
Without it, a judge is compiled cold for every check: about 15 s on 12 cores and about 67 s on one, again the reviewer's figures. The replays' modules are then fetched again for every check.
What a trunk check reads beside it, and what its verdict says, are unchanged.
Proof (tests written first)
internal/builder:
the release judge and which validator it used, named in the verdict;
each repository named with its branch and commit;
the judge kept for each head, and the trunk commit is the release branch's head;
trunk checks are unchanged, including §7;
mesh-lab is never read at a release ref;
planted git hooks and Go env files do not run during judge builds;
with a judge cache, a planted -toolexec hook and poisoned caches are neither run nor read during the replays;
in both states, the reviewer's case: a self-judging controller pull request writes a test into mesh-lab's replays during the gate, with a planted GOFLAGS hook and a poisoned cache entry. None of it runs or is read. Without a judge cache, the check's own volume is made and removed. This test fails when the replays run from the workspace;
warm judge builds, nothing left behind, and the cold fallback.
cmd/mesh-controller: release detection, trunks, the forge's answer read strictly, the beside refs, §7, and the verdict's fields.
cmd/mesh-builder: release, else and MESH_JUDGE_CACHE are passed through.
Commands run: gofmt -l, go vet ./..., and merge-check.sh against a throwaway PostgreSQL over TCP 127.0.0.1 (dynamic_shared_memory_type=mmap). It exited 0, with no FAIL and no NOT RUN.
Rollout order
The delivery group is this pull request (mesh-controller, plus the build agent's mesh-builder image built from it) and mesh-catalog#297. The build agent's mesh-builder must carry this before the controller, or with it.
An old mesh-builder with a new controller, for a pull request into a release branch: it ignores release and else. mesh-lab is still asked at main. It builds the judge from mesh-controller at the release branch, by today's rule. A repository without the release branch fails its clone, so the check errors and never passes. The replays still run as on main today, open to issue 709, until the new mesh-builder lands.
A new mesh-builder, with or without #297 and with any controller: judges and replays are isolated as described above. Without #297 they are only cold.
Not done here: the forge's comment line "read beside it:" prints commits only.
Reviewer's checklist
ADR 0358 §1–§7, issue 704 and issue 709. Nothing outside the check path is touched.
The tests fail before the change and pass now. Existing tests are untouched.
A trunk pull request's request is unchanged. Only the environment its judge and replays run in is stricter.
No secret and no database change. Neither the socket nor the judge cache ever meets anything a pull request can write.
New fields are omitempty, and the readers are lenient.
gofmt, go vet, go test and merge-check.sh pass.
Words follow the glossary.
## What changed
This builds hq ADR 0358 (accepted, version 11) for hq issue 704, and fixes hq issue 709. Issue 709: mesh-lab's replays could run code a pull request wrote, while holding the container runtime's socket. **This delivers together with mesh-catalog#297, which gives the build agent its judge cache. Both use the branch name `fix/704-release-branch-judge`, which makes them one delivery group.**
- **§1 Which base is a release branch.** `releaseBranchOf` asks the forge nothing for a base that is the repository's own trunk (the branch its module follows, or main when it records none) or mesh-controller's trunk. For any other base it asks the forge one question: does mesh-controller have a branch of that name? A 404 means no release branch. An answer that names no branch, names another branch, or cannot be read is an error.
- **§2 The release branch's controller judges.** `releaseJudge` builds mesh-controller at the release branch. It uses mesh-host's validator from mesh-host's same-named branch, or the copy the judge vendors when there is none. A mesh-host pull request is judged with its own validator. A controller pull request judges itself.
- **§3 What is read beside the check.** The controller, the node-engine, mesh-tools, the catalogue and mesh-sdk are read at the release branch, else at their trunk. mesh-controller-main stays at main. **mesh-lab is always read at its trunk**, and both the controller and the build seat enforce that.
- **§4 The verdict says it:** `release`, `judged-by`, `validator` and `beside-at`. Both status summaries open with `[release <branch>, judged by its controller <commit>]`.
- **§5 A release branch's move puts its verdicts out of date.** This already held. mesh-catalog#297 adds the test, and this pull request asserts that the trunk commit is the release branch's head.
- **§6 Built and run where no pull request can reach.** This covers every judge and mesh-lab's replays, **with or without a judge cache**:
- Each run gets a fresh HOME and XDG_CONFIG_HOME, with `GIT_CONFIG_GLOBAL=/dev/null`, `GIT_CONFIG_NOSYSTEM=1`, `GOENV=off`, `-buildvcs=false`, and `GOWORK=off` for the replays.
- Judges are built before anything of the change runs.
- The replays run from a copy of mesh-lab's trunk made right after its clone, before anything of the change runs. Whether that copy holds replays is read at the same moment, so nothing written later decides it.
- **With a judge cache** (`MESH_JUDGE_CACHE`): the copy and the homes are under its homes/, and the caches are its warm Go build cache and module cache. Only judge builds and the replays mount it. **The replays may share it because their build is as trusted as a judge's:** they run mesh-lab's trunk, which is reviewed code, against this check's judge, and nothing of the pull request except its catalogue, which they read as data.
- **Without a judge cache**: the copy, the home and throwaway Go caches live in a container volume the check makes for itself. A container that mounts the workspace read-only fills the volume, before anything of the change runs. Only the replays mount the volume afterwards, and the check removes it at the end. Judges are built cold under the check's root, which is emptied before the clones. Nothing ever falls back to the workspace or to a temporary directory on the host.
- **§7 A release branch's pull request into its trunk** is checked as any trunk pull request.
## Trunk checks
The judge and the replays of a trunk check now run in the same isolated environment, which is stricter than before and closes issues 482 and 709 for them.
- With the judge cache, a judge build stays warm: about 1 s, the reviewer's measurement.
- Without it, a judge is compiled cold for every check: about 15 s on 12 cores and about 67 s on one, again the reviewer's figures. The replays' modules are then fetched again for every check.
What a trunk check reads beside it, and what its verdict says, are unchanged.
## Proof (tests written first)
- `internal/builder`:
- the release judge and which validator it used, named in the verdict;
- each repository named with its branch and commit;
- the judge kept for each head, and the trunk commit is the release branch's head;
- trunk checks are unchanged, including §7;
- mesh-lab is never read at a release ref;
- planted git hooks and Go env files do not run during judge builds;
- with a judge cache, a planted `-toolexec` hook and poisoned caches are neither run nor read during the replays;
- **in both states, the reviewer's case: a self-judging controller pull request writes a test into mesh-lab's replays during the gate, with a planted GOFLAGS hook and a poisoned cache entry. None of it runs or is read. Without a judge cache, the check's own volume is made and removed.** This test fails when the replays run from the workspace;
- warm judge builds, nothing left behind, and the cold fallback.
- `cmd/mesh-controller`: release detection, trunks, the forge's answer read strictly, the beside refs, §7, and the verdict's fields.
- `cmd/mesh-builder`: `release`, `else` and `MESH_JUDGE_CACHE` are passed through.
Commands run: `gofmt -l`, `go vet ./...`, and `merge-check.sh` against a throwaway PostgreSQL over TCP 127.0.0.1 (dynamic_shared_memory_type=mmap). It exited 0, with no FAIL and no NOT RUN.
## Rollout order
The delivery group is this pull request (mesh-controller, plus the build agent's mesh-builder image built from it) and mesh-catalog#297. **The build agent's mesh-builder must carry this before the controller, or with it.**
- **An old mesh-builder with a new controller**, for a pull request into a release branch: it ignores `release` and `else`. mesh-lab is still asked at main. It builds the judge from mesh-controller at the release branch, by today's rule. A repository without the release branch fails its clone, so the check errors and never passes. The replays still run as on main today, open to issue 709, until the new mesh-builder lands.
- **A new mesh-builder**, with or without #297 and with any controller: judges and replays are isolated as described above. Without #297 they are only cold.
Not done here: the forge's comment line "read beside it:" prints commits only.
## Reviewer's checklist
1. ADR 0358 §1–§7, issue 704 and issue 709. Nothing outside the check path is touched.
2. The tests fail before the change and pass now. Existing tests are untouched.
3. A trunk pull request's request is unchanged. Only the environment its judge and replays run in is stricter.
4. No secret and no database change. Neither the socket nor the judge cache ever meets anything a pull request can write.
5. New fields are `omitempty`, and the readers are lenient.
6. gofmt, go vet, go test and merge-check.sh pass.
7. Words follow the glossary.
mesh/merge-gate head 4a75cc51dda6 merged into trunk 535c7641ac41 — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every …
A release branch could never carry a change that needs another repository's
release-branch change: its pull requests were judged by the running controller
and against the other repositories' main (hq issue 704, ADR 0358).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deliverynovox/mesh-controller@847ffd6d1285 — ready since 2026-10-14T14:40:17Z
Delivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
tier 0: mesh-controller
tier 1: build-agent
ace: receives build-agent
g14: receives build-agent
novox: receives mesh-controller, build-agent
shanks: receives build-agent
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
2026-10-14 14:34 (new) → proposed (announced): novox/mesh-controller#329's head announced
2026-10-14 14:40 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit
2026-10-14 14:40 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-controller@847ffd6d1285` — **ready** since 2026-10-14T14:40:17Z
**Delivery plan** — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- ace: receives build-agent
- g14: receives build-agent
- novox: receives mesh-controller, build-agent
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
**Group** `fix/704-release-branch-judge`, in order:
- novox/mesh-catalog@47ef2644aca1 before novox/mesh-controller@847ffd6d1285: built by
- novox/mesh-controller@847ffd6d1285 before novox/mesh-catalog@47ef2644aca1: built by
- **refused**: novox/mesh-catalog@47ef2644aca1 and novox/mesh-controller@847ffd6d1285: built by puts novox/mesh-catalog@47ef2644aca1 first, built by puts novox/mesh-controller@847ffd6d1285 first, version skew puts novox/mesh-controller@847ffd6d1285 first; neither outranks the other: declare the order with a line `after: novox/mesh-catalog` in novox/mesh-controller#329's description, or `after: novox/mesh-controller` in novox/mesh-catalog#297's
**Transitions**
- 2026-10-14 14:34 (new) → proposed (announced): novox/mesh-controller#329's head announced
- 2026-10-14 14:40 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit
- 2026-10-14 14:40 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
mesh/merge-gate head ea7d91bff190 merged into trunk 535c7641ac41 — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every …
ADR 0358 version 4 asks the verdict to say whether mesh-host's release-branch
validator or the vendored one judged, and checks that a release branch's own
pull request into its trunk is judged as any trunk pull request (issue 704).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge check at 4a75cc51
Judged: head 4a75cc51dda6 merged into trunk 535c7641ac41; read beside it: mesh-catalog b15846dd6e78, mesh-controller-main 535c7641ac41, mesh-host 1a2677882380, mesh-tools 954e1a53eef9
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
mesh/repo-check: PASS — its merge-check.sh passed
Delivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
tier 0: mesh-controller
tier 1: build-agent
ace: receives build-agent
g14: receives build-agent
novox: receives mesh-controller, build-agent
shanks: receives build-agent
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on novox as build-1791982177864857946 (builds --log build-1791982177864857946).
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T12:37:05Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T12:37:05Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.270s
ok github.com/novox/mesh-controller/cmd/mesh-controller 268.487s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.016s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.054s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.020s
ok github.com/novox/mesh-controller/examples/route-proxy 1.174s
ok github.com/novox/mesh-controller/internal/artifacts 1.078s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 7.292s
ok github.com/novox/mesh-controller/internal/builder 94.639s
ok github.com/novox/mesh-controller/internal/catalogue 14.576s
ok github.com/novox/mesh-controller/internal/conditions 3.225s
ok github.com/novox/mesh-controller/internal/envfile 1.038s
ok github.com/novox/mesh-controller/internal/facts 1.040s
ok github.com/novox/mesh-controller/internal/identity 10.758s
ok github.com/novox/mesh-controller/internal/inventory 58.618s
ok github.com/novox/mesh-controller/internal/lease 17.792s
ok github.com/novox/mesh-controller/internal/licences 8.936s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.020s
ok github.com/novox/mesh-controller/internal/link 65.440s
ok github.com/novox/mesh-controller/internal/lint 3.585s
ok github.com/novox/mesh-controller/internal/outward 1.121s
ok github.com/novox/mesh-controller/internal/overlay 1.084s
ok github.com/novox/mesh-controller/internal/secrets 2.039s
ok github.com/novox/mesh-controller/internal/store 5.980s
ok github.com/novox/mesh-controller/internal/testbus 1.390s
ok github.com/novox/mesh-controller/internal/token 1.019s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.25s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.25s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.33s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.59s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.34s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.24s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (2.04s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.36s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.16s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.30s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.31s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.24s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (4.79s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (1.40s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.59s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.38s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.22s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.34s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.30s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.35s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.28s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.37s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.48s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.24s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.17s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.21s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.34s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.32s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.37s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.27s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.22s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.37s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.20s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.17s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.25s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.08s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.78s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.45s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.22s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.22s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.21s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.28s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.63s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.20s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.19s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.26s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.37s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.28s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.25s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.29s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.30s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.21s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.23s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.25s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.25s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.27s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.31s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.19s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.12s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.09s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.23s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.19s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.12s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.15s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.08s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.08s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.08s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.36s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.15s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.10s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.16s)
**Merge check** at `4a75cc51`
Judged: head `4a75cc51dda6` merged into trunk `535c7641ac41`; read beside it: mesh-catalog `b15846dd6e78`, mesh-controller-main `535c7641ac41`, mesh-host `1a2677882380`, mesh-tools `954e1a53eef9`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- ace: receives build-agent
- g14: receives build-agent
- novox: receives mesh-controller, build-agent
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
- read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on novox as `build-1791982177864857946` (`builds --log build-1791982177864857946`).
```
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T12:37:05Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T12:37:05Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.270s
ok github.com/novox/mesh-controller/cmd/mesh-controller 268.487s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.016s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.054s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.020s
ok github.com/novox/mesh-controller/examples/route-proxy 1.174s
ok github.com/novox/mesh-controller/internal/artifacts 1.078s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 7.292s
ok github.com/novox/mesh-controller/internal/builder 94.639s
ok github.com/novox/mesh-controller/internal/catalogue 14.576s
ok github.com/novox/mesh-controller/internal/conditions 3.225s
ok github.com/novox/mesh-controller/internal/envfile 1.038s
ok github.com/novox/mesh-controller/internal/facts 1.040s
ok github.com/novox/mesh-controller/internal/identity 10.758s
ok github.com/novox/mesh-controller/internal/inventory 58.618s
ok github.com/novox/mesh-controller/internal/lease 17.792s
ok github.com/novox/mesh-controller/internal/licences 8.936s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.020s
ok github.com/novox/mesh-controller/internal/link 65.440s
ok github.com/novox/mesh-controller/internal/lint 3.585s
ok github.com/novox/mesh-controller/internal/outward 1.121s
ok github.com/novox/mesh-controller/internal/overlay 1.084s
ok github.com/novox/mesh-controller/internal/secrets 2.039s
ok github.com/novox/mesh-controller/internal/store 5.980s
ok github.com/novox/mesh-controller/internal/testbus 1.390s
ok github.com/novox/mesh-controller/internal/token 1.019s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.25s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.25s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.33s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.59s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.34s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.24s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (2.04s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.36s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.16s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.30s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.31s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.24s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (4.79s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (1.40s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.59s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.38s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.22s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.34s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.30s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.35s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.28s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.37s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.48s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.24s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.17s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.21s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.34s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.32s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.37s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.27s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.22s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.37s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.20s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.17s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.25s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.08s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.78s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.45s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.22s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.22s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.21s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.28s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.63s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.20s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.19s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.26s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.37s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.28s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.25s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.29s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.30s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.21s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.23s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.25s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.25s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.27s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.31s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.19s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.12s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.09s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.23s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.19s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.12s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.15s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.08s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.08s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.08s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.36s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.15s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.10s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.16s)
```
Merge check at ea7d91bf
Judged: head ea7d91bff190 merged into trunk 535c7641ac41; read beside it: mesh-catalog b15846dd6e78, mesh-controller-main 535c7641ac41, mesh-host 1a2677882380, mesh-tools 954e1a53eef9
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
mesh/repo-check: PASS — its merge-check.sh passed
Delivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
tier 0: mesh-controller
tier 1: build-agent
ace: receives build-agent
g14: receives build-agent
novox: receives mesh-controller, build-agent
shanks: receives build-agent
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on shanks as build-1791982647000590148 (builds --log build-1791982647000590148).
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T12:37:05Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T12:37:05Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.091s
ok github.com/novox/mesh-controller/cmd/mesh-controller 184.008s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.057s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.057s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.040s
ok github.com/novox/mesh-controller/examples/route-proxy 1.223s
ok github.com/novox/mesh-controller/internal/artifacts 1.086s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.590s
ok github.com/novox/mesh-controller/internal/builder 57.211s
ok github.com/novox/mesh-controller/internal/catalogue 8.638s
ok github.com/novox/mesh-controller/internal/conditions 2.698s
ok github.com/novox/mesh-controller/internal/envfile 1.056s
ok github.com/novox/mesh-controller/internal/facts 1.054s
ok github.com/novox/mesh-controller/internal/identity 5.115s
ok github.com/novox/mesh-controller/internal/inventory 37.430s
ok github.com/novox/mesh-controller/internal/lease 17.733s
ok github.com/novox/mesh-controller/internal/licences 4.183s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.054s
ok github.com/novox/mesh-controller/internal/link 59.854s
ok github.com/novox/mesh-controller/internal/lint 2.580s
ok github.com/novox/mesh-controller/internal/outward 1.108s
ok github.com/novox/mesh-controller/internal/overlay 1.077s
ok github.com/novox/mesh-controller/internal/secrets 1.566s
ok github.com/novox/mesh-controller/internal/store 3.540s
ok github.com/novox/mesh-controller/internal/testbus 1.281s
ok github.com/novox/mesh-controller/internal/token 1.015s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.23s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.24s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.23s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.22s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.21s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.18s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.97s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.25s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.13s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.26s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.26s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.21s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.28s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.26s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.22s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.21s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.22s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.21s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.23s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.29s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.28s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.16s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.16s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.16s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.40s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.25s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.29s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.26s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.20s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.21s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.20s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.16s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.20s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.08s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.47s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.29s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.21s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.21s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.20s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.20s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.57s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.19s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.19s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.24s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.30s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.25s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.19s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.25s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.19s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.20s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.22s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.22s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.23s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.17s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.16s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.08s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.09s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.09s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.09s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.07s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.07s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.07s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.07s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.07s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.08s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.09s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.08s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.09s)
**Merge check** at `ea7d91bf`
Judged: head `ea7d91bff190` merged into trunk `535c7641ac41`; read beside it: mesh-catalog `b15846dd6e78`, mesh-controller-main `535c7641ac41`, mesh-host `1a2677882380`, mesh-tools `954e1a53eef9`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- ace: receives build-agent
- g14: receives build-agent
- novox: receives mesh-controller, build-agent
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
- read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on shanks as `build-1791982647000590148` (`builds --log build-1791982647000590148`).
```
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T12:37:05Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T12:37:05Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.091s
ok github.com/novox/mesh-controller/cmd/mesh-controller 184.008s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.057s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.057s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.040s
ok github.com/novox/mesh-controller/examples/route-proxy 1.223s
ok github.com/novox/mesh-controller/internal/artifacts 1.086s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.590s
ok github.com/novox/mesh-controller/internal/builder 57.211s
ok github.com/novox/mesh-controller/internal/catalogue 8.638s
ok github.com/novox/mesh-controller/internal/conditions 2.698s
ok github.com/novox/mesh-controller/internal/envfile 1.056s
ok github.com/novox/mesh-controller/internal/facts 1.054s
ok github.com/novox/mesh-controller/internal/identity 5.115s
ok github.com/novox/mesh-controller/internal/inventory 37.430s
ok github.com/novox/mesh-controller/internal/lease 17.733s
ok github.com/novox/mesh-controller/internal/licences 4.183s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.054s
ok github.com/novox/mesh-controller/internal/link 59.854s
ok github.com/novox/mesh-controller/internal/lint 2.580s
ok github.com/novox/mesh-controller/internal/outward 1.108s
ok github.com/novox/mesh-controller/internal/overlay 1.077s
ok github.com/novox/mesh-controller/internal/secrets 1.566s
ok github.com/novox/mesh-controller/internal/store 3.540s
ok github.com/novox/mesh-controller/internal/testbus 1.281s
ok github.com/novox/mesh-controller/internal/token 1.015s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.23s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.24s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.23s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.22s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.21s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.18s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.97s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.25s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.13s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.26s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.26s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.21s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.28s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.26s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.22s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.21s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.22s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.21s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.23s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.29s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.28s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.16s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.16s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.16s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.40s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.25s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.29s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.26s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.20s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.21s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.20s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.16s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.20s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.08s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.47s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.29s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.21s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.21s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.20s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.20s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.57s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.19s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.19s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.24s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.30s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.25s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.19s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.25s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.19s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.20s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.22s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.22s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.23s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.17s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.16s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.08s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.09s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.09s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.09s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.07s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.07s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.07s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.07s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.07s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.08s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.09s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.08s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.09s)
```
Independent review of novox/mesh-controller#329 at ea7d91bff1 (4a75cc51 plus ea7d91bf), for issue 704 and ADR 0358. ADR 0358 is proposed, not accepted: it is at version 7, and its latest knowledge-base review (13:02 UTC) says "changes", on the same point as finding 1 below.
What I ran in my own worktree: gofmt -l cmd internal examples printed nothing. go vet ./... passed. merge-check.sh exited 0 against a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap), with 26 packages ok. I stopped the server afterwards.
What I checked and found correct:
A trunk check is unchanged. I ran one catalogue pull request into main through builder.Check on main 535c7641 and on this head, and compared the verdict and the log. They are identical apart from timestamps and the four new empty fields, which are omitempty on the wire. besideOf(…, "") gives the same refs as before. A base of main, of the module's followed branch or of the controller's trunk asks the forge nothing.
The forge question.gitea_api really does answer {"result":{"name":…}}, and a missing branch really does fail with …: 404 {…}; I checked both on the live forge. An unanswered forge errors the check.
The judge. It is built from mesh-controller beside the check, at the release branch. It is built before any code of the change runs, and it is kept outside the mounted workspace. The cache key is the full commit of the controller, plus mesh-host's commit when mesh-host's validator is used. When the branch moves, the key changes, so a stale judge cannot be served. A controller pull request still judges itself.
Rollout. A new builder with an old controller gets no release/else and checks as before. An old builder with a new controller checks out feat/57-… in every repository beside the check. mesh-lab and mesh-tools have no such branch (404 on the live forge), so today that check errors.
The tests fail when their part is reverted. I reverted 20 parts one at a time (forge error, followed branch, beside refs, siblings, checkedOf, the else ref, the cache's location, the release judge, the host validator, the cache, the release mark, beside-at, the validator field, the vendored case, and clause 5's mark). The test for that part failed every time.
Findings:
Must change: unreviewed mesh-lab code gets the container runtime's socket. The change is in cmd/mesh-controller/checks.go:316, which reads mesh-lab at the release branch, else main. internal/builder/check.go:1001-1013 runs mesh-lab's replays/ with /var/run/docker.sock mounted. The design behind it, check.go:64 and :998 ("mesh-lab's main, reviewed code — get the socket"), allows that only for mesh-lab's main. With this change, anyone who can create a branch with a release branch's name in mesh-lab gets root on the build node at the next release-branch check. Nothing checks that the branch is protected. Keep mesh-lab at main, as the ADR review asks, and add a test for it.
Should: an unexpected forge answer reads as "no release branch". At checks.go:404, a 200 answer whose result.name is empty or missing returns false with no error, so the check runs as a trunk check. An empty name should be an error.
Should: the base == "main" guard is untested. The guard is at checks.go:334. The test entries all record Ref: "main", so the followed-branch guard already covers that case, and removing the main guard passes every test. Add a case where a module records Ref: "".
Should, can follow: a cached judge can keep a poisoned Go cache. The release judge is built with GOCACHE=<workspace>/go-cache (check.go:1134). The change's own script writes to that same cache (check.go:612). This weakness existed before (issue 482, shared build caches), but the judge cache now keeps a judge built from a poisoned Go cache for every check of that head. Build the release judge with a Go cache outside the workspace.
Note: the rollout claim is narrower than stated. "An old builder errors, never passes" holds only because some repository beside the check lacks the branch. If every repository had it, an old builder would judge with the release branch's controller under the label "the controller the mesh runs", with no validator swap and no release mark.
Verdict: CHANGES at ea7d91bff190
Independent review of novox/mesh-controller#329 at ea7d91bff190 (4a75cc51 plus ea7d91bf), for issue 704 and ADR 0358. ADR 0358 is **proposed, not accepted**: it is at version 7, and its latest knowledge-base review (13:02 UTC) says "changes", on the same point as finding 1 below.
What I ran in my own worktree: `gofmt -l cmd internal examples` printed nothing. `go vet ./...` passed. `merge-check.sh` exited 0 against a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap), with 26 packages ok. I stopped the server afterwards.
What I checked and found correct:
- **A trunk check is unchanged.** I ran one catalogue pull request into main through `builder.Check` on main 535c7641 and on this head, and compared the verdict and the log. They are identical apart from timestamps and the four new empty fields, which are `omitempty` on the wire. `besideOf(…, "")` gives the same refs as before. A base of `main`, of the module's followed branch or of the controller's trunk asks the forge nothing.
- **The forge question.** `gitea_api` really does answer `{"result":{"name":…}}`, and a missing branch really does fail with `…: 404 {…}`; I checked both on the live forge. An unanswered forge errors the check.
- **The judge.** It is built from `mesh-controller` beside the check, at the release branch. It is built before any code of the change runs, and it is kept outside the mounted workspace. The cache key is the full commit of the controller, plus mesh-host's commit when mesh-host's validator is used. When the branch moves, the key changes, so a stale judge cannot be served. A controller pull request still judges itself.
- **Rollout.** A new builder with an old controller gets no `release`/`else` and checks as before. An old builder with a new controller checks out `feat/57-…` in every repository beside the check. mesh-lab and mesh-tools have no such branch (404 on the live forge), so today that check errors.
- **The tests fail when their part is reverted.** I reverted 20 parts one at a time (forge error, followed branch, beside refs, siblings, checkedOf, the else ref, the cache's location, the release judge, the host validator, the cache, the release mark, beside-at, the validator field, the vendored case, and clause 5's mark). The test for that part failed every time.
Findings:
1. **Must change: unreviewed mesh-lab code gets the container runtime's socket.** The change is in cmd/mesh-controller/checks.go:316, which reads mesh-lab at the release branch, else main. internal/builder/check.go:1001-1013 runs mesh-lab's `replays/` with `/var/run/docker.sock` mounted. The design behind it, check.go:64 and :998 ("mesh-lab's main, reviewed code — get the socket"), allows that only for mesh-lab's main. With this change, anyone who can create a branch with a release branch's name in mesh-lab gets root on the build node at the next release-branch check. Nothing checks that the branch is protected. Keep mesh-lab at main, as the ADR review asks, and add a test for it.
2. **Should: an unexpected forge answer reads as "no release branch".** At checks.go:404, a 200 answer whose `result.name` is empty or missing returns false with no error, so the check runs as a trunk check. An empty name should be an error.
3. **Should: the `base == "main"` guard is untested.** The guard is at checks.go:334. The test entries all record `Ref: "main"`, so the followed-branch guard already covers that case, and removing the `main` guard passes every test. Add a case where a module records `Ref: ""`.
4. **Should, can follow: a cached judge can keep a poisoned Go cache.** The release judge is built with `GOCACHE=<workspace>/go-cache` (check.go:1134). The change's own script writes to that same cache (check.go:612). This weakness existed before (issue 482, shared build caches), but the judge cache now keeps a judge built from a poisoned Go cache for every check of that head. Build the release judge with a Go cache outside the workspace.
5. **Note: the rollout claim is narrower than stated.** "An old builder errors, never passes" holds only because some repository beside the check lacks the branch. If every repository had it, an old builder would judge with the release branch's controller under the label "the controller the mesh runs", with no validator swap and no release mark.
Review of #329: mesh-lab's replays run with the container runtime's socket, so
a same-named branch must never be what runs there; the shared Go cache and HOME
are writable by a pull request's own script, so the judge kept for a head must
not be built from them (issue 704, issue 482). A forge answer naming no branch
is an error, and a trunk is the branch a repository follows, not a name.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This is an independent review of novox/mesh-controller#329 at 48b2906b5c, for issue 704 and ADR 0358. ADR 0358 is still proposed, at version 9. The knowledge base's latest review, of version 8, says "changes", and version 9 has no review yet.
What I ran in my own worktree
gofmt -l cmd internal examples printed nothing.
go vet ./... passed.
merge-check.sh exited 0 against a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap). 26 packages were ok, with no FAIL and no NOT RUN. I stopped the server afterwards.
What I checked and found correct
A trunk check is unchanged. I ran the same catalogue pull request into main through builder.Check on main 535c7641 and on this head. The verdict and the log are identical apart from fresh commit ids, the time taken and four new empty fields. Those fields are omitempty on the wire.
Review point 1 (mesh-lab). The controller (checks.go:316-319) gives mesh-lab Ref: main with no Else for a release branch. The build seat (check.go:432) turns a Ref: <release>, Else: main request for mesh-lab into main. I reverted each of these on its own, and each time its test failed (TestBesideAReleaseBranch…, TestAReleaseBranchCheckReadsMeshLabAtItsTrunkEvenWhenItHasThatBranch).
Review point 3 (forge answer).branchAnswered treats an empty name, another name, an unreadable answer and a non-404 error as errors. With the lenient line restored, the test fails.
Review point 4 (trunk).trunkOf is tested with master and with a controller that follows trunk. Restoring the base == "main" guard makes the test fail.
Review point 5 (rollout order). The PR body's account of an old build seat with a new controller is accurate. An old seat reads only Repository and Ref (mesh-builder main.go:461) and ignores unknown JSON. It gets mesh-lab at main. It builds its judge from the release branch with today's rule. Because the old seat has no fallback, it errors whenever a repository lacks the branch. mesh-tools has no feat/57-config-and-provisioning today: I got a 404 from the live forge. The delivery plan moves the controller in tier 0 and build-agent in tier 1, so the "or in the same walk" window exists, and the body describes what happens during it.
The judge cache key is the controller's full commit, plus mesh-host's commit when its validator is used. When the branch moves, the key moves, so a stale judge is never served. The cache is at <workspace>-judges, which no container mounts.
Findings
Must change: the release judge's build still reads the workspace through HOME, so a pull request's script can plant code in the judge that is kept for that head. The location is internal/builder/check.go:1142-1144, together with check.go:570. Every toolchain container, the judge's build included, runs with HOME=<workspace> and the workspace mounted read-write. The workspace's HOME is never cleaned: forgetLeftCredentials removes only git-credentials and .npmrc. go build stamps the version from git (-buildvcs is not off), and git reads $HOME/.gitconfig. One pull request's merge-check.sh can therefore write <workspace>/.gitconfig with core.fsmonitor = <script>. At the next release-branch check, that script runs inside the judge's build, before compilation, and can rewrite the release controller's sources under check/mesh-controller. The poisoned judge is then kept in the judge cache under the honest commit key, and it judges every check of that head. I reproduced this locally: with HOME holding such a .gitconfig, GOENV=off and a fresh GOCACHE, go build produced a binary from sources the hook rewrote, while HEAD, and so the cache key, stayed at its commit. GOENV=off closes only Go's own environment file.
Fix: build the judge with a HOME of its own under the check's root (and XDG_CONFIG_HOME there too), GIT_CONFIG_GLOBAL=/dev/null, GIT_CONFIG_NOSYSTEM=1, and -buildvcs=false as the toolchain already uses (toolchain.go:176).
Test: plant a .gitconfig in the workspace's HOME, and prove the kept judge does not change.
Must change: for a node-engine pull request into a release branch, the judge that actually judges is built with the workspace's shared Go cache. The location is check.go:1082-1084, in the validator rebuild (judge-with-this-validator). It still uses GOCACHE=<workspace>/go-cache and the workspace HOME. That judge is not kept across checks, but it is the release judge of that check, and the review asked for a cache no pull request's script can write. Use the same fresh cache and environment as in finding 1.
Should, can follow: the build seat's mesh-lab guard keys on Else, not on the release branch. At check.go:432, a request of Ref: <release> with no Else for mesh-lab is still cloned at the release branch. The current controller never sends that request, so this is defence in depth. Still, the PR body says the seat "refuses a release ref for mesh-lab", and the code does not. Key the guard on spec.Release != "" && b.Ref == spec.Release, or refuse any ref but main, and test that case.
Should, can follow: trunkOf's "main when it records none" fallback is untested. It is at cmd/mesh-controller/checks.go:372. Replacing trunkOf with followedBranch passes every test. This is the earlier review's point 3 (a module that records Ref: ""). A repository with no module is never compared with its forge default branch, only asked about once (a 404 means no release branch). That is acceptable, but say so in the comment.
Verdict: CHANGES at 48b2906b5ce4
This is an independent review of novox/mesh-controller#329 at 48b2906b5ce4f826fab760e834320ef5c7273b24, for issue 704 and ADR 0358. ADR 0358 is still **proposed**, at version 9. The knowledge base's latest review, of version 8, says "changes", and version 9 has no review yet.
**What I ran in my own worktree**
- `gofmt -l cmd internal examples` printed nothing.
- `go vet ./...` passed.
- `merge-check.sh` exited 0 against a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap). 26 packages were ok, with no FAIL and no NOT RUN. I stopped the server afterwards.
**What I checked and found correct**
- **A trunk check is unchanged.** I ran the same catalogue pull request into main through `builder.Check` on main 535c7641 and on this head. The verdict and the log are identical apart from fresh commit ids, the time taken and four new empty fields. Those fields are `omitempty` on the wire.
- **Review point 1 (mesh-lab).** The controller (checks.go:316-319) gives mesh-lab `Ref: main` with no `Else` for a release branch. The build seat (check.go:432) turns a `Ref: <release>, Else: main` request for mesh-lab into main. I reverted each of these on its own, and each time its test failed (`TestBesideAReleaseBranch…`, `TestAReleaseBranchCheckReadsMeshLabAtItsTrunkEvenWhenItHasThatBranch`).
- **Review point 3 (forge answer).** `branchAnswered` treats an empty name, another name, an unreadable answer and a non-404 error as errors. With the lenient line restored, the test fails.
- **Review point 4 (trunk).** `trunkOf` is tested with `master` and with a controller that follows `trunk`. Restoring the `base == "main"` guard makes the test fail.
- **Review point 5 (rollout order).** The PR body's account of an old build seat with a new controller is accurate. An old seat reads only Repository and Ref (mesh-builder main.go:461) and ignores unknown JSON. It gets mesh-lab at main. It builds its judge from the release branch with today's rule. Because the old seat has no fallback, it errors whenever a repository lacks the branch. mesh-tools has no `feat/57-config-and-provisioning` today: I got a 404 from the live forge. The delivery plan moves the controller in tier 0 and build-agent in tier 1, so the "or in the same walk" window exists, and the body describes what happens during it.
- **The judge cache key** is the controller's full commit, plus mesh-host's commit when its validator is used. When the branch moves, the key moves, so a stale judge is never served. The cache is at `<workspace>-judges`, which no container mounts.
**Findings**
1. **Must change: the release judge's build still reads the workspace through HOME, so a pull request's script can plant code in the judge that is kept for that head.** The location is internal/builder/check.go:1142-1144, together with check.go:570. Every toolchain container, the judge's build included, runs with `HOME=<workspace>` and the workspace mounted read-write. The workspace's HOME is never cleaned: `forgetLeftCredentials` removes only `git-credentials` and `.npmrc`. `go build` stamps the version from git (`-buildvcs` is not off), and git reads `$HOME/.gitconfig`. One pull request's `merge-check.sh` can therefore write `<workspace>/.gitconfig` with `core.fsmonitor = <script>`. At the next release-branch check, that script runs inside the judge's build, before compilation, and can rewrite the release controller's sources under `check/mesh-controller`. The poisoned judge is then kept in the judge cache under the honest commit key, and it judges every check of that head. I reproduced this locally: with `HOME` holding such a `.gitconfig`, `GOENV=off` and a fresh `GOCACHE`, `go build` produced a binary from sources the hook rewrote, while HEAD, and so the cache key, stayed at its commit. `GOENV=off` closes only Go's own environment file.
- Fix: build the judge with a HOME of its own under the check's root (and `XDG_CONFIG_HOME` there too), `GIT_CONFIG_GLOBAL=/dev/null`, `GIT_CONFIG_NOSYSTEM=1`, and `-buildvcs=false` as the toolchain already uses (toolchain.go:176).
- Test: plant a `.gitconfig` in the workspace's HOME, and prove the kept judge does not change.
2. **Must change: for a node-engine pull request into a release branch, the judge that actually judges is built with the workspace's shared Go cache.** The location is check.go:1082-1084, in the validator rebuild (`judge-with-this-validator`). It still uses `GOCACHE=<workspace>/go-cache` and the workspace HOME. That judge is not kept across checks, but it is the release judge of that check, and the review asked for a cache no pull request's script can write. Use the same fresh cache and environment as in finding 1.
3. **Should, can follow: the build seat's mesh-lab guard keys on `Else`, not on the release branch.** At check.go:432, a request of `Ref: <release>` with no `Else` for mesh-lab is still cloned at the release branch. The current controller never sends that request, so this is defence in depth. Still, the PR body says the seat "refuses a release ref for mesh-lab", and the code does not. Key the guard on `spec.Release != "" && b.Ref == spec.Release`, or refuse any ref but main, and test that case.
4. **Should, can follow: `trunkOf`'s "main when it records none" fallback is untested.** It is at cmd/mesh-controller/checks.go:372. Replacing `trunkOf` with `followedBranch` passes every test. This is the earlier review's point 3 (a module that records `Ref: ""`). A repository with no module is never compared with its forge default branch, only asked about once (a 404 means no release branch). That is acceptable, but say so in the comment.
Merge check at 48b2906b
Judged: head 48b2906b5ce4 merged into trunk 535c7641ac41; read beside it: mesh-catalog 50861c74f8b4, mesh-controller-main 535c7641ac41, mesh-host 1a2677882380, mesh-tools 954e1a53eef9
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
mesh/repo-check: PASS — its merge-check.sh passed
Delivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
tier 0: mesh-controller
tier 1: build-agent
ace: receives build-agent
g14: receives build-agent
novox: receives mesh-controller, build-agent
shanks: receives build-agent
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on novox as build-1791983635010871240 (builds --log build-1791983635010871240).
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:05:20Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:05:20Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.962s
ok github.com/novox/mesh-controller/cmd/mesh-controller 309.956s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.074s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 2.017s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.066s
ok github.com/novox/mesh-controller/examples/route-proxy 2.186s
ok github.com/novox/mesh-controller/internal/artifacts 1.205s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 16.046s
ok github.com/novox/mesh-controller/internal/builder 150.783s
ok github.com/novox/mesh-controller/internal/catalogue 17.327s
ok github.com/novox/mesh-controller/internal/conditions 5.347s
ok github.com/novox/mesh-controller/internal/envfile 2.003s
ok github.com/novox/mesh-controller/internal/facts 1.089s
ok github.com/novox/mesh-controller/internal/identity 21.411s
ok github.com/novox/mesh-controller/internal/inventory 116.442s
ok github.com/novox/mesh-controller/internal/lease 21.117s
ok github.com/novox/mesh-controller/internal/licences 19.195s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.026s
ok github.com/novox/mesh-controller/internal/link 91.456s
ok github.com/novox/mesh-controller/internal/lint 2.681s
ok github.com/novox/mesh-controller/internal/outward 1.040s
ok github.com/novox/mesh-controller/internal/overlay 1.064s
ok github.com/novox/mesh-controller/internal/secrets 1.703s
ok github.com/novox/mesh-controller/internal/store 10.436s
ok github.com/novox/mesh-controller/internal/testbus 2.179s
ok github.com/novox/mesh-controller/internal/token 1.029s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.28s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.25s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.24s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.23s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.23s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.26s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (2.00s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.41s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.13s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.30s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.28s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.30s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.29s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.28s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.22s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.31s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.23s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.23s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.40s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.36s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.31s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.16s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.16s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.18s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.35s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.36s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.42s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.30s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.59s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.37s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.20s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.30s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.09s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.66s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.33s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.22s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.22s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.21s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.41s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (1.25s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.19s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.20s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.26s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.43s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.28s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.27s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.22s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.28s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.20s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.31s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.25s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.24s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.35s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.18s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.18s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.09s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.09s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.10s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.09s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.07s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.12s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.07s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.08s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.08s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.12s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.12s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.09s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.09s)
Out of date when it landed: out of date: judged against trunk 535c7641ac, the trunk is now c975dbf7b053; judged again on a recheck or when it is merged
**Merge check** at `48b2906b`
Judged: head `48b2906b5ce4` merged into trunk `535c7641ac41`; read beside it: mesh-catalog `50861c74f8b4`, mesh-controller-main `535c7641ac41`, mesh-host `1a2677882380`, mesh-tools `954e1a53eef9`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- ace: receives build-agent
- g14: receives build-agent
- novox: receives mesh-controller, build-agent
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
- read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on novox as `build-1791983635010871240` (`builds --log build-1791983635010871240`).
```
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:05:20Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:05:20Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.962s
ok github.com/novox/mesh-controller/cmd/mesh-controller 309.956s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.074s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 2.017s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.066s
ok github.com/novox/mesh-controller/examples/route-proxy 2.186s
ok github.com/novox/mesh-controller/internal/artifacts 1.205s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 16.046s
ok github.com/novox/mesh-controller/internal/builder 150.783s
ok github.com/novox/mesh-controller/internal/catalogue 17.327s
ok github.com/novox/mesh-controller/internal/conditions 5.347s
ok github.com/novox/mesh-controller/internal/envfile 2.003s
ok github.com/novox/mesh-controller/internal/facts 1.089s
ok github.com/novox/mesh-controller/internal/identity 21.411s
ok github.com/novox/mesh-controller/internal/inventory 116.442s
ok github.com/novox/mesh-controller/internal/lease 21.117s
ok github.com/novox/mesh-controller/internal/licences 19.195s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.026s
ok github.com/novox/mesh-controller/internal/link 91.456s
ok github.com/novox/mesh-controller/internal/lint 2.681s
ok github.com/novox/mesh-controller/internal/outward 1.040s
ok github.com/novox/mesh-controller/internal/overlay 1.064s
ok github.com/novox/mesh-controller/internal/secrets 1.703s
ok github.com/novox/mesh-controller/internal/store 10.436s
ok github.com/novox/mesh-controller/internal/testbus 2.179s
ok github.com/novox/mesh-controller/internal/token 1.029s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.28s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.25s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.24s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.23s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.23s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.26s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (2.00s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.41s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.13s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.30s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.28s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.30s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.29s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.28s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.22s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.31s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.23s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.23s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.40s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.36s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.31s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.16s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.16s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.18s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.35s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.36s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.42s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.30s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.59s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.37s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.20s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.30s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.09s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.66s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.33s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.22s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.22s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.21s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.41s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (1.25s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.19s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.20s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.26s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.43s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.28s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.27s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.22s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.28s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.20s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.31s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.25s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.24s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.35s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.18s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.18s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.09s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.09s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.10s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.09s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.07s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.12s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.07s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.08s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.08s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.12s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.12s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.09s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.09s)
```
**Out of date when it landed**: out of date: judged against trunk 535c7641ac41, the trunk is now c975dbf7b053; judged again on a recheck or when it is merged
Review of #329: a judge built with HOME in the workspace runs git under a
configuration a pull request's script can plant, so a hook could rewrite the
judge's sources before they compile and the result be kept under an honest key
(issue 482, issue 704). Every judge now builds with its own HOME, configuration
and Go cache outside the workspace, no git configuration and no VCS stamping.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge check at b7084a19
Judged: head b7084a19e9bf merged into trunk c975dbf7b053; read beside it: mesh-catalog 02427a60ef78, mesh-controller-main c975dbf7b053, mesh-host 1a2677882380, mesh-tools 954e1a53eef9
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
mesh/repo-check: PASS — its merge-check.sh passed
Delivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
tier 0: mesh-controller
tier 1: build-agent
ace: receives build-agent
g14: receives build-agent
novox: receives mesh-controller, build-agent
shanks: receives build-agent
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on novox as build-1791984660282163421 (builds --log build-1791984660282163421).
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:26:29Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:26:29Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 3.287s
ok github.com/novox/mesh-controller/cmd/mesh-controller 269.427s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.030s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.042s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.020s
ok github.com/novox/mesh-controller/examples/route-proxy 1.142s
ok github.com/novox/mesh-controller/internal/artifacts 1.068s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 5.839s
ok github.com/novox/mesh-controller/internal/builder 117.353s
ok github.com/novox/mesh-controller/internal/catalogue 11.780s
ok github.com/novox/mesh-controller/internal/conditions 3.038s
ok github.com/novox/mesh-controller/internal/envfile 1.031s
ok github.com/novox/mesh-controller/internal/facts 1.045s
ok github.com/novox/mesh-controller/internal/identity 7.026s
ok github.com/novox/mesh-controller/internal/inventory 52.896s
ok github.com/novox/mesh-controller/internal/lease 17.657s
ok github.com/novox/mesh-controller/internal/licences 5.390s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.017s
ok github.com/novox/mesh-controller/internal/link 65.859s
ok github.com/novox/mesh-controller/internal/lint 2.865s
ok github.com/novox/mesh-controller/internal/outward 1.042s
ok github.com/novox/mesh-controller/internal/overlay 1.029s
ok github.com/novox/mesh-controller/internal/secrets 1.751s
ok github.com/novox/mesh-controller/internal/store 4.074s
ok github.com/novox/mesh-controller/internal/testbus 1.301s
ok github.com/novox/mesh-controller/internal/token 1.024s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.34s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.34s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.37s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.39s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.34s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.28s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (2.22s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.38s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (1.27s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.86s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.63s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.48s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.86s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (1.18s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.82s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.54s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.29s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.31s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.32s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.83s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.81s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.44s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.32s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.24s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.26s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.84s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.61s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.74s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.59s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.43s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.72s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.36s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.33s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.37s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.17s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (1.03s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.58s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.43s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.43s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.39s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.36s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (5.68s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (1.87s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (1.24s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.45s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.88s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.48s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.55s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.60s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.67s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.45s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.43s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.38s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.37s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.56s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.32s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.26s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.12s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.14s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.17s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.15s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.10s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.11s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.11s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.11s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.11s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.12s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.11s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.10s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.16s)
Out of date when it landed: out of date: judged against trunk c975dbf7b0, the trunk is now 76304d9db817; judged again on a recheck or when it is merged
**Merge check** at `b7084a19`
Judged: head `b7084a19e9bf` merged into trunk `c975dbf7b053`; read beside it: mesh-catalog `02427a60ef78`, mesh-controller-main `c975dbf7b053`, mesh-host `1a2677882380`, mesh-tools `954e1a53eef9`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- ace: receives build-agent
- g14: receives build-agent
- novox: receives mesh-controller, build-agent
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
- read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on novox as `build-1791984660282163421` (`builds --log build-1791984660282163421`).
```
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:26:29Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:26:29Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 3.287s
ok github.com/novox/mesh-controller/cmd/mesh-controller 269.427s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.030s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.042s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.020s
ok github.com/novox/mesh-controller/examples/route-proxy 1.142s
ok github.com/novox/mesh-controller/internal/artifacts 1.068s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 5.839s
ok github.com/novox/mesh-controller/internal/builder 117.353s
ok github.com/novox/mesh-controller/internal/catalogue 11.780s
ok github.com/novox/mesh-controller/internal/conditions 3.038s
ok github.com/novox/mesh-controller/internal/envfile 1.031s
ok github.com/novox/mesh-controller/internal/facts 1.045s
ok github.com/novox/mesh-controller/internal/identity 7.026s
ok github.com/novox/mesh-controller/internal/inventory 52.896s
ok github.com/novox/mesh-controller/internal/lease 17.657s
ok github.com/novox/mesh-controller/internal/licences 5.390s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.017s
ok github.com/novox/mesh-controller/internal/link 65.859s
ok github.com/novox/mesh-controller/internal/lint 2.865s
ok github.com/novox/mesh-controller/internal/outward 1.042s
ok github.com/novox/mesh-controller/internal/overlay 1.029s
ok github.com/novox/mesh-controller/internal/secrets 1.751s
ok github.com/novox/mesh-controller/internal/store 4.074s
ok github.com/novox/mesh-controller/internal/testbus 1.301s
ok github.com/novox/mesh-controller/internal/token 1.024s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.34s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.34s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.37s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.39s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.34s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.28s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (2.22s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.38s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (1.27s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.86s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.63s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.48s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.86s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (1.18s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.82s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.54s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.29s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.31s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.32s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.83s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.81s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.44s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.32s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.24s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.26s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.84s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.61s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.74s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.59s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.43s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.72s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.36s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.33s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.37s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.17s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (1.03s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.58s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.43s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.43s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.39s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.36s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (5.68s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (1.87s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (1.24s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.45s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.88s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.48s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.55s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.60s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.67s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.45s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.43s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.38s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.37s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.56s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.32s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.26s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.12s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.14s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.17s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.15s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.10s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.11s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.11s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.11s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.11s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.12s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.11s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.10s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.16s)
```
**Out of date when it landed**: out of date: judged against trunk c975dbf7b053, the trunk is now 76304d9db817; judged again on a recheck or when it is merged
This is an independent review of novox/mesh-controller#329 at b7084a19e9, for issue 704 and ADR 0358. I reviewed it as core security code that runs on the live build nodes. ADR 0358 is accepted, at version 11. The knowledge base's latest review is of version 10 (13:23 UTC) and says "approve".
What I ran in my own worktree
gofmt -l cmd internal examples printed nothing.
go vet ./... passed.
merge-check.sh against a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap): exited 0, with 26 packages ok and no FAIL or NOT RUN. I stopped the server afterwards.
What I checked and found correct
The judge's build environment. All four judges are built with JudgeBuildEnv (check.go:1183): the running controller (judge), a controller pull request's own controller (self), the build with the change's validator, and the release judge. Each build sets its own HOME and XDG_CONFIG_HOME, GIT_CONFIG_GLOBAL=/dev/null, GIT_CONFIG_NOSYSTEM=1, GOENV=off, -buildvcs=false, GOPROXY=off, and a fresh GOCACHE and GOPATH outside the workspace.
My own planting test. I wrote two tests (kept out of the branch):
In a workspace, I planted the .gitconfig and XDG fsmonitor hook and the Go env file, as the PR's tests do.
I also planted a real poisoned cache entry. I built the judge's sources at the very path the check clones them to, using <workspace>/go-cache. Then I rewrote the cached outputs, keeping their size, so that "the vendored validator" reads "the poisoned validator".
At this head, neither the hook nor the poisoned entry reaches a trunk ("others") judge, the release judge, or the judge kept for that head, across two checks.
With check.go reverted to 48b2906b, all four tests fail: the PR's two and my two. The trunk judge then says "main's controller with the poisoned validator".
mesh-lab. The controller asks for mesh-lab at main only (checks.go:312-321). The build seat forces main with a fallback and without one (check.go:432-443). When I reverted the seat's new condition, TestTheBuildSeatNeverReadsMeshLabAtAReleaseBranch failed.
trunkOf. When I reverted its "main" fallback, TestATrunkIsMainWhenTheSourceRecordsNone failed.
The release judge is still built once per release-branch head. The second check of the same head took the kept judge and ran no go build.
Findings
Must change: the judge's home is made inside the build-agent container, but bind-mounted by path through the host's container runtime. This is check.go:603-614.
os.MkdirTemp("", "mesh-check-judge-") runs inside the build-agent container. That container mounts only mesh-state, the workspace (at the same path) and the docker socket (mesh-catalog modules/build-agent/module.json). Its /tmp is its own.
--volume /tmp/mesh-check-judge-N:/tmp/mesh-check-judge-N is therefore resolved on the host. dockerd creates that directory, and the toolchain container fills it with a full Go cache (235 MB for this repository, measured).
defer os.RemoveAll(judgeHome) removes only the empty copy in the build-agent container. Every check leaves a few hundred MB in the host's /tmp, or in memory where /tmp is a tmpfs. The withinDir guard checks the wrong filesystem.
The tests' fake runtime runs on one filesystem, so it cannot see this. This is my reading of the code and the manifest. I did not reproduce it on a live node.
Fix: give the judge home a host path that the build-agent mounts at the same path and no check container mounts, and remove it from there.
The same applies, in a milder form, to <workspace>-judges (mesh-builder main.go judgeCacheOf). It works, but it lives in the build-agent container's own layer, so it is lost at every redeploy.
Must decide: trunk checks change, and ADR 0358 §1 and issue 704 promise they do not.
On main 535c7641, every judge (self, validator, and the running controller) was built with the warm shared <workspace>/go-cache. Now each check compiles its judge cold.
I measured 15.4 s wall-clock (72 s of CPU) on 12 cores, against 0.8 s warm, and 67 s on one core. That adds about 15–70 s to every check. A validator check's second build reuses the same fresh cache.
The isolation is needed for security, also on trunk: the poisoned-entry test above passes a poisoned trunk judge on the old environment. That is issue 482, open on main today. Even a self judge can be altered by a hook that an earlier, different pull request planted.
Recommendation: keep it, and make it cheap. Use one persistent Go cache that only judge builds use, at a host path that no check container mounts. Go's cache is content-addressed, and go build with CGO off and fixed GOFLAGS runs none of the change's code, so it is safe to share.
Say in the PR body and in issue 482 that this PR changes trunk checks.
Should: the PR body and the clause numbers are out of date.
The body still says the cache is "a fresh Go cache under the check's root".
Comments and tests call the trunk rule "clause 5". In version 11 that rule is §7, and §5 is now "a release branch's move puts its verdicts out of date (ADR 0323 §4, §5)". This PR does not build §5. Say where it is built, or open an issue for it.
Verdict: CHANGES at b7084a19e9bf
This is an independent review of novox/mesh-controller#329 at b7084a19e9bf1547766503ebe85b44db8e70448d, for issue 704 and ADR 0358. I reviewed it as core security code that runs on the live build nodes. ADR 0358 is **accepted**, at version 11. The knowledge base's latest review is of version 10 (13:23 UTC) and says "approve".
**What I ran in my own worktree**
- `gofmt -l cmd internal examples` printed nothing.
- `go vet ./...` passed.
- `merge-check.sh` against a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap): exited 0, with 26 packages ok and no FAIL or NOT RUN. I stopped the server afterwards.
**What I checked and found correct**
- **The judge's build environment.** All four judges are built with `JudgeBuildEnv` (check.go:1183): the running controller (`judge`), a controller pull request's own controller (`self`), the build with the change's validator, and the release judge. Each build sets its own HOME and XDG_CONFIG_HOME, `GIT_CONFIG_GLOBAL=/dev/null`, `GIT_CONFIG_NOSYSTEM=1`, `GOENV=off`, `-buildvcs=false`, `GOPROXY=off`, and a fresh GOCACHE and GOPATH outside the workspace.
- **My own planting test.** I wrote two tests (kept out of the branch):
- In a workspace, I planted the `.gitconfig` and XDG fsmonitor hook and the Go env file, as the PR's tests do.
- I also planted a **real poisoned cache entry**. I built the judge's sources at the very path the check clones them to, using `<workspace>/go-cache`. Then I rewrote the cached outputs, keeping their size, so that "the vendored validator" reads "the poisoned validator".
- At this head, neither the hook nor the poisoned entry reaches a trunk ("others") judge, the release judge, or the judge kept for that head, across two checks.
- With check.go reverted to 48b2906b, all four tests fail: the PR's two and my two. The trunk judge then says "main's controller with the poisoned validator".
- **mesh-lab.** The controller asks for mesh-lab at `main` only (checks.go:312-321). The build seat forces main with a fallback and without one (check.go:432-443). When I reverted the seat's new condition, `TestTheBuildSeatNeverReadsMeshLabAtAReleaseBranch` failed.
- **trunkOf.** When I reverted its "main" fallback, `TestATrunkIsMainWhenTheSourceRecordsNone` failed.
- **The release judge is still built once per release-branch head.** The second check of the same head took the kept judge and ran no `go build`.
**Findings**
1. **Must change: the judge's home is made inside the build-agent container, but bind-mounted by path through the host's container runtime.** This is check.go:603-614.
- `os.MkdirTemp("", "mesh-check-judge-")` runs inside the build-agent container. That container mounts only mesh-state, the workspace (at the same path) and the docker socket (mesh-catalog modules/build-agent/module.json). Its `/tmp` is its own.
- `--volume /tmp/mesh-check-judge-N:/tmp/mesh-check-judge-N` is therefore resolved on the **host**. dockerd creates that directory, and the toolchain container fills it with a full Go cache (235 MB for this repository, measured).
- `defer os.RemoveAll(judgeHome)` removes only the empty copy in the build-agent container. Every check leaves a few hundred MB in the host's /tmp, or in memory where /tmp is a tmpfs. The `withinDir` guard checks the wrong filesystem.
- The tests' fake runtime runs on one filesystem, so it cannot see this. This is my reading of the code and the manifest. I did not reproduce it on a live node.
- Fix: give the judge home a host path that the build-agent mounts at the same path and no check container mounts, and remove it from there.
- The same applies, in a milder form, to `<workspace>-judges` (mesh-builder main.go `judgeCacheOf`). It works, but it lives in the build-agent container's own layer, so it is lost at every redeploy.
2. **Must decide: trunk checks change, and ADR 0358 §1 and issue 704 promise they do not.**
- On main 535c7641, every judge (self, validator, and the running controller) was built with the warm shared `<workspace>/go-cache`. Now each check compiles its judge cold.
- I measured 15.4 s wall-clock (72 s of CPU) on 12 cores, against 0.8 s warm, and 67 s on one core. That adds about 15–70 s to every check. A validator check's second build reuses the same fresh cache.
- The isolation is **needed for security**, also on trunk: the poisoned-entry test above passes a poisoned trunk judge on the old environment. That is issue 482, open on main today. Even a `self` judge can be altered by a hook that an earlier, different pull request planted.
- Recommendation: keep it, and make it cheap. Use one persistent Go cache that only judge builds use, at a host path that no check container mounts. Go's cache is content-addressed, and `go build` with CGO off and fixed GOFLAGS runs none of the change's code, so it is safe to share.
- Say in the PR body and in issue 482 that this PR changes trunk checks.
3. **Should: the PR body and the clause numbers are out of date.**
- The body still says the cache is "a fresh Go cache under the check's root".
- Comments and tests call the trunk rule "clause 5". In version 11 that rule is §7, and §5 is now "a release branch's move puts its verdicts out of date (ADR 0323 §4, §5)". This PR does not build §5. Say where it is built, or open an issue for it.
mesh/delivery-group group fix/704-release-branch-judge rejected: its order contradicts itself: novox/mesh-catalog@47ef2644aca1 and novox/mesh-controller@2bee29…
mesh/merge-gate head 2bee290eea56 merged into trunk 76304d9db817 — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every …
Review of #329: a judge's home made with a temporary directory inside the build
agent is resolved on the host by the container runtime, leaving a cold cache
behind on every check, and a kept judge was lost on every redeploy. Judge builds
now use the judge cache the build agent declares (MESH_JUDGE_CACHE), mounted into
judge builds only: one warm Go cache, the kept judges, and a fresh home per check
removed after it (hq ADR 0358 §6, issue 704, issue 482).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge check at 2bee290e
Judged: head 2bee290eea56 merged into trunk 76304d9db817; read beside it: mesh-catalog cb7bf94a77ea, mesh-controller-main 76304d9db817, mesh-host 1a2677882380, mesh-tools 954e1a53eef9
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
mesh/repo-check: PASS — its merge-check.sh passed
Delivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
tier 0: mesh-controller
tier 1: build-agent
ace: receives build-agent
g14: receives build-agent
novox: receives mesh-controller, build-agent
shanks: receives build-agent
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on ace as build-1791986017411722467 (builds --log build-1791986017411722467).
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:47:24Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:47:24Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.079s
ok github.com/novox/mesh-controller/cmd/mesh-controller 157.139s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.031s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.037s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.024s
ok github.com/novox/mesh-controller/examples/route-proxy 1.122s
ok github.com/novox/mesh-controller/internal/artifacts 1.069s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.016s
ok github.com/novox/mesh-controller/internal/builder 67.161s
ok github.com/novox/mesh-controller/internal/catalogue 7.622s
ok github.com/novox/mesh-controller/internal/conditions 2.523s
ok github.com/novox/mesh-controller/internal/envfile 1.037s
ok github.com/novox/mesh-controller/internal/facts 1.037s
ok github.com/novox/mesh-controller/internal/identity 4.338s
ok github.com/novox/mesh-controller/internal/inventory 31.020s
ok github.com/novox/mesh-controller/internal/lease 30.864s
ok github.com/novox/mesh-controller/internal/licences 3.480s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.026s
ok github.com/novox/mesh-controller/internal/link 58.065s
ok github.com/novox/mesh-controller/internal/lint 2.286s
ok github.com/novox/mesh-controller/internal/outward 1.069s
ok github.com/novox/mesh-controller/internal/overlay 1.061s
ok github.com/novox/mesh-controller/internal/secrets 1.422s
ok github.com/novox/mesh-controller/internal/store 3.279s
ok github.com/novox/mesh-controller/internal/testbus 1.233s
ok github.com/novox/mesh-controller/internal/token 1.016s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.19s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.21s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.20s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.19s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.18s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.16s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.95s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.23s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.11s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.19s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.24s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.23s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.19s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.18s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.19s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.19s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.22s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.27s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.26s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.14s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.13s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.14s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.27s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.21s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.27s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.22s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.18s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.19s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.16s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.13s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.18s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.07s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.44s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.26s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.18s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.17s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.49s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.16s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.16s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.23s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.28s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.23s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.20s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.23s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.17s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.20s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.20s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.20s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.15s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.14s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.07s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.07s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.08s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.07s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.06s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.06s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.06s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.07s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.06s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.08s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.07s)
**Merge check** at `2bee290e`
Judged: head `2bee290eea56` merged into trunk `76304d9db817`; read beside it: mesh-catalog `cb7bf94a77ea`, mesh-controller-main `76304d9db817`, mesh-host `1a2677882380`, mesh-tools `954e1a53eef9`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- ace: receives build-agent
- g14: receives build-agent
- novox: receives mesh-controller, build-agent
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
- read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on ace as `build-1791986017411722467` (`builds --log build-1791986017411722467`).
```
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:47:24Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:47:24Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.079s
ok github.com/novox/mesh-controller/cmd/mesh-controller 157.139s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.031s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.037s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.024s
ok github.com/novox/mesh-controller/examples/route-proxy 1.122s
ok github.com/novox/mesh-controller/internal/artifacts 1.069s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.016s
ok github.com/novox/mesh-controller/internal/builder 67.161s
ok github.com/novox/mesh-controller/internal/catalogue 7.622s
ok github.com/novox/mesh-controller/internal/conditions 2.523s
ok github.com/novox/mesh-controller/internal/envfile 1.037s
ok github.com/novox/mesh-controller/internal/facts 1.037s
ok github.com/novox/mesh-controller/internal/identity 4.338s
ok github.com/novox/mesh-controller/internal/inventory 31.020s
ok github.com/novox/mesh-controller/internal/lease 30.864s
ok github.com/novox/mesh-controller/internal/licences 3.480s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.026s
ok github.com/novox/mesh-controller/internal/link 58.065s
ok github.com/novox/mesh-controller/internal/lint 2.286s
ok github.com/novox/mesh-controller/internal/outward 1.069s
ok github.com/novox/mesh-controller/internal/overlay 1.061s
ok github.com/novox/mesh-controller/internal/secrets 1.422s
ok github.com/novox/mesh-controller/internal/store 3.279s
ok github.com/novox/mesh-controller/internal/testbus 1.233s
ok github.com/novox/mesh-controller/internal/token 1.016s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.19s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.21s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.20s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.19s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.18s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.16s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.95s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.23s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.11s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.19s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.24s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.23s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.19s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.18s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.19s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.19s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.22s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.27s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.26s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.14s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.13s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.14s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.27s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.21s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.27s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.22s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.18s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.19s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.16s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.13s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.18s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.07s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.44s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.26s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.18s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.17s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.49s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.16s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.16s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.23s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.28s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.23s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.20s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.23s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.17s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.20s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.20s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.20s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.15s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.14s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.07s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.07s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.08s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.07s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.06s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.06s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.06s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.07s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.06s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.08s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.07s)
```
Merge check at 2bee290e
Judged: head 2bee290eea56 merged into trunk 76304d9db817; read beside it: mesh-catalog cb7bf94a77ea, mesh-controller-main 76304d9db817, mesh-host 1a2677882380, mesh-tools 954e1a53eef9
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
mesh/repo-check: PASS — its merge-check.sh passed
Delivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
tier 0: mesh-controller
tier 1: build-agent
ace: receives build-agent
g14: receives build-agent
novox: receives mesh-controller, build-agent
shanks: receives build-agent
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on ace as build-1791986017411722467 (builds --log build-1791986017411722467).
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:47:24Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:47:24Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.079s
ok github.com/novox/mesh-controller/cmd/mesh-controller 157.139s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.031s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.037s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.024s
ok github.com/novox/mesh-controller/examples/route-proxy 1.122s
ok github.com/novox/mesh-controller/internal/artifacts 1.069s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.016s
ok github.com/novox/mesh-controller/internal/builder 67.161s
ok github.com/novox/mesh-controller/internal/catalogue 7.622s
ok github.com/novox/mesh-controller/internal/conditions 2.523s
ok github.com/novox/mesh-controller/internal/envfile 1.037s
ok github.com/novox/mesh-controller/internal/facts 1.037s
ok github.com/novox/mesh-controller/internal/identity 4.338s
ok github.com/novox/mesh-controller/internal/inventory 31.020s
ok github.com/novox/mesh-controller/internal/lease 30.864s
ok github.com/novox/mesh-controller/internal/licences 3.480s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.026s
ok github.com/novox/mesh-controller/internal/link 58.065s
ok github.com/novox/mesh-controller/internal/lint 2.286s
ok github.com/novox/mesh-controller/internal/outward 1.069s
ok github.com/novox/mesh-controller/internal/overlay 1.061s
ok github.com/novox/mesh-controller/internal/secrets 1.422s
ok github.com/novox/mesh-controller/internal/store 3.279s
ok github.com/novox/mesh-controller/internal/testbus 1.233s
ok github.com/novox/mesh-controller/internal/token 1.016s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.19s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.21s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.20s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.19s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.18s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.16s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.95s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.23s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.11s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.19s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.24s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.23s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.19s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.18s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.19s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.19s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.22s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.27s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.26s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.14s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.13s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.14s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.27s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.21s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.27s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.22s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.18s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.19s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.16s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.13s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.18s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.07s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.44s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.26s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.18s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.17s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.49s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.16s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.16s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.23s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.28s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.23s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.20s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.23s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.17s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.20s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.20s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.20s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.15s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.14s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.07s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.07s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.08s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.07s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.06s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.06s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.06s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.07s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.06s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.08s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.07s)
**Merge check** at `2bee290e`
Judged: head `2bee290eea56` merged into trunk `76304d9db817`; read beside it: mesh-catalog `cb7bf94a77ea`, mesh-controller-main `76304d9db817`, mesh-host `1a2677882380`, mesh-tools `954e1a53eef9`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- ace: receives build-agent
- g14: receives build-agent
- novox: receives mesh-controller, build-agent
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
- read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on ace as `build-1791986017411722467` (`builds --log build-1791986017411722467`).
```
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:47:24Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:47:24Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.079s
ok github.com/novox/mesh-controller/cmd/mesh-controller 157.139s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.031s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.037s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.024s
ok github.com/novox/mesh-controller/examples/route-proxy 1.122s
ok github.com/novox/mesh-controller/internal/artifacts 1.069s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.016s
ok github.com/novox/mesh-controller/internal/builder 67.161s
ok github.com/novox/mesh-controller/internal/catalogue 7.622s
ok github.com/novox/mesh-controller/internal/conditions 2.523s
ok github.com/novox/mesh-controller/internal/envfile 1.037s
ok github.com/novox/mesh-controller/internal/facts 1.037s
ok github.com/novox/mesh-controller/internal/identity 4.338s
ok github.com/novox/mesh-controller/internal/inventory 31.020s
ok github.com/novox/mesh-controller/internal/lease 30.864s
ok github.com/novox/mesh-controller/internal/licences 3.480s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.026s
ok github.com/novox/mesh-controller/internal/link 58.065s
ok github.com/novox/mesh-controller/internal/lint 2.286s
ok github.com/novox/mesh-controller/internal/outward 1.069s
ok github.com/novox/mesh-controller/internal/overlay 1.061s
ok github.com/novox/mesh-controller/internal/secrets 1.422s
ok github.com/novox/mesh-controller/internal/store 3.279s
ok github.com/novox/mesh-controller/internal/testbus 1.233s
ok github.com/novox/mesh-controller/internal/token 1.016s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.19s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.21s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.20s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.19s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.18s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.16s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.95s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.23s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.11s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.19s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.24s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.23s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.19s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.18s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.19s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.19s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.22s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.27s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.26s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.14s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.13s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.14s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.27s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.21s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.27s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.22s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.18s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.19s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.16s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.13s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.18s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.07s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.44s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.26s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.18s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.17s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.49s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.16s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.16s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.23s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.28s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.23s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.20s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.23s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.17s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.20s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.20s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.20s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.15s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.14s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.07s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.07s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.08s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.07s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.06s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.06s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.06s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.07s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.06s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.08s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.07s)
```
Merge check at 2bee290e
Judged: head 2bee290eea56 merged into trunk 76304d9db817; read beside it: mesh-catalog cb7bf94a77ea, mesh-controller-main 76304d9db817, mesh-host 1a2677882380, mesh-tools 954e1a53eef9
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
mesh/repo-check: PASS — its merge-check.sh passed
Delivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
tier 0: mesh-controller
tier 1: build-agent
ace: receives build-agent
g14: receives build-agent
novox: receives mesh-controller, build-agent
shanks: receives build-agent
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on ace as build-1791986017411722467 (builds --log build-1791986017411722467).
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:47:24Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:47:24Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.079s
ok github.com/novox/mesh-controller/cmd/mesh-controller 157.139s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.031s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.037s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.024s
ok github.com/novox/mesh-controller/examples/route-proxy 1.122s
ok github.com/novox/mesh-controller/internal/artifacts 1.069s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.016s
ok github.com/novox/mesh-controller/internal/builder 67.161s
ok github.com/novox/mesh-controller/internal/catalogue 7.622s
ok github.com/novox/mesh-controller/internal/conditions 2.523s
ok github.com/novox/mesh-controller/internal/envfile 1.037s
ok github.com/novox/mesh-controller/internal/facts 1.037s
ok github.com/novox/mesh-controller/internal/identity 4.338s
ok github.com/novox/mesh-controller/internal/inventory 31.020s
ok github.com/novox/mesh-controller/internal/lease 30.864s
ok github.com/novox/mesh-controller/internal/licences 3.480s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.026s
ok github.com/novox/mesh-controller/internal/link 58.065s
ok github.com/novox/mesh-controller/internal/lint 2.286s
ok github.com/novox/mesh-controller/internal/outward 1.069s
ok github.com/novox/mesh-controller/internal/overlay 1.061s
ok github.com/novox/mesh-controller/internal/secrets 1.422s
ok github.com/novox/mesh-controller/internal/store 3.279s
ok github.com/novox/mesh-controller/internal/testbus 1.233s
ok github.com/novox/mesh-controller/internal/token 1.016s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.19s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.21s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.20s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.19s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.18s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.16s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.95s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.23s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.11s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.19s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.24s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.23s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.19s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.18s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.19s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.19s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.22s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.27s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.26s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.14s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.13s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.14s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.27s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.21s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.27s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.22s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.18s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.19s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.16s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.13s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.18s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.07s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.44s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.26s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.18s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.17s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.49s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.16s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.16s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.23s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.28s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.23s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.20s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.23s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.17s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.20s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.20s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.20s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.15s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.14s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.07s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.07s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.08s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.07s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.06s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.06s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.06s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.07s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.06s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.08s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.07s)
**Merge check** at `2bee290e`
Judged: head `2bee290eea56` merged into trunk `76304d9db817`; read beside it: mesh-catalog `cb7bf94a77ea`, mesh-controller-main `76304d9db817`, mesh-host `1a2677882380`, mesh-tools `954e1a53eef9`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- ace: receives build-agent
- g14: receives build-agent
- novox: receives mesh-controller, build-agent
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
- read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on ace as `build-1791986017411722467` (`builds --log build-1791986017411722467`).
```
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:47:24Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:47:24Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.079s
ok github.com/novox/mesh-controller/cmd/mesh-controller 157.139s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.031s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.037s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.024s
ok github.com/novox/mesh-controller/examples/route-proxy 1.122s
ok github.com/novox/mesh-controller/internal/artifacts 1.069s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.016s
ok github.com/novox/mesh-controller/internal/builder 67.161s
ok github.com/novox/mesh-controller/internal/catalogue 7.622s
ok github.com/novox/mesh-controller/internal/conditions 2.523s
ok github.com/novox/mesh-controller/internal/envfile 1.037s
ok github.com/novox/mesh-controller/internal/facts 1.037s
ok github.com/novox/mesh-controller/internal/identity 4.338s
ok github.com/novox/mesh-controller/internal/inventory 31.020s
ok github.com/novox/mesh-controller/internal/lease 30.864s
ok github.com/novox/mesh-controller/internal/licences 3.480s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.026s
ok github.com/novox/mesh-controller/internal/link 58.065s
ok github.com/novox/mesh-controller/internal/lint 2.286s
ok github.com/novox/mesh-controller/internal/outward 1.069s
ok github.com/novox/mesh-controller/internal/overlay 1.061s
ok github.com/novox/mesh-controller/internal/secrets 1.422s
ok github.com/novox/mesh-controller/internal/store 3.279s
ok github.com/novox/mesh-controller/internal/testbus 1.233s
ok github.com/novox/mesh-controller/internal/token 1.016s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.19s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.21s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.20s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.19s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.18s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.16s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.95s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.23s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.11s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.19s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.24s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.23s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.19s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.18s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.19s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.19s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.22s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.27s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.26s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.14s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.13s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.14s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.27s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.21s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.27s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.22s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.18s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.19s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.16s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.13s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.18s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.07s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.44s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.26s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.18s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.17s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.49s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.16s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.16s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.23s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.28s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.23s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.20s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.23s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.17s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.20s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.20s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.20s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.15s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.14s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.07s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.07s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.08s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.07s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.06s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.06s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.06s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.07s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.06s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.08s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.07s)
```
gofmt -l cmd internal examples: nothing. go vet ./...: passed.
merge-check.sh with a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap), stopped afterwards: exit 0, 26 packages ok, no FAIL, no NOT RUN.
The catalogue's merge-check.sh at #297's head with MESH_GATE built from this head (MESH_CHECK_MODULES=build-agent,gitea): exit 0.
My own planting tests from the previous round (kept out of the branch), adapted to judges/: a poisoned Go cache entry and a .gitconfig/fsmonitor hook in the workspace reach neither a trunk judge nor the kept release judge, across two checks. Both pass.
A warm judge build: the controller built with JudgeBuildEnv against one persistent Go cache took 14.9 s cold, then 0.88 s and 0.82 s warm (12 cores, toolchain on the host, no container start). The body's "about 1 s" holds.
What I checked and found correct (review 12286's points)
Every docker run in the build seat: the check's own containers (in, check.go:577) mount only the workspace; the replays add only the runtime's socket (check.go:1055); dependencies.go and builder.go mount build trees and npm files. Only inJudgeBuild (check.go:611-619) mounts the judge cache's homes/<id> and go-cache/.
judgeBuildDirs (check.go:1199) makes the home under the judge cache, which the agent sees at the host's own path, and defer os.RemoveAll(judgeHome) removes it there. Nothing in the judge path uses os.MkdirTemp any more. Without a judge cache, both go under the check's root, which is emptied before the clones (check.go:315) and removed afterwards.
A judge cache inside the workspace is refused (check.go:1209-1211).
Delivery order: an old mesh-builder with the new manifest ignores MESH_JUDGE_CACHE and leaves an empty directory. A new mesh-builder without it builds every judge cold under the check's root (15 s on 12 cores, about 67 s on one core per review 12286). Neither order produces a wrong verdict.
Findings
Must change: a pull request can still reach the judge cache, through mesh-lab's replays (check.go:578 and 1049-1055). This was already possible on main, but this pull request's claim (ADR 0358 §6, its checklist item 4: "the judge build reads nothing a pull request can write") does not hold while it stays. The judge cache also now persists across checks and redeploys, so a single poisoning reaches every later judge.
The replays run go test in a container that has /var/run/docker.sock, with HOME=<workspace> (the default in in), no GOENV=off, no GIT_CONFIG_GLOBAL, and GOCACHE=<workspace>/go-cache. A check's own script writes all of these.
Reproduced with a test (not in the branch): I planted <workspace>/.config/go/env with GOFLAGS=-toolexec=<hook> (the same file aPlantedWorkspace plants) and gave mesh-lab a replays/ package. The hook ran in <workspace>/check/mesh-lab/replays, in the run that carries --volume /var/run/docker.sock. With the socket, that program can docker run -v <judge cache>:…, or the host's root.
A poisoned entry in <workspace>/go-cache reaches the replays' test binary the same way.
Fix: run the replays in the judge build's environment: a fresh HOME and XDG_CONFIG_HOME, GOENV=off, GIT_CONFIG_GLOBAL=/dev/null, GIT_CONFIG_NOSYSTEM=1, and a Go cache that no check container mounts (the judge cache's, or one of its own). Then add the planted-env test for the replays.
Should: release_branch_test.go:365 still calls the trunk rule "Clause 5 (ADR 0358 §5)". In v11 that is §7.
Should: the body's "without it, a few minutes" is 15 s on 12 cores and about 67 s on one core. Say that instead.
ADR 0358 §5: the claim holds. The gitea module's weighTrunks weighs every open pull request's base, and merge.ts:95 compares against the pull request's own base. #297's new test passes with Node's runner (8 of 8 trunk tests).
Verdict: CHANGES at 2bee290eea56
Independent review of novox/mesh-controller#329 at 2bee290eea56dc94dd67fe379c59ad35e4e64ef5 (issue 704, ADR 0358 v11), together with novox/mesh-catalog#297 at 47ef2644aca1, as core code for the live build nodes. I read review 12286.
**What I ran**
- `gofmt -l cmd internal examples`: nothing. `go vet ./...`: passed.
- `merge-check.sh` with a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap), stopped afterwards: exit 0, 26 packages ok, no FAIL, no NOT RUN.
- The catalogue's `merge-check.sh` at #297's head with MESH_GATE built from this head (MESH_CHECK_MODULES=build-agent,gitea): exit 0.
- My own planting tests from the previous round (kept out of the branch), adapted to `judges/`: a poisoned Go cache entry and a `.gitconfig`/fsmonitor hook in the workspace reach neither a trunk judge nor the kept release judge, across two checks. Both pass.
- A warm judge build: the controller built with `JudgeBuildEnv` against one persistent Go cache took 14.9 s cold, then 0.88 s and 0.82 s warm (12 cores, toolchain on the host, no container start). The body's "about 1 s" holds.
**What I checked and found correct (review 12286's points)**
- Every `docker run` in the build seat: the check's own containers (`in`, check.go:577) mount only the workspace; the replays add only the runtime's socket (check.go:1055); `dependencies.go` and `builder.go` mount build trees and npm files. Only `inJudgeBuild` (check.go:611-619) mounts the judge cache's `homes/<id>` and `go-cache/`.
- `judgeBuildDirs` (check.go:1199) makes the home under the judge cache, which the agent sees at the host's own path, and `defer os.RemoveAll(judgeHome)` removes it there. Nothing in the judge path uses `os.MkdirTemp` any more. Without a judge cache, both go under the check's root, which is emptied before the clones (check.go:315) and removed afterwards.
- A judge cache inside the workspace is refused (check.go:1209-1211).
- Delivery order: an old mesh-builder with the new manifest ignores MESH_JUDGE_CACHE and leaves an empty directory. A new mesh-builder without it builds every judge cold under the check's root (15 s on 12 cores, about 67 s on one core per review 12286). Neither order produces a wrong verdict.
**Findings**
1. **Must change: a pull request can still reach the judge cache, through mesh-lab's replays** (check.go:578 and 1049-1055). This was already possible on main, but this pull request's claim (ADR 0358 §6, its checklist item 4: "the judge build reads nothing a pull request can write") does not hold while it stays. The judge cache also now persists across checks and redeploys, so a single poisoning reaches every later judge.
- The replays run `go test` in a container that has `/var/run/docker.sock`, with `HOME=<workspace>` (the default in `in`), no `GOENV=off`, no `GIT_CONFIG_GLOBAL`, and `GOCACHE=<workspace>/go-cache`. A check's own script writes all of these.
- Reproduced with a test (not in the branch): I planted `<workspace>/.config/go/env` with `GOFLAGS=-toolexec=<hook>` (the same file `aPlantedWorkspace` plants) and gave mesh-lab a `replays/` package. The hook ran in `<workspace>/check/mesh-lab/replays`, in the run that carries `--volume /var/run/docker.sock`. With the socket, that program can `docker run -v <judge cache>:…`, or the host's root.
- A poisoned entry in `<workspace>/go-cache` reaches the replays' test binary the same way.
- Fix: run the replays in the judge build's environment: a fresh HOME and XDG_CONFIG_HOME, `GOENV=off`, `GIT_CONFIG_GLOBAL=/dev/null`, `GIT_CONFIG_NOSYSTEM=1`, and a Go cache that no check container mounts (the judge cache's, or one of its own). Then add the planted-env test for the replays.
2. **Should: release_branch_test.go:365** still calls the trunk rule "Clause 5 (ADR 0358 §5)". In v11 that is §7.
3. **Should: the body's "without it, a few minutes"** is 15 s on 12 cores and about 67 s on one core. Say that instead.
ADR 0358 §5: the claim holds. The gitea module's `weighTrunks` weighs every open pull request's base, and `merge.ts:95` compares against the pull request's own base. #297's new test passes with Node's runner (8 of 8 trunk tests).
mesh/merge-gate head 0214b45469ec merged into trunk 76304d9db817 — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every …
The replays hold the container runtime's socket, yet took their HOME, Go
environment, build cache and module cache from the workspace a pull request's
own script writes, so a planted -toolexec hook ran as root on the build node
(hq issue 709). They now run from a copy of mesh-lab made before anything of
the change runs, with a fresh home and the judge cache's caches, as a judge is
built (ADR 0358 §6).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge check at 0214b454
Judged: head 0214b45469ec merged into trunk 76304d9db817; read beside it: mesh-catalog cb7bf94a77ea, mesh-controller-main 76304d9db817, mesh-host 1a2677882380, mesh-tools 954e1a53eef9
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
mesh/repo-check: PASS — its merge-check.sh passed
Delivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
tier 0: mesh-controller
tier 1: build-agent
ace: receives build-agent
g14: receives build-agent
novox: receives mesh-controller, build-agent
shanks: receives build-agent
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on shanks as build-1791987347185392290 (builds --log build-1791987347185392290).
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:47:24Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:47:24Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.096s
ok github.com/novox/mesh-controller/cmd/mesh-controller 187.609s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.055s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.062s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.066s
ok github.com/novox/mesh-controller/examples/route-proxy 1.216s
ok github.com/novox/mesh-controller/internal/artifacts 1.096s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.510s
ok github.com/novox/mesh-controller/internal/builder 83.928s
ok github.com/novox/mesh-controller/internal/catalogue 8.596s
ok github.com/novox/mesh-controller/internal/conditions 2.679s
ok github.com/novox/mesh-controller/internal/envfile 1.061s
ok github.com/novox/mesh-controller/internal/facts 1.061s
ok github.com/novox/mesh-controller/internal/identity 4.994s
ok github.com/novox/mesh-controller/internal/inventory 37.228s
ok github.com/novox/mesh-controller/internal/lease 30.888s
ok github.com/novox/mesh-controller/internal/licences 4.057s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.051s
ok github.com/novox/mesh-controller/internal/link 60.441s
ok github.com/novox/mesh-controller/internal/lint 2.591s
ok github.com/novox/mesh-controller/internal/outward 1.090s
ok github.com/novox/mesh-controller/internal/overlay 1.075s
ok github.com/novox/mesh-controller/internal/secrets 1.571s
ok github.com/novox/mesh-controller/internal/store 3.467s
ok github.com/novox/mesh-controller/internal/testbus 1.265s
ok github.com/novox/mesh-controller/internal/token 1.017s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.23s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.24s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.22s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.21s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.21s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.18s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.97s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.24s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.12s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.25s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.25s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.20s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.21s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.26s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.21s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.25s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.21s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.20s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.20s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.20s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.22s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.28s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.28s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.16s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.15s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.17s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.29s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.24s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.28s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.24s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.19s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.20s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.18s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.16s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.20s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.08s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.48s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.27s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.20s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.20s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.19s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.29s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.55s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.19s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.18s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.24s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.30s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.25s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.20s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.24s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.19s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.19s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.21s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.21s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.23s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.16s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.15s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.08s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.08s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.10s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.09s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.07s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.07s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.07s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.08s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.07s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.08s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.08s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.08s)
**Merge check** at `0214b454`
Judged: head `0214b45469ec` merged into trunk `76304d9db817`; read beside it: mesh-catalog `cb7bf94a77ea`, mesh-controller-main `76304d9db817`, mesh-host `1a2677882380`, mesh-tools `954e1a53eef9`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- ace: receives build-agent
- g14: receives build-agent
- novox: receives mesh-controller, build-agent
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
- read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on shanks as `build-1791987347185392290` (`builds --log build-1791987347185392290`).
```
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:47:24Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:47:24Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.096s
ok github.com/novox/mesh-controller/cmd/mesh-controller 187.609s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.055s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.062s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.066s
ok github.com/novox/mesh-controller/examples/route-proxy 1.216s
ok github.com/novox/mesh-controller/internal/artifacts 1.096s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.510s
ok github.com/novox/mesh-controller/internal/builder 83.928s
ok github.com/novox/mesh-controller/internal/catalogue 8.596s
ok github.com/novox/mesh-controller/internal/conditions 2.679s
ok github.com/novox/mesh-controller/internal/envfile 1.061s
ok github.com/novox/mesh-controller/internal/facts 1.061s
ok github.com/novox/mesh-controller/internal/identity 4.994s
ok github.com/novox/mesh-controller/internal/inventory 37.228s
ok github.com/novox/mesh-controller/internal/lease 30.888s
ok github.com/novox/mesh-controller/internal/licences 4.057s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.051s
ok github.com/novox/mesh-controller/internal/link 60.441s
ok github.com/novox/mesh-controller/internal/lint 2.591s
ok github.com/novox/mesh-controller/internal/outward 1.090s
ok github.com/novox/mesh-controller/internal/overlay 1.075s
ok github.com/novox/mesh-controller/internal/secrets 1.571s
ok github.com/novox/mesh-controller/internal/store 3.467s
ok github.com/novox/mesh-controller/internal/testbus 1.265s
ok github.com/novox/mesh-controller/internal/token 1.017s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.23s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.24s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.22s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.21s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.21s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.18s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.97s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.24s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.12s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.25s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.25s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.20s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.21s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.26s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.21s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.25s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.21s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.20s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.20s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.20s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.22s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.28s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.28s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.16s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.15s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.17s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.29s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.24s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.28s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.24s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.19s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.20s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.18s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.16s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.20s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.08s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.48s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.27s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.20s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.20s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.19s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.29s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.55s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.19s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.18s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.24s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.30s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.25s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.20s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.24s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.19s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.19s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.21s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.21s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.23s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.16s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.15s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.08s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.08s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.10s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.09s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.07s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.07s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.07s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.08s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.07s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.08s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.08s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.08s)
```
Independent review of novox/mesh-controller#329 at 0214b45469 (issue 704, ADR 0358 v11, issue 709), together with novox/mesh-catalog#297 at 47ef2644aca1, reviewed as security-critical code for the live build nodes. I read review 12295.
What I ran
gofmt -l cmd internal examples: nothing. go vet ./...: passed.
merge-check.sh with a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap), stopped afterwards: exit 0, 26 packages ok, no FAIL, no NOT RUN.
With check.go put back to 2bee290 and the new test kept, TestTheReplaysRunWhereNoPullRequestReaches fails. At the head, it passes.
My own tests (not in the branch):
A real poisoned Go cache entry for the replay package, compiled into <workspace>/go-cache at both the old path and the copy's path, plus the planted -toolexec Go env file and .gitconfig hook. With a judge cache, the replay ran honest and no hook ran. With check.go at 2bee290, the replay ran the poisoned code.
The poisoned-cache and hook tests from the previous round, for the trunk judge and the kept release judge: both pass.
A controller pull request that judges itself, whose judge rewrites $MESH_CHECK_BESIDE/mesh-lab/replays during the gate. With a judge cache, the replays run from the copy and the rewrite never runs. Without one, see finding 1.
Issue 709 with a judge cache: fixed. The copy is made right after mesh-lab's clone, before any container runs (check.go:457). The copy uses git clone --no-local, and the host's git runs it, not a check container. The replays get a fresh HOME and XDG_CONFIG_HOME, GOENV=off, GIT_CONFIG_GLOBAL=/dev/null, GIT_CONFIG_NOSYSTEM=1, -buildvcs=false, and the judge cache's Go build and module caches (check.go:637-647, 1305).
The author's reasoning for sharing the judge cache holds. The replays compile only mesh-lab's trunk and public modules that the checksum database verifies. Whatever holds the socket is already root-equivalent, so sharing the judge's Go cache gives the replays no reach they did not already have. The pull request's only input to the replays is the catalogue, which they read as data (see below).
Where pull-request-written data goes, for each run in internal/builder
in (check.go:598), used by the check's containers, the gate's module check and merge gate, and the repository's own check: the workspace is mounted read-write, with HOME and GOCACHE in the workspace. PR data reaches it by design. It has no socket and no judge cache, and runs as the builder's user, not root.
inJudgeBuild (check.go:624): it mounts the judge cache's homes/<id> and go-cache. It compiles fresh clones, and for a self-judge or a validator change it also compiles the pull request's Go code. That build uses CGO_ENABLED=0, GOPROXY=off and -mod=vendor, so the compile runs none of the pull request's code. It only writes cache entries under the build's own content-addressed keys (action IDs).
The judge kept for a head is built and stored before any of the change runs (check.go:1201-1207). Nothing that mounts the workspace mounts it.
inReplays (check.go:637): it has the socket and the replay base and caches, and the workspace through in. PR data that reaches it: MESH_REPLAY_CATALOGUE. mesh-lab's bed, store and resolver replays read image names, env, args and health commands from that catalogue. They start those images as unprivileged containers whose binds are only scratch directories. git show/rev-parse on the catalogue checkout ran no repository-config hook in my probe (git 2.56). This was already so on main.
The throwaway store and bus (check.go:1637): their images come from the facts. No PR data reaches them.
dependencies.go and builder.go: build trees and npm files. They are not changed here.
Findings
Must change: without a judge cache, issue 709 is still open (check.go:633-636 and 1270-1280).
With JudgeCache == "", replay.lab is empty, so the replays run root/mesh-lab/replays from the workspace, with the socket. Their Go cache (root/judge-go-cache) is also in the workspace.
The gate runs before the replays, in containers that mount the workspace read-write. For a controller pull request (a self-judge) or a node-engine pull request (a validator change), that is the pull request's own code. "Every check empties the root before it clones" does not help, because this happens within one check.
Reproduced: a self-judging controller pull request wrote evil_test.go into root/mesh-lab/replays, and it ran in the replays' go test, the run that mounts /var/run/docker.sock.
The body names this state as supported ("A new mesh-builder without #297 builds judges and runs the replays cold").
Fix: without a judge cache, either refuse the replays loudly (the gate's verdict is error, never pass), or make the copy and its caches outside the workspace in that case too. Then add the self-judge test for that case.
Should: the replays' environment could also set GOWORK=off. That keeps a go.work file in a directory above the judge cache from being read. It is not reachable today.
Should: the comment at cmd/mesh-builder/main.go:316 still says "only judge builds mount" the judge cache. The replays now mount it too.
Since 2bee290: only check.go and release_branch_test.go changed (179 lines added, 9 removed). The judge-build path is unchanged, so the earlier points of 12248, 12264 and 12286 still hold, and so does the warm trunk judge (about 1 s, measured in 12295). Review 12295's findings 2 (clause 7) and 3 (the cold timings in the body) are done.
Verdict: CHANGES at 0214b45469ec
Independent review of novox/mesh-controller#329 at 0214b45469ecaf44e883936f4550ce78d24560c5 (issue 704, ADR 0358 v11, issue 709), together with novox/mesh-catalog#297 at 47ef2644aca1, reviewed as security-critical code for the live build nodes. I read review 12295.
**What I ran**
- `gofmt -l cmd internal examples`: nothing. `go vet ./...`: passed.
- `merge-check.sh` with a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap), stopped afterwards: exit 0, 26 packages ok, no FAIL, no NOT RUN.
- With check.go put back to 2bee290 and the new test kept, `TestTheReplaysRunWhereNoPullRequestReaches` fails. At the head, it passes.
- My own tests (not in the branch):
- A real poisoned Go cache entry for the replay package, compiled into `<workspace>/go-cache` at both the old path and the copy's path, plus the planted `-toolexec` Go env file and `.gitconfig` hook. With a judge cache, the replay ran honest and no hook ran. With check.go at 2bee290, the replay ran the poisoned code.
- The poisoned-cache and hook tests from the previous round, for the trunk judge and the kept release judge: both pass.
- A controller pull request that judges itself, whose judge rewrites `$MESH_CHECK_BESIDE/mesh-lab/replays` during the gate. With a judge cache, the replays run from the copy and the rewrite never runs. Without one, see finding 1.
**Issue 709 with a judge cache: fixed.** The copy is made right after mesh-lab's clone, before any container runs (check.go:457). The copy uses `git clone --no-local`, and the host's git runs it, not a check container. The replays get a fresh HOME and XDG_CONFIG_HOME, `GOENV=off`, `GIT_CONFIG_GLOBAL=/dev/null`, `GIT_CONFIG_NOSYSTEM=1`, `-buildvcs=false`, and the judge cache's Go build and module caches (check.go:637-647, 1305).
**The author's reasoning for sharing the judge cache holds.** The replays compile only mesh-lab's trunk and public modules that the checksum database verifies. Whatever holds the socket is already root-equivalent, so sharing the judge's Go cache gives the replays no reach they did not already have. The pull request's only input to the replays is the catalogue, which they read as data (see below).
**Where pull-request-written data goes, for each run in internal/builder**
- `in` (check.go:598), used by the check's containers, the gate's module check and merge gate, and the repository's own check: the workspace is mounted read-write, with HOME and GOCACHE in the workspace. PR data reaches it by design. It has no socket and no judge cache, and runs as the builder's user, not root.
- `inJudgeBuild` (check.go:624): it mounts the judge cache's `homes/<id>` and `go-cache`. It compiles fresh clones, and for a self-judge or a validator change it also compiles the pull request's Go code. That build uses `CGO_ENABLED=0`, `GOPROXY=off` and `-mod=vendor`, so the compile runs none of the pull request's code. It only writes cache entries under the build's own content-addressed keys (action IDs).
- The judge kept for a head is built and stored before any of the change runs (check.go:1201-1207). Nothing that mounts the workspace mounts it.
- `inReplays` (check.go:637): it has the socket and the replay base and caches, and the workspace through `in`. PR data that reaches it: `MESH_REPLAY_CATALOGUE`. mesh-lab's bed, store and resolver replays read image names, env, args and health commands from that catalogue. They start those images as unprivileged containers whose binds are only scratch directories. `git show`/`rev-parse` on the catalogue checkout ran no repository-config hook in my probe (git 2.56). This was already so on main.
- The throwaway store and bus (check.go:1637): their images come from the facts. No PR data reaches them.
- `dependencies.go` and `builder.go`: build trees and npm files. They are not changed here.
**Findings**
1. **Must change: without a judge cache, issue 709 is still open** (check.go:633-636 and 1270-1280).
- With `JudgeCache == ""`, `replay.lab` is empty, so the replays run `root/mesh-lab/replays` from the workspace, with the socket. Their Go cache (`root/judge-go-cache`) is also in the workspace.
- The gate runs before the replays, in containers that mount the workspace read-write. For a controller pull request (a self-judge) or a node-engine pull request (a validator change), that is the pull request's own code. "Every check empties the root before it clones" does not help, because this happens within one check.
- Reproduced: a self-judging controller pull request wrote `evil_test.go` into `root/mesh-lab/replays`, and it ran in the replays' `go test`, the run that mounts `/var/run/docker.sock`.
- The body names this state as supported ("A new mesh-builder without #297 builds judges and runs the replays cold").
- Fix: without a judge cache, either refuse the replays loudly (the gate's verdict is error, never pass), or make the copy and its caches outside the workspace in that case too. Then add the self-judge test for that case.
2. **Should: the replays' environment could also set `GOWORK=off`.** That keeps a `go.work` file in a directory above the judge cache from being read. It is not reachable today.
3. **Should: the comment at cmd/mesh-builder/main.go:316 still says "only judge builds mount"** the judge cache. The replays now mount it too.
**Since 2bee290:** only check.go and release_branch_test.go changed (179 lines added, 9 removed). The judge-build path is unchanged, so the earlier points of 12248, 12264 and 12286 still hold, and so does the warm trunk judge (about 1 s, measured in 12295). Review 12295's findings 2 (clause 7) and 3 (the cold timings in the body) are done.
mesh/merge-gate head 847ffd6d1285 merged into trunk 76304d9db817 — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every …
Without a judge cache the replays still ran mesh-lab's checkout in the workspace
with the container runtime's socket, so a self-judging pull request could write
a test into them (hq issue 709, review 12303). They now run from a copy in a
container volume of the check's own, made before anything of the change runs,
with a fresh home and throwaway caches, removed after the check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge check at 847ffd6d
Judged: head 847ffd6d1285 merged into trunk 76304d9db817; read beside it: mesh-catalog cb7bf94a77ea, mesh-controller-main 76304d9db817, mesh-host 1a2677882380, mesh-tools 954e1a53eef9
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
mesh/repo-check: PASS — its merge-check.sh passed
Delivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
tier 0: mesh-controller
tier 1: build-agent
ace: receives build-agent
g14: receives build-agent
novox: receives mesh-controller, build-agent
shanks: receives build-agent
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on shanks as build-1791988447107965492 (builds --log build-1791988447107965492).
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:47:24Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:47:24Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.095s
ok github.com/novox/mesh-controller/cmd/mesh-controller 187.738s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.036s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.056s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.029s
ok github.com/novox/mesh-controller/examples/route-proxy 1.187s
ok github.com/novox/mesh-controller/internal/artifacts 1.085s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.579s
ok github.com/novox/mesh-controller/internal/builder 94.646s
ok github.com/novox/mesh-controller/internal/catalogue 8.623s
ok github.com/novox/mesh-controller/internal/conditions 2.676s
ok github.com/novox/mesh-controller/internal/envfile 1.051s
ok github.com/novox/mesh-controller/internal/facts 1.063s
ok github.com/novox/mesh-controller/internal/identity 5.008s
ok github.com/novox/mesh-controller/internal/inventory 37.576s
ok github.com/novox/mesh-controller/internal/lease 30.927s
ok github.com/novox/mesh-controller/internal/licences 4.098s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.049s
ok github.com/novox/mesh-controller/internal/link 60.110s
ok github.com/novox/mesh-controller/internal/lint 2.606s
ok github.com/novox/mesh-controller/internal/outward 1.097s
ok github.com/novox/mesh-controller/internal/overlay 1.074s
ok github.com/novox/mesh-controller/internal/secrets 1.566s
ok github.com/novox/mesh-controller/internal/store 3.486s
ok github.com/novox/mesh-controller/internal/testbus 1.258s
ok github.com/novox/mesh-controller/internal/token 1.018s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.22s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.23s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.22s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.22s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.20s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.18s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.97s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.26s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.12s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.26s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.25s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.21s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.21s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.28s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.26s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.21s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.21s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.21s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.21s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.24s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.29s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.28s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.16s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.15s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.16s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.30s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.24s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.29s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.25s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.20s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.21s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.19s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.16s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.19s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.08s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.47s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.28s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.21s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.21s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.20s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.20s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.56s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.18s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.25s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.30s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.26s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.20s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.26s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.19s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.20s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.22s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.33s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.23s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.17s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.16s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.08s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.08s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.09s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.09s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.07s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.07s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.07s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.07s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.07s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.09s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.09s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.08s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.08s)
**Merge check** at `847ffd6d`
Judged: head `847ffd6d1285` merged into trunk `76304d9db817`; read beside it: mesh-catalog `cb7bf94a77ea`, mesh-controller-main `76304d9db817`, mesh-host `1a2677882380`, mesh-tools `954e1a53eef9`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- ace: receives build-agent
- g14: receives build-agent
- novox: receives mesh-controller, build-agent
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before build-agent is judged on its first machine
- read by no module's build: cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go, internal/builder/release_branch_test.go
Run by the build seat on shanks as `build-1791988447107965492` (`builds --log build-1791988447107965492`).
```
--- the gate: build-agent, mesh-controller
mesh-controller: ok, 60 tool(s); WARNING: merge-window ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T13:47:24Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-14T13:47:24Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 2 module(s) in 2 tier(s): build-agent, mesh-controller
notes:
- cmd/mesh-builder/release_test.go, cmd/mesh-controller/release_branch_test.go and internal/builder/release_branch_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.095s
ok github.com/novox/mesh-controller/cmd/mesh-controller 187.738s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.036s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.056s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.029s
ok github.com/novox/mesh-controller/examples/route-proxy 1.187s
ok github.com/novox/mesh-controller/internal/artifacts 1.085s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.579s
ok github.com/novox/mesh-controller/internal/builder 94.646s
ok github.com/novox/mesh-controller/internal/catalogue 8.623s
ok github.com/novox/mesh-controller/internal/conditions 2.676s
ok github.com/novox/mesh-controller/internal/envfile 1.051s
ok github.com/novox/mesh-controller/internal/facts 1.063s
ok github.com/novox/mesh-controller/internal/identity 5.008s
ok github.com/novox/mesh-controller/internal/inventory 37.576s
ok github.com/novox/mesh-controller/internal/lease 30.927s
ok github.com/novox/mesh-controller/internal/licences 4.098s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.049s
ok github.com/novox/mesh-controller/internal/link 60.110s
ok github.com/novox/mesh-controller/internal/lint 2.606s
ok github.com/novox/mesh-controller/internal/outward 1.097s
ok github.com/novox/mesh-controller/internal/overlay 1.074s
ok github.com/novox/mesh-controller/internal/secrets 1.566s
ok github.com/novox/mesh-controller/internal/store 3.486s
ok github.com/novox/mesh-controller/internal/testbus 1.258s
ok github.com/novox/mesh-controller/internal/token 1.018s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.22s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.23s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.22s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.22s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.20s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.18s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.97s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.26s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.12s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.26s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.25s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.21s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.21s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.28s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.26s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.21s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.21s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.21s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.21s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.24s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.29s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.28s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.16s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.15s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.16s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.30s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.24s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.29s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.25s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.20s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.21s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.19s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.16s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.19s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.08s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.47s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.28s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.21s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.21s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.20s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.20s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.56s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.18s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.25s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.30s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.26s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.22s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.20s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.26s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.19s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.20s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.22s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.33s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.23s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.17s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.16s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.08s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.08s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.09s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.09s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.07s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.07s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.07s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.07s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.07s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.09s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.09s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.08s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.08s)
```
gofmt -l cmd internal examples printed nothing. go vet ./... passed.
I ran merge-check.sh against a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap) and stopped the server afterwards. It exited 0, with 26 packages ok, no FAIL and no NOT RUN.
I put check.go back to 0214b45 and kept the new test. TestTheReplaysNeverReadWhatAPullRequestWroteWithOrWithoutAJudgeCache/judge_cache_false failed with "the test the pull request wrote into the replays ran with the socket". My own self-judge test from review 12303 also failed in the no-cache case. At the head, both pass.
I also ran my own tests from review 12303 (not in the branch), now in both cache states: a self-judging controller pull request that writes evil_test.go into $MESH_CHECK_BESIDE/mesh-lab/replays, the planted -toolexec Go env file and git hook, and a real poisoned Go cache entry for the replay package, planted at the workspace's path and at the copy's path. All of them pass at the head, and the poisoned-cache and hook tests for the trunk judge and the kept release judge still pass. In no case did the pull request's test or the hook run, and the poisoned entry was never read.
docker info fails here with "permission denied" on the socket, and I did not use sudo. So I could not run the real volume sequence (finding 2 says what the first live check must show).
Requested checks
(1) Issue 709 is now closed by construction in both states. The copy is made right after mesh-lab's clone (check.go:469), and hasReplays is read at that moment.
(3) GOWORK=off is set in ReplayEnv, the comment at cmd/mesh-builder/main.go:316 is fixed, and the body is fixed.
(4) Since 0214b45 the diff touches only cmd/mesh-builder/main.go, check.go and release_branch_test.go (178 lines added, 38 removed). judgeBuildDirs and inJudgeBuild are unchanged.
Findings
Must change: without a judge cache, the store replay writes to the build node's own disk, outside the workspace, and never cleans it up (check.go:649, together with mesh-lab replays/store_test.go:62-99).
The replays now run with /mesh-replays/mesh-lab/replays as their working directory. That path exists only inside the check's named volume.
mesh-lab's store replay depends on a host path: "a check's workspace is mounted into its containers at the same path, so the runtime binds what this test made". It makes os.MkdirTemp(Getwd(), "store-measure-") and passes that directory to sibling containers as HostConfig.Binds.
The container runtime creates a missing bind source on the host, as root. So each check without a judge cache will create /mesh-replays/mesh-lab/replays/store-measure-* on the build node's root filesystem. postgres then initialises its data there, and the check leaves the directories behind. The volume and the replays' own RemoveAll never see this path.
The replay will probably still pass, so nothing about this is loud.
This follows from the runtime's documented behaviour for Binds. I could not reproduce it live here.
Fix: give the volume a mount path that is identical on the host, or keep the volume path and have mesh-lab bind through a place it is given. Alternatively, since #297 delivers with this pull request, refuse the replays loudly (gate verdict error) when there is no judge cache.
Should: say the volume in the build log, and say when removing it fails.
The removal at check.go:345 discards its error, so a leaked volume stays unnoticed. If the build agent dies, nothing sweeps volumes labelled with mesh.build.
Today the first live check can prove the volume path only indirectly: the report must show --- the replays (mesh-lab replays/) followed by go test's ok, and it must not say mesh-lab could not be copied for its replays. A create or copy failure is loud (the check's verdict is error).
A mount failure of the replays' container is reported as fail with "a replay of a core incident fails with this change", which blames the change for a problem of the build node (check.go:1096).
Should: refuse an id that is not safe instead of using the name "check" (check.go:1285-1291). Today every such id gets the same volume, mesh-check-check-replays, and the pre-removal at check.go:1328 would hit a concurrent check's volume. Ids from link.NewBuildID (build-<nanoseconds>) are unique and safe, so this does not happen with the ids the controller makes today.
Verdict: CHANGES at 847ffd6d1285
Independent review of novox/mesh-controller#329 at 847ffd6d1285a35d5e9fe572d05b55b8dbe18fd2 (issues 704 and 709, ADR 0358 v11), which delivers together with novox/mesh-catalog#297 at 47ef2644aca1. I read review 12303 first.
**What I ran**
- `gofmt -l cmd internal examples` printed nothing. `go vet ./...` passed.
- I ran `merge-check.sh` against a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap) and stopped the server afterwards. It exited 0, with 26 packages ok, no FAIL and no NOT RUN.
- I put check.go back to 0214b45 and kept the new test. `TestTheReplaysNeverReadWhatAPullRequestWroteWithOrWithoutAJudgeCache/judge_cache_false` failed with "the test the pull request wrote into the replays ran with the socket". My own self-judge test from review 12303 also failed in the no-cache case. At the head, both pass.
- I also ran my own tests from review 12303 (not in the branch), now in both cache states: a self-judging controller pull request that writes `evil_test.go` into `$MESH_CHECK_BESIDE/mesh-lab/replays`, the planted `-toolexec` Go env file and git hook, and a real poisoned Go cache entry for the replay package, planted at the workspace's path and at the copy's path. All of them pass at the head, and the poisoned-cache and hook tests for the trunk judge and the kept release judge still pass. In no case did the pull request's test or the hook run, and the poisoned entry was never read.
- `docker info` fails here with "permission denied" on the socket, and I did not use sudo. So I could not run the real volume sequence (finding 2 says what the first live check must show).
**Requested checks**
- (1) Issue 709 is now closed by construction in both states. The copy is made right after mesh-lab's clone (check.go:469), and `hasReplays` is read at that moment.
- (3) `GOWORK=off` is set in `ReplayEnv`, the comment at cmd/mesh-builder/main.go:316 is fixed, and the body is fixed.
- (4) Since 0214b45 the diff touches only cmd/mesh-builder/main.go, check.go and release_branch_test.go (178 lines added, 38 removed). `judgeBuildDirs` and `inJudgeBuild` are unchanged.
**Findings**
1. **Must change: without a judge cache, the store replay writes to the build node's own disk, outside the workspace, and never cleans it up** (check.go:649, together with mesh-lab replays/store_test.go:62-99).
- The replays now run with `/mesh-replays/mesh-lab/replays` as their working directory. That path exists only inside the check's named volume.
- mesh-lab's store replay depends on a host path: "a check's workspace is mounted into its containers at the same path, so the runtime binds what this test made". It makes `os.MkdirTemp(Getwd(), "store-measure-")` and passes that directory to sibling containers as `HostConfig.Binds`.
- The container runtime creates a missing bind source on the host, as root. So each check without a judge cache will create `/mesh-replays/mesh-lab/replays/store-measure-*` on the build node's root filesystem. postgres then initialises its data there, and the check leaves the directories behind. The volume and the replays' own `RemoveAll` never see this path.
- The replay will probably still pass, so nothing about this is loud.
- This follows from the runtime's documented behaviour for Binds. I could not reproduce it live here.
- Fix: give the volume a mount path that is identical on the host, or keep the volume path and have mesh-lab bind through a place it is given. Alternatively, since #297 delivers with this pull request, refuse the replays loudly (gate verdict error) when there is no judge cache.
2. **Should: say the volume in the build log, and say when removing it fails.**
- The removal at check.go:345 discards its error, so a leaked volume stays unnoticed. If the build agent dies, nothing sweeps volumes labelled with `mesh.build`.
- Today the first live check can prove the volume path only indirectly: the report must show `--- the replays (mesh-lab replays/)` followed by go test's `ok`, and it must not say `mesh-lab could not be copied for its replays`. A create or copy failure is loud (the check's verdict is error).
- A mount failure of the replays' container is reported as `fail` with "a replay of a core incident fails with this change", which blames the change for a problem of the build node (check.go:1096).
3. **Should: refuse an id that is not safe instead of using the name "check"** (check.go:1285-1291). Today every such id gets the same volume, `mesh-check-check-replays`, and the pre-removal at check.go:1328 would hit a concurrent check's volume. Ids from `link.NewBuildID` (`build-<nanoseconds>`) are unique and safe, so this does not happen with the ids the controller makes today.
All checks were successful
mesh/merge-gate head 847ffd6d1285 merged into trunk 76304d9db817 — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every …
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.
What changed
This builds hq ADR 0358 (accepted, version 11) for hq issue 704, and fixes hq issue 709. Issue 709: mesh-lab's replays could run code a pull request wrote, while holding the container runtime's socket. This delivers together with mesh-catalog#297, which gives the build agent its judge cache. Both use the branch name
fix/704-release-branch-judge, which makes them one delivery group.releaseBranchOfasks the forge nothing for a base that is the repository's own trunk (the branch its module follows, or main when it records none) or mesh-controller's trunk. For any other base it asks the forge one question: does mesh-controller have a branch of that name? A 404 means no release branch. An answer that names no branch, names another branch, or cannot be read is an error.releaseJudgebuilds mesh-controller at the release branch. It uses mesh-host's validator from mesh-host's same-named branch, or the copy the judge vendors when there is none. A mesh-host pull request is judged with its own validator. A controller pull request judges itself.release,judged-by,validatorandbeside-at. Both status summaries open with[release <branch>, judged by its controller <commit>].GIT_CONFIG_GLOBAL=/dev/null,GIT_CONFIG_NOSYSTEM=1,GOENV=off,-buildvcs=false, andGOWORK=offfor the replays.MESH_JUDGE_CACHE): the copy and the homes are under its homes/, and the caches are its warm Go build cache and module cache. Only judge builds and the replays mount it. The replays may share it because their build is as trusted as a judge's: they run mesh-lab's trunk, which is reviewed code, against this check's judge, and nothing of the pull request except its catalogue, which they read as data.Trunk checks
The judge and the replays of a trunk check now run in the same isolated environment, which is stricter than before and closes issues 482 and 709 for them.
What a trunk check reads beside it, and what its verdict says, are unchanged.
Proof (tests written first)
internal/builder:-toolexechook and poisoned caches are neither run nor read during the replays;cmd/mesh-controller: release detection, trunks, the forge's answer read strictly, the beside refs, §7, and the verdict's fields.cmd/mesh-builder:release,elseandMESH_JUDGE_CACHEare passed through.Commands run:
gofmt -l,go vet ./..., andmerge-check.shagainst a throwaway PostgreSQL over TCP 127.0.0.1 (dynamic_shared_memory_type=mmap). It exited 0, with no FAIL and no NOT RUN.Rollout order
The delivery group is this pull request (mesh-controller, plus the build agent's mesh-builder image built from it) and mesh-catalog#297. The build agent's mesh-builder must carry this before the controller, or with it.
releaseandelse. mesh-lab is still asked at main. It builds the judge from mesh-controller at the release branch, by today's rule. A repository without the release branch fails its clone, so the check errors and never passes. The replays still run as on main today, open to issue 709, until the new mesh-builder lands.Not done here: the forge's comment line "read beside it:" prints commits only.
Reviewer's checklist
omitempty, and the readers are lenient.Delivery
novox/mesh-controller@847ffd6d1285— ready since 2026-10-14T14:40:17ZDelivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
Group
fix/704-release-branch-judge, in order:after: novox/mesh-catalogin novox/mesh-controller#329's description, orafter: novox/mesh-controllerin novox/mesh-catalog#297'sTransitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
4a75cc51Judged: head
4a75cc51dda6merged into trunk535c7641ac41; read beside it: mesh-catalogb15846dd6e78, mesh-controller-main535c7641ac41, mesh-host1a2677882380, mesh-tools954e1a53eef9mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
Run by the build seat on novox as
build-1791982177864857946(builds --log build-1791982177864857946).Merge check at
ea7d91bfJudged: head
ea7d91bff190merged into trunk535c7641ac41; read beside it: mesh-catalogb15846dd6e78, mesh-controller-main535c7641ac41, mesh-host1a2677882380, mesh-tools954e1a53eef9mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
Run by the build seat on shanks as
build-1791982647000590148(builds --log build-1791982647000590148).Verdict: CHANGES at
ea7d91bff1Independent review of novox/mesh-controller#329 at
ea7d91bff1(4a75cc51plusea7d91bf), for issue 704 and ADR 0358. ADR 0358 is proposed, not accepted: it is at version 7, and its latest knowledge-base review (13:02 UTC) says "changes", on the same point as finding 1 below.What I ran in my own worktree:
gofmt -l cmd internal examplesprinted nothing.go vet ./...passed.merge-check.shexited 0 against a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap), with 26 packages ok. I stopped the server afterwards.What I checked and found correct:
builder.Checkon main535c7641and on this head, and compared the verdict and the log. They are identical apart from timestamps and the four new empty fields, which areomitemptyon the wire.besideOf(…, "")gives the same refs as before. A base ofmain, of the module's followed branch or of the controller's trunk asks the forge nothing.gitea_apireally does answer{"result":{"name":…}}, and a missing branch really does fail with…: 404 {…}; I checked both on the live forge. An unanswered forge errors the check.mesh-controllerbeside the check, at the release branch. It is built before any code of the change runs, and it is kept outside the mounted workspace. The cache key is the full commit of the controller, plus mesh-host's commit when mesh-host's validator is used. When the branch moves, the key changes, so a stale judge cannot be served. A controller pull request still judges itself.release/elseand checks as before. An old builder with a new controller checks outfeat/57-…in every repository beside the check. mesh-lab and mesh-tools have no such branch (404 on the live forge), so today that check errors.Findings:
replays/with/var/run/docker.sockmounted. The design behind it, check.go:64 and :998 ("mesh-lab's main, reviewed code — get the socket"), allows that only for mesh-lab's main. With this change, anyone who can create a branch with a release branch's name in mesh-lab gets root on the build node at the next release-branch check. Nothing checks that the branch is protected. Keep mesh-lab at main, as the ADR review asks, and add a test for it.result.nameis empty or missing returns false with no error, so the check runs as a trunk check. An empty name should be an error.base == "main"guard is untested. The guard is at checks.go:334. The test entries all recordRef: "main", so the followed-branch guard already covers that case, and removing themainguard passes every test. Add a case where a module recordsRef: "".GOCACHE=<workspace>/go-cache(check.go:1134). The change's own script writes to that same cache (check.go:612). This weakness existed before (issue 482, shared build caches), but the judge cache now keeps a judge built from a poisoned Go cache for every check of that head. Build the release judge with a Go cache outside the workspace.Verdict: CHANGES at
48b2906b5cThis is an independent review of novox/mesh-controller#329 at
48b2906b5c, for issue 704 and ADR 0358. ADR 0358 is still proposed, at version 9. The knowledge base's latest review, of version 8, says "changes", and version 9 has no review yet.What I ran in my own worktree
gofmt -l cmd internal examplesprinted nothing.go vet ./...passed.merge-check.shexited 0 against a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap). 26 packages were ok, with no FAIL and no NOT RUN. I stopped the server afterwards.What I checked and found correct
builder.Checkon main535c7641and on this head. The verdict and the log are identical apart from fresh commit ids, the time taken and four new empty fields. Those fields areomitemptyon the wire.Ref: mainwith noElsefor a release branch. The build seat (check.go:432) turns aRef: <release>, Else: mainrequest for mesh-lab into main. I reverted each of these on its own, and each time its test failed (TestBesideAReleaseBranch…,TestAReleaseBranchCheckReadsMeshLabAtItsTrunkEvenWhenItHasThatBranch).branchAnsweredtreats an empty name, another name, an unreadable answer and a non-404 error as errors. With the lenient line restored, the test fails.trunkOfis tested withmasterand with a controller that followstrunk. Restoring thebase == "main"guard makes the test fail.feat/57-config-and-provisioningtoday: I got a 404 from the live forge. The delivery plan moves the controller in tier 0 and build-agent in tier 1, so the "or in the same walk" window exists, and the body describes what happens during it.<workspace>-judges, which no container mounts.Findings
HOME=<workspace>and the workspace mounted read-write. The workspace's HOME is never cleaned:forgetLeftCredentialsremoves onlygit-credentialsand.npmrc.go buildstamps the version from git (-buildvcsis not off), and git reads$HOME/.gitconfig. One pull request'smerge-check.shcan therefore write<workspace>/.gitconfigwithcore.fsmonitor = <script>. At the next release-branch check, that script runs inside the judge's build, before compilation, and can rewrite the release controller's sources undercheck/mesh-controller. The poisoned judge is then kept in the judge cache under the honest commit key, and it judges every check of that head. I reproduced this locally: withHOMEholding such a.gitconfig,GOENV=offand a freshGOCACHE,go buildproduced a binary from sources the hook rewrote, while HEAD, and so the cache key, stayed at its commit.GOENV=offcloses only Go's own environment file.XDG_CONFIG_HOMEthere too),GIT_CONFIG_GLOBAL=/dev/null,GIT_CONFIG_NOSYSTEM=1, and-buildvcs=falseas the toolchain already uses (toolchain.go:176)..gitconfigin the workspace's HOME, and prove the kept judge does not change.judge-with-this-validator). It still usesGOCACHE=<workspace>/go-cacheand the workspace HOME. That judge is not kept across checks, but it is the release judge of that check, and the review asked for a cache no pull request's script can write. Use the same fresh cache and environment as in finding 1.Else, not on the release branch. At check.go:432, a request ofRef: <release>with noElsefor mesh-lab is still cloned at the release branch. The current controller never sends that request, so this is defence in depth. Still, the PR body says the seat "refuses a release ref for mesh-lab", and the code does not. Key the guard onspec.Release != "" && b.Ref == spec.Release, or refuse any ref but main, and test that case.trunkOf's "main when it records none" fallback is untested. It is at cmd/mesh-controller/checks.go:372. ReplacingtrunkOfwithfollowedBranchpasses every test. This is the earlier review's point 3 (a module that recordsRef: ""). A repository with no module is never compared with its forge default branch, only asked about once (a 404 means no release branch). That is acceptable, but say so in the comment.Merge check at
48b2906bJudged: head
48b2906b5ce4merged into trunk535c7641ac41; read beside it: mesh-catalog50861c74f8b4, mesh-controller-main535c7641ac41, mesh-host1a2677882380, mesh-tools954e1a53eef9mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
Run by the build seat on novox as
build-1791983635010871240(builds --log build-1791983635010871240).Out of date when it landed: out of date: judged against trunk
535c7641ac, the trunk is now c975dbf7b053; judged again on a recheck or when it is mergedMerge check at
b7084a19Judged: head
b7084a19e9bfmerged into trunkc975dbf7b053; read beside it: mesh-catalog02427a60ef78, mesh-controller-mainc975dbf7b053, mesh-host1a2677882380, mesh-tools954e1a53eef9mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
Run by the build seat on novox as
build-1791984660282163421(builds --log build-1791984660282163421).Out of date when it landed: out of date: judged against trunk
c975dbf7b0, the trunk is now 76304d9db817; judged again on a recheck or when it is mergedVerdict: CHANGES at
b7084a19e9This is an independent review of novox/mesh-controller#329 at
b7084a19e9, for issue 704 and ADR 0358. I reviewed it as core security code that runs on the live build nodes. ADR 0358 is accepted, at version 11. The knowledge base's latest review is of version 10 (13:23 UTC) and says "approve".What I ran in my own worktree
gofmt -l cmd internal examplesprinted nothing.go vet ./...passed.merge-check.shagainst a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap): exited 0, with 26 packages ok and no FAIL or NOT RUN. I stopped the server afterwards.What I checked and found correct
JudgeBuildEnv(check.go:1183): the running controller (judge), a controller pull request's own controller (self), the build with the change's validator, and the release judge. Each build sets its own HOME and XDG_CONFIG_HOME,GIT_CONFIG_GLOBAL=/dev/null,GIT_CONFIG_NOSYSTEM=1,GOENV=off,-buildvcs=false,GOPROXY=off, and a fresh GOCACHE and GOPATH outside the workspace..gitconfigand XDG fsmonitor hook and the Go env file, as the PR's tests do.<workspace>/go-cache. Then I rewrote the cached outputs, keeping their size, so that "the vendored validator" reads "the poisoned validator".48b2906b, all four tests fail: the PR's two and my two. The trunk judge then says "main's controller with the poisoned validator".mainonly (checks.go:312-321). The build seat forces main with a fallback and without one (check.go:432-443). When I reverted the seat's new condition,TestTheBuildSeatNeverReadsMeshLabAtAReleaseBranchfailed.TestATrunkIsMainWhenTheSourceRecordsNonefailed.go build.Findings
os.MkdirTemp("", "mesh-check-judge-")runs inside the build-agent container. That container mounts only mesh-state, the workspace (at the same path) and the docker socket (mesh-catalog modules/build-agent/module.json). Its/tmpis its own.--volume /tmp/mesh-check-judge-N:/tmp/mesh-check-judge-Nis therefore resolved on the host. dockerd creates that directory, and the toolchain container fills it with a full Go cache (235 MB for this repository, measured).defer os.RemoveAll(judgeHome)removes only the empty copy in the build-agent container. Every check leaves a few hundred MB in the host's /tmp, or in memory where /tmp is a tmpfs. ThewithinDirguard checks the wrong filesystem.<workspace>-judges(mesh-builder main.gojudgeCacheOf). It works, but it lives in the build-agent container's own layer, so it is lost at every redeploy.535c7641, every judge (self, validator, and the running controller) was built with the warm shared<workspace>/go-cache. Now each check compiles its judge cold.selfjudge can be altered by a hook that an earlier, different pull request planted.go buildwith CGO off and fixed GOFLAGS runs none of the change's code, so it is safe to share.Merge check at
2bee290eJudged: head
2bee290eea56merged into trunk76304d9db817; read beside it: mesh-catalogcb7bf94a77ea, mesh-controller-main76304d9db817, mesh-host1a2677882380, mesh-tools954e1a53eef9mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
Run by the build seat on ace as
build-1791986017411722467(builds --log build-1791986017411722467).Merge check at
2bee290eJudged: head
2bee290eea56merged into trunk76304d9db817; read beside it: mesh-catalogcb7bf94a77ea, mesh-controller-main76304d9db817, mesh-host1a2677882380, mesh-tools954e1a53eef9mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
Run by the build seat on ace as
build-1791986017411722467(builds --log build-1791986017411722467).Merge check at
2bee290eJudged: head
2bee290eea56merged into trunk76304d9db817; read beside it: mesh-catalogcb7bf94a77ea, mesh-controller-main76304d9db817, mesh-host1a2677882380, mesh-tools954e1a53eef9mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
Run by the build seat on ace as
build-1791986017411722467(builds --log build-1791986017411722467).Verdict: CHANGES at
2bee290eeaIndependent review of novox/mesh-controller#329 at
2bee290eea(issue 704, ADR 0358 v11), together with novox/mesh-catalog#297 at 47ef2644aca1, as core code for the live build nodes. I read review 12286.What I ran
gofmt -l cmd internal examples: nothing.go vet ./...: passed.merge-check.shwith a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap), stopped afterwards: exit 0, 26 packages ok, no FAIL, no NOT RUN.merge-check.shat #297's head with MESH_GATE built from this head (MESH_CHECK_MODULES=build-agent,gitea): exit 0.judges/: a poisoned Go cache entry and a.gitconfig/fsmonitor hook in the workspace reach neither a trunk judge nor the kept release judge, across two checks. Both pass.JudgeBuildEnvagainst one persistent Go cache took 14.9 s cold, then 0.88 s and 0.82 s warm (12 cores, toolchain on the host, no container start). The body's "about 1 s" holds.What I checked and found correct (review 12286's points)
docker runin the build seat: the check's own containers (in, check.go:577) mount only the workspace; the replays add only the runtime's socket (check.go:1055);dependencies.goandbuilder.gomount build trees and npm files. OnlyinJudgeBuild(check.go:611-619) mounts the judge cache'shomes/<id>andgo-cache/.judgeBuildDirs(check.go:1199) makes the home under the judge cache, which the agent sees at the host's own path, anddefer os.RemoveAll(judgeHome)removes it there. Nothing in the judge path usesos.MkdirTempany more. Without a judge cache, both go under the check's root, which is emptied before the clones (check.go:315) and removed afterwards.Findings
go testin a container that has/var/run/docker.sock, withHOME=<workspace>(the default inin), noGOENV=off, noGIT_CONFIG_GLOBAL, andGOCACHE=<workspace>/go-cache. A check's own script writes all of these.<workspace>/.config/go/envwithGOFLAGS=-toolexec=<hook>(the same fileaPlantedWorkspaceplants) and gave mesh-lab areplays/package. The hook ran in<workspace>/check/mesh-lab/replays, in the run that carries--volume /var/run/docker.sock. With the socket, that program candocker run -v <judge cache>:…, or the host's root.<workspace>/go-cachereaches the replays' test binary the same way.GOENV=off,GIT_CONFIG_GLOBAL=/dev/null,GIT_CONFIG_NOSYSTEM=1, and a Go cache that no check container mounts (the judge cache's, or one of its own). Then add the planted-env test for the replays.ADR 0358 §5: the claim holds. The gitea module's
weighTrunksweighs every open pull request's base, andmerge.ts:95compares against the pull request's own base. #297's new test passes with Node's runner (8 of 8 trunk tests).Merge check at
0214b454Judged: head
0214b45469ecmerged into trunk76304d9db817; read beside it: mesh-catalogcb7bf94a77ea, mesh-controller-main76304d9db817, mesh-host1a2677882380, mesh-tools954e1a53eef9mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
Run by the build seat on shanks as
build-1791987347185392290(builds --log build-1791987347185392290).Verdict: CHANGES at
0214b45469Independent review of novox/mesh-controller#329 at
0214b45469(issue 704, ADR 0358 v11, issue 709), together with novox/mesh-catalog#297 at 47ef2644aca1, reviewed as security-critical code for the live build nodes. I read review 12295.What I ran
gofmt -l cmd internal examples: nothing.go vet ./...: passed.merge-check.shwith a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap), stopped afterwards: exit 0, 26 packages ok, no FAIL, no NOT RUN.2bee290and the new test kept,TestTheReplaysRunWhereNoPullRequestReachesfails. At the head, it passes.<workspace>/go-cacheat both the old path and the copy's path, plus the planted-toolexecGo env file and.gitconfighook. With a judge cache, the replay ran honest and no hook ran. With check.go at2bee290, the replay ran the poisoned code.$MESH_CHECK_BESIDE/mesh-lab/replaysduring the gate. With a judge cache, the replays run from the copy and the rewrite never runs. Without one, see finding 1.Issue 709 with a judge cache: fixed. The copy is made right after mesh-lab's clone, before any container runs (check.go:457). The copy uses
git clone --no-local, and the host's git runs it, not a check container. The replays get a fresh HOME and XDG_CONFIG_HOME,GOENV=off,GIT_CONFIG_GLOBAL=/dev/null,GIT_CONFIG_NOSYSTEM=1,-buildvcs=false, and the judge cache's Go build and module caches (check.go:637-647, 1305).The author's reasoning for sharing the judge cache holds. The replays compile only mesh-lab's trunk and public modules that the checksum database verifies. Whatever holds the socket is already root-equivalent, so sharing the judge's Go cache gives the replays no reach they did not already have. The pull request's only input to the replays is the catalogue, which they read as data (see below).
Where pull-request-written data goes, for each run in internal/builder
in(check.go:598), used by the check's containers, the gate's module check and merge gate, and the repository's own check: the workspace is mounted read-write, with HOME and GOCACHE in the workspace. PR data reaches it by design. It has no socket and no judge cache, and runs as the builder's user, not root.inJudgeBuild(check.go:624): it mounts the judge cache'shomes/<id>andgo-cache. It compiles fresh clones, and for a self-judge or a validator change it also compiles the pull request's Go code. That build usesCGO_ENABLED=0,GOPROXY=offand-mod=vendor, so the compile runs none of the pull request's code. It only writes cache entries under the build's own content-addressed keys (action IDs).inReplays(check.go:637): it has the socket and the replay base and caches, and the workspace throughin. PR data that reaches it:MESH_REPLAY_CATALOGUE. mesh-lab's bed, store and resolver replays read image names, env, args and health commands from that catalogue. They start those images as unprivileged containers whose binds are only scratch directories.git show/rev-parseon the catalogue checkout ran no repository-config hook in my probe (git 2.56). This was already so on main.dependencies.goandbuilder.go: build trees and npm files. They are not changed here.Findings
JudgeCache == "",replay.labis empty, so the replays runroot/mesh-lab/replaysfrom the workspace, with the socket. Their Go cache (root/judge-go-cache) is also in the workspace.evil_test.gointoroot/mesh-lab/replays, and it ran in the replays'go test, the run that mounts/var/run/docker.sock.GOWORK=off. That keeps ago.workfile in a directory above the judge cache from being read. It is not reachable today.Since
2bee290: only check.go and release_branch_test.go changed (179 lines added, 9 removed). The judge-build path is unchanged, so the earlier points of 12248, 12264 and 12286 still hold, and so does the warm trunk judge (about 1 s, measured in 12295). Review 12295's findings 2 (clause 7) and 3 (the cold timings in the body) are done.Merge check at
847ffd6dJudged: head
847ffd6d1285merged into trunk76304d9db817; read beside it: mesh-catalogcb7bf94a77ea, mesh-controller-main76304d9db817, mesh-host1a2677882380, mesh-tools954e1a53eef9mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step
Run by the build seat on shanks as
build-1791988447107965492(builds --log build-1791988447107965492).Verdict: CHANGES at
847ffd6d12Independent review of novox/mesh-controller#329 at
847ffd6d12(issues 704 and 709, ADR 0358 v11), which delivers together with novox/mesh-catalog#297 at 47ef2644aca1. I read review 12303 first.What I ran
gofmt -l cmd internal examplesprinted nothing.go vet ./...passed.merge-check.shagainst a throwaway PostgreSQL (TCP 127.0.0.1, dynamic_shared_memory_type=mmap) and stopped the server afterwards. It exited 0, with 26 packages ok, no FAIL and no NOT RUN.0214b45and kept the new test.TestTheReplaysNeverReadWhatAPullRequestWroteWithOrWithoutAJudgeCache/judge_cache_falsefailed with "the test the pull request wrote into the replays ran with the socket". My own self-judge test from review 12303 also failed in the no-cache case. At the head, both pass.evil_test.gointo$MESH_CHECK_BESIDE/mesh-lab/replays, the planted-toolexecGo env file and git hook, and a real poisoned Go cache entry for the replay package, planted at the workspace's path and at the copy's path. All of them pass at the head, and the poisoned-cache and hook tests for the trunk judge and the kept release judge still pass. In no case did the pull request's test or the hook run, and the poisoned entry was never read.docker infofails here with "permission denied" on the socket, and I did not use sudo. So I could not run the real volume sequence (finding 2 says what the first live check must show).Requested checks
hasReplaysis read at that moment.GOWORK=offis set inReplayEnv, the comment at cmd/mesh-builder/main.go:316 is fixed, and the body is fixed.0214b45the diff touches only cmd/mesh-builder/main.go, check.go and release_branch_test.go (178 lines added, 38 removed).judgeBuildDirsandinJudgeBuildare unchanged.Findings
/mesh-replays/mesh-lab/replaysas their working directory. That path exists only inside the check's named volume.os.MkdirTemp(Getwd(), "store-measure-")and passes that directory to sibling containers asHostConfig.Binds./mesh-replays/mesh-lab/replays/store-measure-*on the build node's root filesystem. postgres then initialises its data there, and the check leaves the directories behind. The volume and the replays' ownRemoveAllnever see this path.mesh.build.--- the replays (mesh-lab replays/)followed by go test'sok, and it must not saymesh-lab could not be copied for its replays. A create or copy failure is loud (the check's verdict is error).failwith "a replay of a core incident fails with this change", which blames the change for a problem of the build node (check.go:1096).mesh-check-check-replays, and the pre-removal at check.go:1328 would hit a concurrent check's volume. Ids fromlink.NewBuildID(build-<nanoseconds>) are unique and safe, so this does not happen with the ids the controller makes today.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.