What: cmd/mesh-controller/replay348_test.go (TestReplay348AFaultFromBeforeTheSendFailsNoGate), listed in testdata/store-tests; and the resolver manifest test now refuses bind-dynamic and requires bind-interfaces.
Why: issue 348's core fix (this repo #179, 9ca7952d) and the catalogue's (#161, 105cc7c0) are merged and live, but a replay in mesh-lab's register was still owed (ADR 0237), and the diagnosis left a follow-up here: once the catalogue's main binds once, refuse bind-dynamic. Its main has bound once since 105cc7c0.
The replay is written only with what the controller had before #179 (aMesh, stateHealth, the keeper's open conditions, aboutTheMachine), and asserts the operator's acceptance: a build sent after the resolver fault began is not held for it, and a restarted engine's undecided statement does not clear the condition.
How it was tested:
mesh-lab go run ./cmd/prove R348: PROVED. Before its fix it fails ("the restarted node-engine's first, undecided statement cleared the network condition while the resolver still refused", and the gate held mesh-host and mesh-controller with "raised since it was sent"); on 9ca7952d it passes; it passes on main.
The manifest test fails against a catalogue with bind-dynamic put back (MESH_CHECK_BESIDE), passes on catalogue main and on the captured copy.
merge-check.sh with MESH_TEST_POSTGRES: exit 0; the new replay ran against the store and passed.
Registered in mesh-lab (R348, separate PR).
Fixes issue 348 (its replay).
What: `cmd/mesh-controller/replay348_test.go` (TestReplay348AFaultFromBeforeTheSendFailsNoGate), listed in testdata/store-tests; and the resolver manifest test now refuses `bind-dynamic` and requires `bind-interfaces`.
Why: issue 348's core fix (this repo #179, 9ca7952d) and the catalogue's (#161, 105cc7c0) are merged and live, but a replay in mesh-lab's register was still owed (ADR 0237), and the diagnosis left a follow-up here: once the catalogue's main binds once, refuse bind-dynamic. Its main has bound once since 105cc7c0.
The replay is written only with what the controller had before #179 (aMesh, stateHealth, the keeper's open conditions, aboutTheMachine), and asserts the operator's acceptance: a build sent after the resolver fault began is not held for it, and a restarted engine's undecided statement does not clear the condition.
How it was tested:
- mesh-lab `go run ./cmd/prove R348`: PROVED. Before its fix it fails ("the restarted node-engine's first, undecided statement cleared the network condition while the resolver still refused", and the gate held mesh-host and mesh-controller with "raised since it was sent"); on 9ca7952d it passes; it passes on main.
- The manifest test fails against a catalogue with bind-dynamic put back (MESH_CHECK_BESIDE), passes on catalogue main and on the captured copy.
- `merge-check.sh` with MESH_TEST_POSTGRES: exit 0; the new replay ran against the store and passed.
Registered in mesh-lab (R348, separate PR).
Fixes issue 348 (its replay).
mesh/merge-gate head 6eea92c323f4 merged into trunk e0d69ab7a05b — pass: builds build-agent → ace, g14, novox, shanks; no bus step; every machine composes …
mesh/delivery covered: a later merge that contains it was delivered: novox/mesh-controller@ef3e5ae9b0dc (merged as cd6757f1 into main, walk plan-17918675…
The replay holds the operator's acceptance: a build sent after the resolver
stopped answering is not put back for that fault, and a restarted engine's
undecided statement does not forget it. Written only with what the controller
had before mesh-controller #179, so mesh-lab's prover lays it over the commit
before: it fails there and passes on the fix and on main.
The resolver's manifest test took either binding until the catalogue's main
bound once; mesh-catalog #161 (105cc7c0) did, so bind-dynamic is refused.
Deliverynovox/mesh-controller@6eea92c323f4 — covered since 2026-10-13T05:13:17Z
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
composed together: pass — the change touches no module of the mesh's graph
Transitions
2026-10-13 04:10 (new) → proposed (announced): novox/mesh-controller#291's head announced
2026-10-13 04:14 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit
2026-10-13 04:14 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-13 04:22 ready → proposed (trunk moved): out of date: judged against trunk b12c4b82e8, the trunk is now e0d69ab7a05b; judged again on a recheck or when it is merged
2026-10-13 04:38 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit
2026-10-13 04:38 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-13 04:41 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
2026-10-13 05:13 published → covered (covered): covered: a later merge that contains it was delivered: novox/mesh-controller@ef3e5ae9b0 (merged as cd6757f1 into main, walk plan-1791867557600646669): build-agent
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-controller@6eea92c323f4` — **covered** since 2026-10-13T05:13:17Z
**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/348-replay`, in order: novox/mesh-controller@6eea92c323f4 → novox/mesh-lab@becff66e0a8a
- composed together: pass — the change touches no module of the mesh's graph
**Transitions**
- 2026-10-13 04:10 (new) → proposed (announced): novox/mesh-controller#291's head announced
- 2026-10-13 04:14 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit
- 2026-10-13 04:14 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-13 04:22 ready → proposed (trunk moved): out of date: judged against trunk b12c4b82e820, the trunk is now e0d69ab7a05b; judged again on a recheck or when it is merged
- 2026-10-13 04:38 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit
- 2026-10-13 04:38 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-13 04:41 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
- 2026-10-13 05:13 published → covered (covered): covered: a later merge that contains it was delivered: novox/mesh-controller@ef3e5ae9b0dc (merged as cd6757f1 into main, walk plan-1791867557600646669): build-agent
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
The replay (TestReplay348AFaultFromBeforeTheSendFailsNoGate) is written only with helpers present before 9ca7952d — aMesh, conditionsFrom, stateHealth, link.NetworkPart/NetworkHealth, conditions.Condition, k.Open and aboutTheMachine with its gateFacts{judged, open} all exist already at c58516f (9ca7952d's first parent). I checked this with git grep for each symbol at that commit.
I laid the new test file over three commits with MESH_TEST_POSTGRES pointing at a throwaway postgres:17-alpine container (via the repo's own make postgres target): on c58516f (9ca7952d^1) it fails with "the restarted node-engine's first, undecided statement cleared the network condition while the resolver still refused" and then "mesh-host, sent after the resolver stopped answering, was held for that fault" — on 9ca7952d it passes, and on the PR's own head (which carries main forward) it passes too.
It does replay the real fault: the scenario raises the network condition at the second failing look (10:58:45 equivalent), sends builds, then has the restarted engine's first undecided look clear the condition even though the resolver still refuses, then reopens it after the send — exactly the sequence issue 348 describes, and I confirmed in gate.go's history that the fix changed the gate from comparing c.Raised.Before(since) to c.OpenAt(since) (via an intermediate c.Began()), i.e. tracking a condition's first occurrence and gaps rather than its latest raise, which is precisely what this replay exercises.
The resolver_manifests_test.go change is right against mesh-catalog main: I cloned mesh-catalog, confirmed dnsmasq's module.json on main contains "bind-interfaces" and "listen-address=${machine:address}"/"127.0.0.1" and no "bind-dynamic" anywhere (comment there cites issue 348 and the same teardown mechanism), and running TestTheResolverForwardsToFixedUpstreamsAndNeverReadsResolvConf with MESH_CHECK_BESIDE pointed at that real clone passes.
go build ./... and go vet on the affected packages are clean on this head. The testdata/store-tests entry is listed correctly.
Verdict: approve at 6eea92c323f4862d4162f9d977c8783d8a62efc3
The replay (TestReplay348AFaultFromBeforeTheSendFailsNoGate) is written only with helpers present before 9ca7952d — aMesh, conditionsFrom, stateHealth, link.NetworkPart/NetworkHealth, conditions.Condition, k.Open and aboutTheMachine with its gateFacts{judged, open} all exist already at c58516f (9ca7952d's first parent). I checked this with git grep for each symbol at that commit.
I laid the new test file over three commits with MESH_TEST_POSTGRES pointing at a throwaway postgres:17-alpine container (via the repo's own make postgres target): on c58516f (9ca7952d^1) it fails with "the restarted node-engine's first, undecided statement cleared the network condition while the resolver still refused" and then "mesh-host, sent after the resolver stopped answering, was held for that fault" — on 9ca7952d it passes, and on the PR's own head (which carries main forward) it passes too.
It does replay the real fault: the scenario raises the network condition at the second failing look (10:58:45 equivalent), sends builds, then has the restarted engine's first undecided look clear the condition even though the resolver still refuses, then reopens it after the send — exactly the sequence issue 348 describes, and I confirmed in gate.go's history that the fix changed the gate from comparing c.Raised.Before(since) to c.OpenAt(since) (via an intermediate c.Began()), i.e. tracking a condition's first occurrence and gaps rather than its latest raise, which is precisely what this replay exercises.
The resolver_manifests_test.go change is right against mesh-catalog main: I cloned mesh-catalog, confirmed dnsmasq's module.json on main contains "bind-interfaces" and "listen-address=${machine:address}"/"127.0.0.1" and no "bind-dynamic" anywhere (comment there cites issue 348 and the same teardown mechanism), and running TestTheResolverForwardsToFixedUpstreamsAndNeverReadsResolvConf with MESH_CHECK_BESIDE pointed at that real clone passes.
go build ./... and go vet on the affected packages are clean on this head. The testdata/store-tests entry is listed correctly.
Merge check at 6eea92c3
Judged: head 6eea92c323f4 merged into trunk e0d69ab7a05b; read beside it: mesh-catalog 53e51864969f, mesh-controller-main e0d69ab7a05b, mesh-host 7a41e120635b, mesh-tools 954e1a53eef9
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (run 2) (modules: build-agent)
mesh/repo-check: PASS — its merge-check.sh passed (run 2)
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 g14 as build-1791865589358629203 (builds --log build-1791865589358629203).
restarted: handed out 2 times; an earlier hand-out did not finish here, so this run started from the beginning
--- the gate: build-agent
judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-13T04:25:17Z 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-13T04:25:17Z
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 1 module(s) in 1 tier(s): build-agent
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.041s
ok github.com/novox/mesh-controller/cmd/mesh-controller 172.268s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.012s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.018s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.011s
ok github.com/novox/mesh-controller/examples/route-proxy 1.168s
ok github.com/novox/mesh-controller/internal/artifacts 1.056s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 3.986s
ok github.com/novox/mesh-controller/internal/builder 29.612s
ok github.com/novox/mesh-controller/internal/catalogue 7.278s
ok github.com/novox/mesh-controller/internal/conditions 2.490s
ok github.com/novox/mesh-controller/internal/envfile 1.028s
ok github.com/novox/mesh-controller/internal/facts 1.034s
ok github.com/novox/mesh-controller/internal/identity 4.334s
ok github.com/novox/mesh-controller/internal/inventory 30.957s
ok github.com/novox/mesh-controller/internal/lease 17.686s
ok github.com/novox/mesh-controller/internal/licences 3.513s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.010s
ok github.com/novox/mesh-controller/internal/link 59.164s
ok github.com/novox/mesh-controller/internal/lint 2.261s
ok github.com/novox/mesh-controller/internal/outward 1.042s
ok github.com/novox/mesh-controller/internal/overlay 1.026s
ok github.com/novox/mesh-controller/internal/secrets 1.450s
ok github.com/novox/mesh-controller/internal/store 3.264s
ok github.com/novox/mesh-controller/internal/testbus 1.181s
ok github.com/novox/mesh-controller/internal/token 1.015s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.18s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.20s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.20s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.17s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.17s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.14s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.96s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.19s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.12s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.24s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.24s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.19s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.26s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.24s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.18s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.18s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.17s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.17s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.20s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.23s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.24s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.15s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.13s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.14s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.23s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.21s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.26s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.57s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.17s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.19s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.16s)
./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.07s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.06s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.06s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.06s)
**Merge check** at `6eea92c3`
Judged: head `6eea92c323f4` merged into trunk `e0d69ab7a05b`; read beside it: mesh-catalog `53e51864969f`, mesh-controller-main `e0d69ab7a05b`, mesh-host `7a41e120635b`, mesh-tools `954e1a53eef9`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (run 2) (modules: build-agent)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed (run 2)
**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 g14 as `build-1791865589358629203` (`builds --log build-1791865589358629203`).
```
restarted: handed out 2 times; an earlier hand-out did not finish here, so this run started from the beginning
--- the gate: build-agent
judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-13T04:25:17Z 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-13T04:25:17Z
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 1 module(s) in 1 tier(s): build-agent
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.041s
ok github.com/novox/mesh-controller/cmd/mesh-controller 172.268s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.012s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.018s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.011s
ok github.com/novox/mesh-controller/examples/route-proxy 1.168s
ok github.com/novox/mesh-controller/internal/artifacts 1.056s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 3.986s
ok github.com/novox/mesh-controller/internal/builder 29.612s
ok github.com/novox/mesh-controller/internal/catalogue 7.278s
ok github.com/novox/mesh-controller/internal/conditions 2.490s
ok github.com/novox/mesh-controller/internal/envfile 1.028s
ok github.com/novox/mesh-controller/internal/facts 1.034s
ok github.com/novox/mesh-controller/internal/identity 4.334s
ok github.com/novox/mesh-controller/internal/inventory 30.957s
ok github.com/novox/mesh-controller/internal/lease 17.686s
ok github.com/novox/mesh-controller/internal/licences 3.513s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.010s
ok github.com/novox/mesh-controller/internal/link 59.164s
ok github.com/novox/mesh-controller/internal/lint 2.261s
ok github.com/novox/mesh-controller/internal/outward 1.042s
ok github.com/novox/mesh-controller/internal/overlay 1.026s
ok github.com/novox/mesh-controller/internal/secrets 1.450s
ok github.com/novox/mesh-controller/internal/store 3.264s
ok github.com/novox/mesh-controller/internal/testbus 1.181s
ok github.com/novox/mesh-controller/internal/token 1.015s
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.18s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.20s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.20s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.17s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.17s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.14s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (1.96s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.19s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.12s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.24s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.24s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.19s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.26s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.19s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.24s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.18s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.18s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.17s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.17s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.20s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.23s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.24s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.15s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.13s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.14s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.23s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.21s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.26s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.57s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.17s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.19s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.16s)
./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.07s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.06s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.06s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.06s)
```
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:
cmd/mesh-controller/replay348_test.go(TestReplay348AFaultFromBeforeTheSendFailsNoGate), listed in testdata/store-tests; and the resolver manifest test now refusesbind-dynamicand requiresbind-interfaces.Why: issue 348's core fix (this repo #179,
9ca7952d) and the catalogue's (#161, 105cc7c0) are merged and live, but a replay in mesh-lab's register was still owed (ADR 0237), and the diagnosis left a follow-up here: once the catalogue's main binds once, refuse bind-dynamic. Its main has bound once since 105cc7c0.The replay is written only with what the controller had before #179 (aMesh, stateHealth, the keeper's open conditions, aboutTheMachine), and asserts the operator's acceptance: a build sent after the resolver fault began is not held for it, and a restarted engine's undecided statement does not clear the condition.
How it was tested:
go run ./cmd/prove R348: PROVED. Before its fix it fails ("the restarted node-engine's first, undecided statement cleared the network condition while the resolver still refused", and the gate held mesh-host and mesh-controller with "raised since it was sent"); on9ca7952dit passes; it passes on main.merge-check.shwith MESH_TEST_POSTGRES: exit 0; the new replay ran against the store and passed.Registered in mesh-lab (R348, separate PR).
Fixes issue 348 (its replay).
Delivery
novox/mesh-controller@6eea92c323f4— covered since 2026-10-13T05:13:17ZDelivery plan — builds build-agent → ace, g14, novox, shanks; no bus step
Group
fix/348-replay, in order: novox/mesh-controller@6eea92c323 → novox/mesh-lab@becff66e0aTransitions
b12c4b82e8, the trunk is now e0d69ab7a05b; judged again on a recheck or when it is mergedcd6757f1into main, walk plan-1791867557600646669): build-agentThe commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Verdict: approve at
6eea92c323The replay (TestReplay348AFaultFromBeforeTheSendFailsNoGate) is written only with helpers present before
9ca7952d— aMesh, conditionsFrom, stateHealth, link.NetworkPart/NetworkHealth, conditions.Condition, k.Open and aboutTheMachine with its gateFacts{judged, open} all exist already atc58516f(9ca7952d's first parent). I checked this with git grep for each symbol at that commit.I laid the new test file over three commits with MESH_TEST_POSTGRES pointing at a throwaway postgres:17-alpine container (via the repo's own make postgres target): on
c58516f(9ca7952d^1) it fails with "the restarted node-engine's first, undecided statement cleared the network condition while the resolver still refused" and then "mesh-host, sent after the resolver stopped answering, was held for that fault" — on9ca7952dit passes, and on the PR's own head (which carries main forward) it passes too.It does replay the real fault: the scenario raises the network condition at the second failing look (10:58:45 equivalent), sends builds, then has the restarted engine's first undecided look clear the condition even though the resolver still refuses, then reopens it after the send — exactly the sequence issue 348 describes, and I confirmed in gate.go's history that the fix changed the gate from comparing c.Raised.Before(since) to c.OpenAt(since) (via an intermediate c.Began()), i.e. tracking a condition's first occurrence and gaps rather than its latest raise, which is precisely what this replay exercises.
The resolver_manifests_test.go change is right against mesh-catalog main: I cloned mesh-catalog, confirmed dnsmasq's module.json on main contains "bind-interfaces" and "listen-address=${machine:address}"/"127.0.0.1" and no "bind-dynamic" anywhere (comment there cites issue 348 and the same teardown mechanism), and running TestTheResolverForwardsToFixedUpstreamsAndNeverReadsResolvConf with MESH_CHECK_BESIDE pointed at that real clone passes.
go build ./... and go vet on the affected packages are clean on this head. The testdata/store-tests entry is listed correctly.
Merge check at
6eea92c3Judged: head
6eea92c323f4merged into trunke0d69ab7a05b; read beside it: mesh-catalog53e51864969f, mesh-controller-maine0d69ab7a05b, mesh-host7a41e120635b, mesh-tools954e1a53eef9mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (run 2) (modules: build-agent)mesh/repo-check: PASS — its merge-check.sh passed (run 2)Delivery plan — builds build-agent → ace, g14, novox, shanks; no bus step
Run by the build seat on g14 as
build-1791865589358629203(builds --log build-1791865589358629203).