Part of issue 145 (a machine reads healthy while its modules cannot reach each other). Goes with mesh-catalog's pull request on the same branch name, which declares the checks this reads.
What
testdata/store-tests lists the two tests of the provider hold:
TestOneProviderDownAndThreeConsumersFailingAreOneCondition (ADR 0240 rule 5, "how it is checked")
The issue's diagnosis (note of 2026-10-14) said nothing reads needs. That is wrong: Phase C of to-be 48 was merged on 2026-10-07 as #111 (cmd/mesh-controller/provider_hold.go). needs is carried back in the node-engine's statement (mesh-host liveness.NeedsOf), a consumer's check finding is held under its provider's module.<provider>.<machine>.unhealthy condition (urgent, listing who waits on it), and the consumer's gate reads healthWaiting, never put back at its bound. What was missing is that the rule 5 test needs the store and skips without one, and it was not in testdata/store-tests, so the merge check passed it without running it (issue 459's gap).
So there is no code change here, and no test that fails on main: the behaviour is on main.
How it was tested
Against a throwaway PostgreSQL: both tests pass on main.
The hold taken out (heldFinding returning false): the rule 5 test fails with raised [module.shop.laptop.unhealthy module.wiki.laptop.unhealthy module.crm.anchor.unhealthy module.db.anchor.unhealthy]; want the provider's alone.
MESH_CHECK_STORE_ONLY=1 MESH_TEST_POSTGRES=… sh merge-check.sh: exit 0, both listed tests named as passed.
The other hold tests (waiting provider, ADR 0292; failed wait, issue 450) run without the store and are not listed.
Part of issue 145.
Part of issue 145 (a machine reads healthy while its modules cannot reach each other). Goes with mesh-catalog's pull request on the same branch name, which declares the checks this reads.
## What
`testdata/store-tests` lists the two tests of the provider hold:
- `TestOneProviderDownAndThreeConsumersFailingAreOneCondition` (ADR 0240 rule 5, "how it is checked")
- `TestAConsumerFailingBesideAHealthyProviderIsItsOwn`
## Why
The issue's diagnosis (note of 2026-10-14) said nothing reads `needs`. That is wrong: Phase C of to-be 48 was merged on 2026-10-07 as #111 (`cmd/mesh-controller/provider_hold.go`). `needs` is carried back in the node-engine's statement (mesh-host `liveness.NeedsOf`), a consumer's check finding is held under its provider's `module.<provider>.<machine>.unhealthy` condition (urgent, listing who waits on it), and the consumer's gate reads `healthWaiting`, never put back at its bound. What was missing is that the rule 5 test needs the store and skips without one, and it was not in `testdata/store-tests`, so the merge check passed it without running it (issue 459's gap).
So there is no code change here, and no test that fails on main: the behaviour is on main.
## How it was tested
- Against a throwaway PostgreSQL: both tests pass on main.
- The hold taken out (`heldFinding` returning false): the rule 5 test fails with `raised [module.shop.laptop.unhealthy module.wiki.laptop.unhealthy module.crm.anchor.unhealthy module.db.anchor.unhealthy]; want the provider's alone`.
- `MESH_CHECK_STORE_ONLY=1 MESH_TEST_POSTGRES=… sh merge-check.sh`: exit 0, both listed tests named as passed.
The other hold tests (waiting provider, ADR 0292; failed wait, issue 450) run without the store and are not listed.
Part of issue 145.
mesh/merge-gate head cebc593627d3 merged into trunk 2959c8143536 — pass: builds build-agent → ace, g14, novox, shanks; no bus step; every machine composes …
The rule 5 test of ADR 0240 (one provider down, three consumers, one
condition) and its healthy-provider twin need the store and skip without
one; unlisted, the merge check passed them without running them.
Deliverynovox/mesh-controller@cebc593627d3 — delivered since 2026-10-14T05:19:54Z
Delivery plan — builds build-agent → ace, g14, novox, shanks; no bus step
tier 0: build-agent
ace: receives build-agent
g14: receives build-agent
novox: receives 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 01:22 (new) → proposed (announced): novox/mesh-controller#319's head announced
2026-10-14 01:26 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit
2026-10-14 01:26 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-14 05:19 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
2026-10-14 05:19 published → delivered (done): its walk plan-1791955100529922192 moved nothing: build-agent matched what runs, its build source holding none of the files changed, so the build the mesh holds is its build (novox/hq issue 611)
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-controller@cebc593627d3` — **delivered** since 2026-10-14T05:19:54Z
**Delivery plan** — builds build-agent → ace, g14, novox, shanks; no bus step
- tier 0: build-agent
- ace: receives build-agent
- g14: receives build-agent
- novox: receives 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/145-a-consumer-is-held-under-its-provider`, in order: novox/mesh-controller@cebc593627d3 → novox/mesh-catalog@2bb5d344f6f1
- novox/mesh-controller@cebc593627d3 before novox/mesh-catalog@2bb5d344f6f1: declared
**Transitions**
- 2026-10-14 01:22 (new) → proposed (announced): novox/mesh-controller#319's head announced
- 2026-10-14 01:26 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit
- 2026-10-14 01:26 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-14 05:19 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
- 2026-10-14 05:19 published → delivered (done): its walk plan-1791955100529922192 moved nothing: build-agent matched what runs, its build source holding none of the files changed, so the build the mesh holds is its build (novox/hq issue 611)
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
Merge check at cebc5936
Judged: head cebc593627d3 merged into trunk 2959c8143536; read beside it: mesh-catalog ebf7f3773dc7, mesh-controller-main 2959c8143536, 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/repo-check: PASS — its merge-check.sh passed
Delivery plan — builds build-agent → ace, g14, novox, shanks; no bus step
tier 0: build-agent
ace: receives build-agent
g14: receives build-agent
novox: receives 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
Run by the build seat on ace as build-1791940945578777763 (builds --log build-1791940945578777763).
--- the gate: build-agent
judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T01:08:55Z 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-14T01:08:55Z
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 0 module(s) in 0 tier(s)
notes:
- testdata/store-tests 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.084s
ok github.com/novox/mesh-controller/cmd/mesh-controller 151.935s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.015s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.016s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.015s
ok github.com/novox/mesh-controller/examples/route-proxy 1.107s
ok github.com/novox/mesh-controller/internal/artifacts 1.035s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.003s
ok github.com/novox/mesh-controller/internal/builder 33.307s
ok github.com/novox/mesh-controller/internal/catalogue 7.638s
ok github.com/novox/mesh-controller/internal/conditions 2.540s
ok github.com/novox/mesh-controller/internal/envfile 1.059s
ok github.com/novox/mesh-controller/internal/facts 1.090s
ok github.com/novox/mesh-controller/internal/identity 4.295s
ok github.com/novox/mesh-controller/internal/inventory 29.733s
ok github.com/novox/mesh-controller/internal/lease 17.711s
ok github.com/novox/mesh-controller/internal/licences 3.551s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.090s
ok github.com/novox/mesh-controller/internal/link 57.537s
ok github.com/novox/mesh-controller/internal/lint 2.293s
ok github.com/novox/mesh-controller/internal/outward 1.091s
ok github.com/novox/mesh-controller/internal/overlay 1.080s
ok github.com/novox/mesh-controller/internal/secrets 1.431s
ok github.com/novox/mesh-controller/internal/store 3.227s
ok github.com/novox/mesh-controller/internal/testbus 1.187s
ok github.com/novox/mesh-controller/internal/token 1.017s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.18s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.21s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.19s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.18s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.17s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.15s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.94s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.21s)
./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.18s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.18s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.24s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.22s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.17s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.17s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.17s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.17s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.19s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.25s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.24s)
./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.26s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.21s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.26s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.21s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.17s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.18s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.16s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.13s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.16s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.07s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.42s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.25s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.17s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.17s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.17s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.47s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.16s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.15s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.21s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.26s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.21s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.21s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.16s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.17s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.19s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.19s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.20s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.15s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.13s)
./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.07s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.06s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.06s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.07s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.06s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.07s)
**Merge check** at `cebc5936`
Judged: head `cebc593627d3` merged into trunk `2959c8143536`; read beside it: mesh-catalog `ebf7f3773dc7`, mesh-controller-main `2959c8143536`, 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/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent → ace, g14, novox, shanks; no bus step
- tier 0: build-agent
- ace: receives build-agent
- g14: receives build-agent
- novox: receives 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
Run by the build seat on ace as `build-1791940945578777763` (`builds --log build-1791940945578777763`).
```
--- the gate: build-agent
judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-14T01:08:55Z 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-14T01:08:55Z
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 0 module(s) in 0 tier(s)
notes:
- testdata/store-tests 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.084s
ok github.com/novox/mesh-controller/cmd/mesh-controller 151.935s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.015s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.016s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.015s
ok github.com/novox/mesh-controller/examples/route-proxy 1.107s
ok github.com/novox/mesh-controller/internal/artifacts 1.035s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 4.003s
ok github.com/novox/mesh-controller/internal/builder 33.307s
ok github.com/novox/mesh-controller/internal/catalogue 7.638s
ok github.com/novox/mesh-controller/internal/conditions 2.540s
ok github.com/novox/mesh-controller/internal/envfile 1.059s
ok github.com/novox/mesh-controller/internal/facts 1.090s
ok github.com/novox/mesh-controller/internal/identity 4.295s
ok github.com/novox/mesh-controller/internal/inventory 29.733s
ok github.com/novox/mesh-controller/internal/lease 17.711s
ok github.com/novox/mesh-controller/internal/licences 3.551s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.090s
ok github.com/novox/mesh-controller/internal/link 57.537s
ok github.com/novox/mesh-controller/internal/lint 2.293s
ok github.com/novox/mesh-controller/internal/outward 1.091s
ok github.com/novox/mesh-controller/internal/overlay 1.080s
ok github.com/novox/mesh-controller/internal/secrets 1.431s
ok github.com/novox/mesh-controller/internal/store 3.227s
ok github.com/novox/mesh-controller/internal/testbus 1.187s
ok github.com/novox/mesh-controller/internal/token 1.017s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.18s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.21s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.19s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.18s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.17s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.15s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.94s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.21s)
./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.18s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.18s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.24s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.22s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.17s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.17s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.17s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.17s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.19s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.25s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.24s)
./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.26s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.21s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.26s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.21s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.17s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.18s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.16s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.13s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.16s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.07s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (0.42s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.25s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.18s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.17s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.17s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.17s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.47s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.16s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.15s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.21s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.26s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.21s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.17s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.21s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.16s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.17s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.19s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.19s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.20s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.15s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.13s)
./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.07s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.06s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.06s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.07s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.07s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.06s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.07s)
```
Verdict: sound at cebc593627, but do not merge until mesh/delivery-group is green; it is still red from 01:31.
Independent review for issue 145 (a machine reads healthy while its modules cannot reach each other).
Checks at this head: mesh/merge-gate success ("PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent)"), mesh/repo-check success ("PASS — its merge-check.sh passed"), mesh/delivery success ("ready: waits for its merge"), mesh/delivery-group FAILURE, set 01:31:20 ("rejected: composed together: the check could not run: the facts snapshot cannot be read ... cannot reach the artifact store at novox.internal:5100 ... connect: connection refused"). The artifact store answers now: GET http://novox.internal:5100/v2/ returned 200 at 05:04 from novox and from shanks. Nobody has asked the composed check again since, so the red verdict is stale and needs a fresh one.
The repo-check report now names both tests among the store tests: "./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.15s)" and "--- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.13s)". Before this change they were skipped without a store and never seen.
provider_hold.go does what issue 145 asks for the provisions it covers. A consumer's finding from a check that names needs is held under the provider composed for it (its recorded binding, else the provider of its credential). Only findings are held: down and restarting stay the consumer's own, and so does anything found while the provider is healthy. The provider's condition becomes urgent and lists who waits on it, and the consumer's gate waits rather than fails. The test asserts each of these: one condition for one provider and three consumers, urgent severity, the waiters listed, each gate waiting even past its bound, and after the provider recovers, the failing consumer raised on its own. Two notes, neither blocking: a consumer with two failing findings that need different providers is listed under the last one only; and the issue's other half (dialling a grant, ADR 0146) is still unbuilt, as the issue's diagnosis says.
I did not run the store tests on g14; they need the store. The repo-check run on ace ran them.
Merge order: this one first, then mesh-catalog #289 (after: mesh-controller), once the composed check has been asked again and is green.
Reviewed by an independent reviewer on g14.
Verdict: sound at cebc593627d3, but do not merge until mesh/delivery-group is green; it is still red from 01:31.
Independent review for issue 145 (a machine reads healthy while its modules cannot reach each other).
Checks at this head: mesh/merge-gate success ("PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent)"), mesh/repo-check success ("PASS — its merge-check.sh passed"), mesh/delivery success ("ready: waits for its merge"), mesh/delivery-group FAILURE, set 01:31:20 ("rejected: composed together: the check could not run: the facts snapshot cannot be read ... cannot reach the artifact store at novox.internal:5100 ... connect: connection refused"). The artifact store answers now: GET http://novox.internal:5100/v2/ returned 200 at 05:04 from novox and from shanks. Nobody has asked the composed check again since, so the red verdict is stale and needs a fresh one.
1. The repo-check report now names both tests among the store tests: "./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.15s)" and "--- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.13s)". Before this change they were skipped without a store and never seen.
2. provider_hold.go does what issue 145 asks for the provisions it covers. A consumer's finding from a check that names `needs` is held under the provider composed for it (its recorded binding, else the provider of its credential). Only findings are held: down and restarting stay the consumer's own, and so does anything found while the provider is healthy. The provider's condition becomes urgent and lists who waits on it, and the consumer's gate waits rather than fails. The test asserts each of these: one condition for one provider and three consumers, urgent severity, the waiters listed, each gate waiting even past its bound, and after the provider recovers, the failing consumer raised on its own. Two notes, neither blocking: a consumer with two failing findings that need different providers is listed under the last one only; and the issue's other half (dialling a grant, ADR 0146) is still unbuilt, as the issue's diagnosis says.
I did not run the store tests on g14; they need the store. The repo-check run on ace ran them.
Merge order: this one first, then mesh-catalog #289 (after: mesh-controller), once the composed check has been asked again and is green.
Reviewed by an independent reviewer on g14.
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.
Part of issue 145 (a machine reads healthy while its modules cannot reach each other). Goes with mesh-catalog's pull request on the same branch name, which declares the checks this reads.
What
testdata/store-testslists the two tests of the provider hold:TestOneProviderDownAndThreeConsumersFailingAreOneCondition(ADR 0240 rule 5, "how it is checked")TestAConsumerFailingBesideAHealthyProviderIsItsOwnWhy
The issue's diagnosis (note of 2026-10-14) said nothing reads
needs. That is wrong: Phase C of to-be 48 was merged on 2026-10-07 as #111 (cmd/mesh-controller/provider_hold.go).needsis carried back in the node-engine's statement (mesh-hostliveness.NeedsOf), a consumer's check finding is held under its provider'smodule.<provider>.<machine>.unhealthycondition (urgent, listing who waits on it), and the consumer's gate readshealthWaiting, never put back at its bound. What was missing is that the rule 5 test needs the store and skips without one, and it was not intestdata/store-tests, so the merge check passed it without running it (issue 459's gap).So there is no code change here, and no test that fails on main: the behaviour is on main.
How it was tested
heldFindingreturning false): the rule 5 test fails withraised [module.shop.laptop.unhealthy module.wiki.laptop.unhealthy module.crm.anchor.unhealthy module.db.anchor.unhealthy]; want the provider's alone.MESH_CHECK_STORE_ONLY=1 MESH_TEST_POSTGRES=… sh merge-check.sh: exit 0, both listed tests named as passed.The other hold tests (waiting provider, ADR 0292; failed wait, issue 450) run without the store and are not listed.
Part of issue 145.
Delivery
novox/mesh-controller@cebc593627d3— delivered since 2026-10-14T05:19:54ZDelivery plan — builds build-agent → ace, g14, novox, shanks; no bus step
Group
fix/145-a-consumer-is-held-under-its-provider, in order: novox/mesh-controller@cebc593627 → novox/mesh-catalog@2bb5d344f6Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
cebc5936Judged: head
cebc593627d3merged into trunk2959c8143536; read beside it: mesh-catalogebf7f3773dc7, mesh-controller-main2959c8143536, 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/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent → ace, g14, novox, shanks; no bus step
Run by the build seat on ace as
build-1791940945578777763(builds --log build-1791940945578777763).Verdict: sound at
cebc593627, but do not merge until mesh/delivery-group is green; it is still red from 01:31.Independent review for issue 145 (a machine reads healthy while its modules cannot reach each other).
Checks at this head: mesh/merge-gate success ("PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent)"), mesh/repo-check success ("PASS — its merge-check.sh passed"), mesh/delivery success ("ready: waits for its merge"), mesh/delivery-group FAILURE, set 01:31:20 ("rejected: composed together: the check could not run: the facts snapshot cannot be read ... cannot reach the artifact store at novox.internal:5100 ... connect: connection refused"). The artifact store answers now: GET http://novox.internal:5100/v2/ returned 200 at 05:04 from novox and from shanks. Nobody has asked the composed check again since, so the red verdict is stale and needs a fresh one.
needsis held under the provider composed for it (its recorded binding, else the provider of its credential). Only findings are held: down and restarting stay the consumer's own, and so does anything found while the provider is healthy. The provider's condition becomes urgent and lists who waits on it, and the consumer's gate waits rather than fails. The test asserts each of these: one condition for one provider and three consumers, urgent severity, the waiters listed, each gate waiting even past its bound, and after the provider recovers, the failing consumer raised on its own. Two notes, neither blocking: a consumer with two failing findings that need different providers is listed under the last one only; and the issue's other half (dialling a grant, ADR 0146) is still unbuilt, as the issue's diagnosis says.I did not run the store tests on g14; they need the store. The repo-check run on ace ran them.
Merge order: this one first, then mesh-catalog #289 (after: mesh-controller), once the composed check has been asked again and is green.
Reviewed by an independent reviewer on g14.