Waits for ADR 0363 (proposed; it needs the knowledge base's approval and then the operator's Approve). Do not merge before the record is accepted.
Implements the controller's part of ADR 0363 for issue 718: mesh-mail's events on a stream of their own (MAIL, ADR 0359 §2), heard only by the modules its grants value names per account (§4).
What changes
Manifest key streams (catalogue/streams.go): {name, events, max-age-days, max-mib, grant: {config, events}}. Events are local patterns with * and trailing **, so an account-keyed family is declared once. Refused at registration: bad name, a mesh stream name or a reserved prefix (SEAT_, LOG_, KV_, OBJ_, DEAD_), bounds (1-30 days, 1-8192 MiB), an emits entry a stream covers, overlapping streams of one module, a grant whose value is not a trusted (terminal) key, a grant pattern without exactly one {key}; across the catalogue, two modules declaring one stream name.
The stream (broker/modstreams.go): <NAME> on mesh.stream.<module>.event.<pattern> (no overlap with EVENTS), limits retention, its age and size. Asserted with every raise and every send in assertBusObjects, before the consumers.
Grants: the provider's account and the runtime carrying it may publish the stream's patterns. A consumer's consumes naming the emitter literally is narrowed to the stream's patterns and, for a restricted stream, to the keys the provider's value lists for it (mesh layer under the machine's layer, per machine running the provider, <machine>.<module> for one machine). Only then: a durable consumer <node>_<module> on the stream, the account's INFO / MSG.NEXT / ACK on it, subscribe on the filters, and the membership's hears. A wildcard emitter (**) never reaches a module stream. What a stream carries leaves EVENTS' consumes.
Withdrawal: every assertion removes consumers on a module stream the composition no longer asks for (PruneHeard), so a consumer that loses its grant loses what it reads through on that send. Memberships of assignments that hear a module stream on machines the send does not reach are re-issued as last issued with only hears changed.
Dead letters: a message given up on a module stream is delivered again on EVENTS under the consumer's again-subject only while its consumer on the stream still exists and filters the subject.
Membership gains streams (stream, events, subject) and hears (stream, consumer).
Nothing changes on the bus while no manifest declares streams (ADR 0262).
Order of delivery
This PR (controller).
The runtime in mesh-tools (issue 725): publish per membership streams, bind each hears consumer.
mesh-mail's manifest (mesh-catalog PR 300, issue 710): declare the stream and drop its three emits.
The mesh-config half (compose on config-changed once config moves to mesh-config, ADR 0348) is issue 724.
Checks
go vet ./... clean; go test ./internal/... ./cmd/... pass locally.
mesh-controller.try on the head: see the comment once it answers.
Reviewer checklist: the grant can never be composed from consumes alone for a restricted stream; a wildcard emitter never reaches a module stream; EVENTS consumer filters never include a mesh.stream. subject; a consumer losing its grant is removed in the same assertion; nothing changes for manifests without streams.
**Waits for ADR 0363** (proposed; it needs the knowledge base's approval and then the operator's Approve). Do not merge before the record is accepted.
Implements the controller's part of ADR 0363 for issue 718: mesh-mail's events on a stream of their own (`MAIL`, ADR 0359 §2), heard only by the modules its `grants` value names per account (§4).
## What changes
- **Manifest key `streams`** (catalogue/streams.go): `{name, events, max-age-days, max-mib, grant: {config, events}}`. Events are local patterns with `*` and trailing `**`, so an account-keyed family is declared once. Refused at registration: bad name, a mesh stream name or a reserved prefix (`SEAT_`, `LOG_`, `KV_`, `OBJ_`, `DEAD_`), bounds (1-30 days, 1-8192 MiB), an `emits` entry a stream covers, overlapping streams of one module, a grant whose value is not a trusted (terminal) key, a grant pattern without exactly one `{key}`; across the catalogue, two modules declaring one stream name.
- **The stream** (broker/modstreams.go): `<NAME>` on `mesh.stream.<module>.event.<pattern>` (no overlap with EVENTS), limits retention, its age and size. Asserted with every raise and every send in `assertBusObjects`, before the consumers.
- **Grants**: the provider's account and the runtime carrying it may publish the stream's patterns. A consumer's `consumes` naming the emitter literally is narrowed to the stream's patterns and, for a restricted stream, to the keys the provider's value lists for it (mesh layer under the machine's layer, per machine running the provider, `<machine>.<module>` for one machine). Only then: a durable consumer `<node>_<module>` on the stream, the account's INFO / MSG.NEXT / ACK on it, subscribe on the filters, and the membership's `hears`. A wildcard emitter (`**`) never reaches a module stream. What a stream carries leaves EVENTS' consumes.
- **Withdrawal**: every assertion removes consumers on a module stream the composition no longer asks for (`PruneHeard`), so a consumer that loses its grant loses what it reads through on that send. Memberships of assignments that hear a module stream on machines the send does not reach are re-issued as last issued with only `hears` changed.
- **Dead letters**: a message given up on a module stream is delivered again on EVENTS under the consumer's again-subject only while its consumer on the stream still exists and filters the subject.
- **Membership** gains `streams` (stream, events, subject) and `hears` (stream, consumer).
Nothing changes on the bus while no manifest declares `streams` (ADR 0262).
## Order of delivery
1. This PR (controller).
2. The runtime in mesh-tools (issue 725): publish per membership `streams`, bind each `hears` consumer.
3. mesh-mail's manifest (mesh-catalog PR 300, issue 710): declare the stream and drop its three emits.
The mesh-config half (compose on `config-changed` once config moves to mesh-config, ADR 0348) is issue 724.
## Checks
- `go vet ./...` clean; `go test ./internal/... ./cmd/...` pass locally.
- New tests: catalogue/streams_test.go, broker/modstreams_test.go, broker/modstreams_live_test.go (real bus: stream beside EVENTS, narrowing, removal), inventory/streams_test.go, link/deadletters_module_stream_test.go, cmd/mesh-controller/reissue_hearing_test.go.
- `mesh-controller.try` on the head: see the comment once it answers.
Reviewer checklist: the grant can never be composed from `consumes` alone for a restricted stream; a wildcard emitter never reaches a module stream; EVENTS consumer filters never include a `mesh.stream.` subject; a consumer losing its grant is removed in the same assertion; nothing changes for manifests without `streams`.
mesh-mail's events must live on a stream of their own and reach only the modules the operator granted
an account (ADR 0359 §2, §4). The controller now creates a module's declared stream, publishes its events
on mesh.stream.<module>.event.<event>, and composes a consumer's durable consumer, filters and bus grants
on a restricted stream only where its consumes asks and the provider's trusted value names it; a consumer
that loses its grant has its consumer removed on the next assertion. Nothing changes while no manifest
declares a stream.
route-proxy provides route: its consumers are sent again after it
route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
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 route-proxy, build-agent is judged on its first machine
Machines
mesh-controller on every machine running it: sent
route-proxy on every machine running it: sent
build-agent on every machine running it: sent
Transitions
2026-10-14 20:05 (new) → proposed (announced): novox/mesh-controller#338's head announced
2026-10-14 20:09 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit
2026-10-14 20:09 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-14 20:14 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 20:14 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path — not a failed walk that carried a later commit for it, after which it waits for a walk of its own commit
2026-10-14 20:20 delivering → delivered (done): its walk is done, carrying its own commit: every machine of its deploy plan passed, or was left as its policy says
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-controller@743e6478a76c` — **delivered** since 2026-10-14T20:20:11Z
**Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller, route-proxy
- tier 1: build-agent
- ace: receives route-proxy, build-agent
- g14: receives build-agent
- novox: receives mesh-controller, route-proxy, build-agent
- shanks: receives build-agent
- route-proxy provides route: its consumers are sent again after it
- route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
- 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 route-proxy, build-agent is judged on its first machine
**Machines**
- mesh-controller on every machine running it: sent
- route-proxy on every machine running it: sent
- build-agent on every machine running it: sent
**Transitions**
- 2026-10-14 20:05 (new) → proposed (announced): novox/mesh-controller#338's head announced
- 2026-10-14 20:09 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit
- 2026-10-14 20:09 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-14 20:14 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 20:14 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path — not a failed walk that carried a later commit for it, after which it waits for a walk of its own commit
- 2026-10-14 20:20 delivering → delivered (done): its walk is done, carrying its own commit: every machine of its deploy plan passed, or was left as its policy says
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
route-proxy provides route: its consumers are sent again after it
route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
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 route-proxy, build-agent is judged on its first machine
read by no module's build: cmd/mesh-controller/reissue_hearing_test.go, internal/broker/modstreams_live_test.go, internal/broker/modstreams_test.go, internal/catalogue/streams_test.go, internal/inventory/streams_test.go, internal/link/deadletters_module_stream_test.go
Run by the build seat on shanks as build-1792007842533777312 (builds --log build-1792007842533777312).
--- the gate: build-agent, mesh-controller, route-proxy
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-14T19:40:09Z 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-14T19:40:09Z
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 3 module(s) in 2 tier(s): build-agent, mesh-controller, route-proxy
notes:
- cmd/mesh-controller/reissue_hearing_test.go, internal/broker/modstreams_live_test.go, internal/broker/modstreams_test.go, internal/catalogue/streams_test.go, internal/inventory/streams_test.go and internal/link/deadletters_module_stream_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.117s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.020s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.025s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.018s
ok github.com/novox/mesh-controller/examples/route-proxy 1.258s
ok github.com/novox/mesh-controller/internal/artifacts 1.048s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 6.688s
ok github.com/novox/mesh-controller/internal/catalogue 22.010s
ok github.com/novox/mesh-controller/internal/conditions 2.854s
ok github.com/novox/mesh-controller/internal/envfile 1.054s
ok github.com/novox/mesh-controller/internal/facts 1.056s
ok github.com/novox/mesh-controller/internal/identity 9.752s
ok github.com/novox/mesh-controller/internal/lease 10.256s
ok github.com/novox/mesh-controller/internal/licences 6.713s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.043s
ok github.com/novox/mesh-controller/internal/lint 2.900s
ok github.com/novox/mesh-controller/internal/outward 1.078s
ok github.com/novox/mesh-controller/internal/overlay 1.062s
ok github.com/novox/mesh-controller/internal/secrets 1.584s
ok github.com/novox/mesh-controller/internal/store 3.717s
ok github.com/novox/mesh-controller/internal/testbus 1.264s
ok github.com/novox/mesh-controller/internal/token 1.047s
ok github.com/novox/mesh-controller/cmd/mesh-controller 45s (shard 1 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 50s (shard 2 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 52s (shard 3 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 45s (shard 4 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 43s (shard 5 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 40s (shard 6 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 49s (shard 7 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 48s (shard 8 of 8: 114 tests)
ok github.com/novox/mesh-controller/internal/inventory 25s (shard 1 of 4: 68 tests)
ok github.com/novox/mesh-controller/internal/inventory 23s (shard 2 of 4: 68 tests)
ok github.com/novox/mesh-controller/internal/inventory 23s (shard 3 of 4: 68 tests)
ok github.com/novox/mesh-controller/internal/inventory 25s (shard 4 of 4: 67 tests)
ok github.com/novox/mesh-controller/internal/builder 22s (shard 1 of 4: 51 tests)
ok github.com/novox/mesh-controller/internal/builder 22s (shard 2 of 4: 51 tests)
ok github.com/novox/mesh-controller/internal/builder 64s (shard 3 of 4: 51 tests)
ok github.com/novox/mesh-controller/internal/builder 27s (shard 4 of 4: 50 tests)
ok github.com/novox/mesh-controller/internal/link 16s (shard 1 of 4: 44 tests)
ok github.com/novox/mesh-controller/internal/link 22s (shard 2 of 4: 44 tests)
ok github.com/novox/mesh-controller/internal/link 18s (shard 3 of 4: 44 tests)
ok github.com/novox/mesh-controller/internal/link 19s (shard 4 of 4: 44 tests)
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.36s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.45s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.67s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.80s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.84s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.79s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (2.64s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (1.02s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.20s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.40s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.39s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.31s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.33s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.40s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.31s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.39s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.87s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.99s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.76s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.80s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.52s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (1.17s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (1.27s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.25s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.24s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.25s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.72s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.69s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.73s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.57s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.47s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.70s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.42s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.48s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.73s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.22s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (2.05s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.91s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.37s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.33s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.33s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.46s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.98s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.32s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.30s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.40s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.65s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.49s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.41s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.28s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.41s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.29s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.57s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.72s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.42s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.95s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.70s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.49s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.13s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.16s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.16s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.12s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.11s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.12s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.16s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.13s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.11s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.14s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.12s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.19s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.65s)
**Merge check** at `ede2772b`
Judged: head `ede2772b3c90` merged into trunk `c2ec0a601acb`; read beside it: mesh-catalog `fadf5025cc5a`, mesh-controller-main `c2ec0a601acb`, 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, route-proxy)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller, route-proxy
- tier 1: build-agent
- ace: receives route-proxy, build-agent
- g14: receives build-agent
- novox: receives mesh-controller, route-proxy, build-agent
- shanks: receives build-agent
- route-proxy provides route: its consumers are sent again after it
- route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
- 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 route-proxy, build-agent is judged on its first machine
- read by no module's build: cmd/mesh-controller/reissue_hearing_test.go, internal/broker/modstreams_live_test.go, internal/broker/modstreams_test.go, internal/catalogue/streams_test.go, internal/inventory/streams_test.go, internal/link/deadletters_module_stream_test.go
Run by the build seat on shanks as `build-1792007842533777312` (`builds --log build-1792007842533777312`).
```
--- the gate: build-agent, mesh-controller, route-proxy
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-14T19:40:09Z 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-14T19:40:09Z
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 3 module(s) in 2 tier(s): build-agent, mesh-controller, route-proxy
notes:
- cmd/mesh-controller/reissue_hearing_test.go, internal/broker/modstreams_live_test.go, internal/broker/modstreams_test.go, internal/catalogue/streams_test.go, internal/inventory/streams_test.go and internal/link/deadletters_module_stream_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.117s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.020s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.025s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.018s
ok github.com/novox/mesh-controller/examples/route-proxy 1.258s
ok github.com/novox/mesh-controller/internal/artifacts 1.048s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 6.688s
ok github.com/novox/mesh-controller/internal/catalogue 22.010s
ok github.com/novox/mesh-controller/internal/conditions 2.854s
ok github.com/novox/mesh-controller/internal/envfile 1.054s
ok github.com/novox/mesh-controller/internal/facts 1.056s
ok github.com/novox/mesh-controller/internal/identity 9.752s
ok github.com/novox/mesh-controller/internal/lease 10.256s
ok github.com/novox/mesh-controller/internal/licences 6.713s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.043s
ok github.com/novox/mesh-controller/internal/lint 2.900s
ok github.com/novox/mesh-controller/internal/outward 1.078s
ok github.com/novox/mesh-controller/internal/overlay 1.062s
ok github.com/novox/mesh-controller/internal/secrets 1.584s
ok github.com/novox/mesh-controller/internal/store 3.717s
ok github.com/novox/mesh-controller/internal/testbus 1.264s
ok github.com/novox/mesh-controller/internal/token 1.047s
ok github.com/novox/mesh-controller/cmd/mesh-controller 45s (shard 1 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 50s (shard 2 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 52s (shard 3 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 45s (shard 4 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 43s (shard 5 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 40s (shard 6 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 49s (shard 7 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 48s (shard 8 of 8: 114 tests)
ok github.com/novox/mesh-controller/internal/inventory 25s (shard 1 of 4: 68 tests)
ok github.com/novox/mesh-controller/internal/inventory 23s (shard 2 of 4: 68 tests)
ok github.com/novox/mesh-controller/internal/inventory 23s (shard 3 of 4: 68 tests)
ok github.com/novox/mesh-controller/internal/inventory 25s (shard 4 of 4: 67 tests)
ok github.com/novox/mesh-controller/internal/builder 22s (shard 1 of 4: 51 tests)
ok github.com/novox/mesh-controller/internal/builder 22s (shard 2 of 4: 51 tests)
ok github.com/novox/mesh-controller/internal/builder 64s (shard 3 of 4: 51 tests)
ok github.com/novox/mesh-controller/internal/builder 27s (shard 4 of 4: 50 tests)
ok github.com/novox/mesh-controller/internal/link 16s (shard 1 of 4: 44 tests)
ok github.com/novox/mesh-controller/internal/link 22s (shard 2 of 4: 44 tests)
ok github.com/novox/mesh-controller/internal/link 18s (shard 3 of 4: 44 tests)
ok github.com/novox/mesh-controller/internal/link 19s (shard 4 of 4: 44 tests)
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.36s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.45s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.67s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.80s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.84s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.79s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (2.64s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (1.02s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.20s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.40s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.39s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.31s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.33s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.40s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.31s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.39s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.87s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.99s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.76s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.80s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.52s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (1.17s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (1.27s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.25s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.24s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.25s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.72s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.69s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.73s)
./cmd/mesh-controller --- PASS: TestReplay340 (0.57s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.47s)
./cmd/mesh-controller --- PASS: TestReplay349 (0.70s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (0.42s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.48s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.73s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.22s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (2.05s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.91s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.37s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.33s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.33s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.46s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (0.98s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.32s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.30s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.40s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.65s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.49s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.41s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.28s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.41s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.29s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.57s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.72s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.42s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.95s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.70s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.49s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.13s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.16s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.16s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.12s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.11s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.12s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.16s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.13s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.11s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.14s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.12s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.19s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.65s)
```
route-proxy provides route: its consumers are sent again after it
route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
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 route-proxy, build-agent is judged on its first machine
read by no module's build: cmd/mesh-controller/reissue_hearing_test.go, internal/broker/modstreams_live_test.go, internal/broker/modstreams_test.go, internal/broker/stream_names_agreement_test.go, internal/catalogue/streams_test.go, internal/inventory/streams_test.go, internal/link/deadletters_module_stream_test.go
Run by the build seat on shanks as build-1792008356329597819 (builds --log build-1792008356329597819).
--- the gate: build-agent, mesh-controller, route-proxy
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-14T20:00:09Z 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-14T20:00:09Z
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 3 module(s) in 2 tier(s): build-agent, mesh-controller, route-proxy
notes:
- cmd/mesh-controller/reissue_hearing_test.go, internal/broker/modstreams_live_test.go, internal/broker/modstreams_test.go, internal/broker/stream_names_agreement_test.go, internal/catalogue/streams_test.go, internal/inventory/streams_test.go and internal/link/deadletters_module_stream_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.139s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.027s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.027s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.025s
ok github.com/novox/mesh-controller/examples/route-proxy 1.184s
ok github.com/novox/mesh-controller/internal/artifacts 1.076s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 6.372s
ok github.com/novox/mesh-controller/internal/catalogue 13.664s
ok github.com/novox/mesh-controller/internal/conditions 3.730s
ok github.com/novox/mesh-controller/internal/envfile 1.067s
ok github.com/novox/mesh-controller/internal/facts 1.079s
ok github.com/novox/mesh-controller/internal/identity 8.525s
ok github.com/novox/mesh-controller/internal/lease 10.343s
ok github.com/novox/mesh-controller/internal/licences 7.167s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.027s
ok github.com/novox/mesh-controller/internal/lint 3.985s
ok github.com/novox/mesh-controller/internal/outward 1.115s
ok github.com/novox/mesh-controller/internal/overlay 1.104s
ok github.com/novox/mesh-controller/internal/secrets 1.904s
ok github.com/novox/mesh-controller/internal/store 4.609s
ok github.com/novox/mesh-controller/internal/testbus 1.356s
ok github.com/novox/mesh-controller/internal/token 1.077s
ok github.com/novox/mesh-controller/cmd/mesh-controller 34s (shard 1 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 38s (shard 2 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 41s (shard 3 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 33s (shard 4 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 30s (shard 5 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 28s (shard 6 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 39s (shard 7 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 35s (shard 8 of 8: 114 tests)
ok github.com/novox/mesh-controller/internal/inventory 22s (shard 1 of 4: 68 tests)
ok github.com/novox/mesh-controller/internal/inventory 19s (shard 2 of 4: 68 tests)
ok github.com/novox/mesh-controller/internal/inventory 20s (shard 3 of 4: 68 tests)
ok github.com/novox/mesh-controller/internal/inventory 21s (shard 4 of 4: 67 tests)
ok github.com/novox/mesh-controller/internal/builder 19s (shard 1 of 4: 51 tests)
ok github.com/novox/mesh-controller/internal/builder 19s (shard 2 of 4: 51 tests)
ok github.com/novox/mesh-controller/internal/builder 59s (shard 3 of 4: 51 tests)
ok github.com/novox/mesh-controller/internal/builder 25s (shard 4 of 4: 50 tests)
ok github.com/novox/mesh-controller/internal/link 15s (shard 1 of 4: 44 tests)
ok github.com/novox/mesh-controller/internal/link 22s (shard 2 of 4: 44 tests)
ok github.com/novox/mesh-controller/internal/link 16s (shard 3 of 4: 44 tests)
ok github.com/novox/mesh-controller/internal/link 20s (shard 4 of 4: 44 tests)
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.32s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.37s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.36s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.38s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.37s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.28s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (2.25s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.45s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.43s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.45s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.34s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.32s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.61s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.38s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.40s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.36s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.33s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.41s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.46s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.44s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.96s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.65s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.28s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.26s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.25s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.91s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.52s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.49s)
./cmd/mesh-controller --- PASS: TestReplay340 (1.14s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.29s)
./cmd/mesh-controller --- PASS: TestReplay349 (1.08s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (2.06s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.29s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.25s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.19s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (1.12s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.80s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.90s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.30s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.32s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.46s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (1.88s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.28s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.40s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.44s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.52s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.41s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.35s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.48s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.47s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.34s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.36s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.43s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.56s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.37s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.51s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.41s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.09s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.12s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.14s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.12s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.09s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.08s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.11s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.09s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.08s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.10s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.10s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.08s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.43s)
**Merge check** at `743e6478`
Judged: head `743e6478a76c` merged into trunk `c2ec0a601acb`; read beside it: mesh-catalog `fadf5025cc5a`, mesh-controller-main `c2ec0a601acb`, 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, route-proxy)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller, route-proxy
- tier 1: build-agent
- ace: receives route-proxy, build-agent
- g14: receives build-agent
- novox: receives mesh-controller, route-proxy, build-agent
- shanks: receives build-agent
- route-proxy provides route: its consumers are sent again after it
- route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
- 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 route-proxy, build-agent is judged on its first machine
- read by no module's build: cmd/mesh-controller/reissue_hearing_test.go, internal/broker/modstreams_live_test.go, internal/broker/modstreams_test.go, internal/broker/stream_names_agreement_test.go, internal/catalogue/streams_test.go, internal/inventory/streams_test.go, internal/link/deadletters_module_stream_test.go
Run by the build seat on shanks as `build-1792008356329597819` (`builds --log build-1792008356329597819`).
```
--- the gate: build-agent, mesh-controller, route-proxy
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-14T20:00:09Z 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-14T20:00:09Z
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 3 module(s) in 2 tier(s): build-agent, mesh-controller, route-proxy
notes:
- cmd/mesh-controller/reissue_hearing_test.go, internal/broker/modstreams_live_test.go, internal/broker/modstreams_test.go, internal/broker/stream_names_agreement_test.go, internal/catalogue/streams_test.go, internal/inventory/streams_test.go and internal/link/deadletters_module_stream_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.139s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.027s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.027s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.025s
ok github.com/novox/mesh-controller/examples/route-proxy 1.184s
ok github.com/novox/mesh-controller/internal/artifacts 1.076s
? github.com/novox/mesh-controller/internal/beside [no test files]
ok github.com/novox/mesh-controller/internal/broker 6.372s
ok github.com/novox/mesh-controller/internal/catalogue 13.664s
ok github.com/novox/mesh-controller/internal/conditions 3.730s
ok github.com/novox/mesh-controller/internal/envfile 1.067s
ok github.com/novox/mesh-controller/internal/facts 1.079s
ok github.com/novox/mesh-controller/internal/identity 8.525s
ok github.com/novox/mesh-controller/internal/lease 10.343s
ok github.com/novox/mesh-controller/internal/licences 7.167s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.027s
ok github.com/novox/mesh-controller/internal/lint 3.985s
ok github.com/novox/mesh-controller/internal/outward 1.115s
ok github.com/novox/mesh-controller/internal/overlay 1.104s
ok github.com/novox/mesh-controller/internal/secrets 1.904s
ok github.com/novox/mesh-controller/internal/store 4.609s
ok github.com/novox/mesh-controller/internal/testbus 1.356s
ok github.com/novox/mesh-controller/internal/token 1.077s
ok github.com/novox/mesh-controller/cmd/mesh-controller 34s (shard 1 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 38s (shard 2 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 41s (shard 3 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 33s (shard 4 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 30s (shard 5 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 28s (shard 6 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 39s (shard 7 of 8: 115 tests)
ok github.com/novox/mesh-controller/cmd/mesh-controller 35s (shard 8 of 8: 114 tests)
ok github.com/novox/mesh-controller/internal/inventory 22s (shard 1 of 4: 68 tests)
ok github.com/novox/mesh-controller/internal/inventory 19s (shard 2 of 4: 68 tests)
ok github.com/novox/mesh-controller/internal/inventory 20s (shard 3 of 4: 68 tests)
ok github.com/novox/mesh-controller/internal/inventory 21s (shard 4 of 4: 67 tests)
ok github.com/novox/mesh-controller/internal/builder 19s (shard 1 of 4: 51 tests)
ok github.com/novox/mesh-controller/internal/builder 19s (shard 2 of 4: 51 tests)
ok github.com/novox/mesh-controller/internal/builder 59s (shard 3 of 4: 51 tests)
ok github.com/novox/mesh-controller/internal/builder 25s (shard 4 of 4: 50 tests)
ok github.com/novox/mesh-controller/internal/link 15s (shard 1 of 4: 44 tests)
ok github.com/novox/mesh-controller/internal/link 22s (shard 2 of 4: 44 tests)
ok github.com/novox/mesh-controller/internal/link 16s (shard 3 of 4: 44 tests)
ok github.com/novox/mesh-controller/internal/link 20s (shard 4 of 4: 44 tests)
store tests, each run against the store:
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeWalksTheOthersAgain (0.32s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeEndsTheMergesThatContainIt (0.37s)
./cmd/mesh-controller --- PASS: TestAStopWalksTheOthersAgainInTheOpenBatch (0.36s)
./cmd/mesh-controller --- PASS: TestAStopNamesWhatStaysOnTheMachinesAndWhatStillCarriesIt (0.38s)
./cmd/mesh-controller --- PASS: TestAStopWithoutAMergeLeavesItOutOfABatch (0.37s)
./cmd/mesh-controller --- PASS: TestSavingPlansAndMovingMergesIsOneAct (0.28s)
./cmd/mesh-controller --- PASS: TestAPlanFollowedFromTheStoreAnswersWhenItMoves (2.25s)
./cmd/mesh-controller --- PASS: TestNodeShowAndStatusReadTheLastSendFromTheStore (0.45s)
./cmd/mesh-controller --- PASS: TestTheConditionsVerbReadsTheLooksTheBucketNoLongerHolds (0.23s)
./cmd/mesh-controller --- PASS: TestAWalkLetGoAndStoppedByVerbsIsSaidStartedAndEnded (0.43s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedOrClosedByAPersonIsSaidEndedStopped (0.45s)
./cmd/mesh-controller --- PASS: TestAWalkRetriedByAPersonIsSaidStartedAgain (0.34s)
./cmd/mesh-controller --- PASS: TestABacklogReleasedByAPersonIsSaidStarted (0.32s)
./cmd/mesh-controller --- PASS: TestAWalkEndedByCancelOrClearIsSaidEnded (0.61s)
./cmd/mesh-controller --- PASS: TestAWalkRestartedByARebuildIsSaidStarted (0.38s)
./cmd/mesh-controller --- PASS: TestAWalkStoppedByHandAndRetriedEndsFailedWhenItFailsAgain (0.40s)
./cmd/mesh-controller --- PASS: TestReplay237 (0.36s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer (0.33s)
./cmd/mesh-controller --- PASS: TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt (0.41s)
./cmd/mesh-controller --- PASS: TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal (0.46s)
./cmd/mesh-controller --- PASS: TestADirectoryOwnersKeyIsRefusedThroughAVerb (0.44s)
./cmd/mesh-controller --- PASS: TestTheSendMakesNoValueForAnOutsideSecretNobodyGave (0.96s)
./cmd/mesh-controller --- PASS: TestAQuestionComposesWithoutAnOutsideSecretNobodyGave (0.65s)
./cmd/mesh-controller --- PASS: TestReplay201 (0.28s)
./cmd/mesh-controller --- PASS: TestARollbackWhoseSendWasRefusedIsCompletedByTheNextSend (0.26s)
./cmd/mesh-controller --- PASS: TestAGateJudgesTheOtherMovesBesideAKeptCore (0.25s)
./cmd/mesh-controller --- PASS: TestReplay401 (0.91s)
./cmd/mesh-controller --- PASS: TestReplay201ThePlansSend (0.52s)
./cmd/mesh-controller --- PASS: TestPlanAndNodeListAnOptionalRequirementLeftUnbound (0.49s)
./cmd/mesh-controller --- PASS: TestReplay340 (1.14s)
./cmd/mesh-controller --- PASS: TestOnlyATrustedFilesNamedKeyIsRefusedThroughAVerb (0.29s)
./cmd/mesh-controller --- PASS: TestReplay349 (1.08s)
./cmd/mesh-controller --- PASS: TestReplay348AFaultFromBeforeTheSendFailsNoGate (2.06s)
./cmd/mesh-controller --- PASS: TestReplay239AModuleNameIsNotTakenOverByAnotherRepository (0.29s)
./cmd/mesh-controller --- PASS: TestAWalkThatMovedNothingSaysWhichModulesMatchedWhatRuns (0.25s)
./cmd/mesh-controller --- PASS: TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles (0.19s)
./cmd/mesh-controller --- PASS: TestOneAcceptForAProviderIsPlacedForEveryConsumer (1.12s)
./cmd/mesh-controller --- PASS: TestReplay164 (0.80s)
./cmd/mesh-controller --- PASS: TestAnApprovedLayerOpensTheWalkThatSendsIt (0.90s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsOneMachineAtATimeEachJudged (0.30s)
./cmd/mesh-controller --- PASS: TestAFailedSettingsWalkStopsAndHoldsNothingBack (0.32s)
./cmd/mesh-controller --- PASS: TestASettingsWalkSendsTheLayerAloneEveryBuildKept (0.46s)
./cmd/mesh-controller --- PASS: TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway (1.88s)
./cmd/mesh-controller --- PASS: TestACrossingSendSupersedesASettingsGate (0.28s)
./cmd/mesh-controller --- PASS: TestASettingsWalkFailsOnARefusalThatCannotClear (0.40s)
./cmd/mesh-controller --- PASS: TestAProviderElsewhereServesItsOwnComposedName (0.44s)
./cmd/mesh-controller --- PASS: TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne (0.52s)
./cmd/mesh-controller --- PASS: TestAReleaseSendsTheRestAtOnceAfterTheFirstPasses (0.41s)
./cmd/mesh-controller --- PASS: TestARestMachineThatFailsIsPutBackAloneAndTheOthersAreJudgedOn (0.35s)
./cmd/mesh-controller --- PASS: TestAWalkTakesOverTheReadingsOfAGateJudgingTheSameBuildThere (0.48s)
./cmd/mesh-controller --- PASS: TestAFirstSendMadeAndNotKeptIsNotSentAgain (0.47s)
./cmd/mesh-controller --- PASS: TestAReleaseSendKeptAndMadeIsNotMadeAgain (0.34s)
./cmd/mesh-controller --- PASS: TestAFirstMachineThatFailsStillStopsTheWalk (0.36s)
./cmd/mesh-controller --- PASS: TestTheControlNodeIsSentLastInAStep (0.43s)
./cmd/mesh-controller --- PASS: TestARestMachineSilentPastItsBoundIsLeftAndSaid (0.56s)
./cmd/mesh-controller --- PASS: TestANoMoveTierWaitsForNoNewReport (0.37s)
./cmd/mesh-controller --- PASS: TestOneProviderDownAndThreeConsumersFailingAreOneCondition (0.51s)
./cmd/mesh-controller --- PASS: TestAConsumerFailingBesideAHealthyProviderIsItsOwn (0.41s)
./internal/inventory --- PASS: TestTheLastSendSaysWhatTheMachineAnswered (0.09s)
./internal/inventory --- PASS: TestAReportIsTheLastSendsAnswerOnlyWhenItIsAboutThatSend (0.12s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedToEveryHolderOnceAndNotAgain (0.14s)
./internal/inventory --- PASS: TestAnIssuedValueIsSealedAgainAfterAKeyChangeOrAnAcceptance (0.12s)
./internal/inventory --- PASS: TestAConditionsLooksAreKeptBesideTheBucket (0.09s)
./internal/inventory --- PASS: TestAPlanIdHoldingAQuoteIsReadAsAPlainId (0.08s)
./internal/inventory --- PASS: TestAWalksStartIsKeptAndARefusedSaveLeavesItUnsaid (0.11s)
./internal/inventory --- PASS: TestAWalksRestIsReadFromEachMachinesOwnSend (0.09s)
./internal/inventory --- PASS: TestAStoredBuildWithASilentMergeableFileIsStillReadAndComposed (0.08s)
./internal/inventory --- PASS: TestACredentialIssuedOutsideIsNeverMade (0.10s)
./internal/inventory --- PASS: TestOneAcceptForAProviderIsSealedToEveryConsumer (0.10s)
./internal/inventory --- PASS: TestASharedOwnSecretIssuedOutsideIsNeverMade (0.08s)
./internal/inventory --- PASS: TestAReportOfABusyContainerIsKeptAndReadBack (0.43s)
```
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.
Waits for ADR 0363 (proposed; it needs the knowledge base's approval and then the operator's Approve). Do not merge before the record is accepted.
Implements the controller's part of ADR 0363 for issue 718: mesh-mail's events on a stream of their own (
MAIL, ADR 0359 §2), heard only by the modules itsgrantsvalue names per account (§4).What changes
streams(catalogue/streams.go):{name, events, max-age-days, max-mib, grant: {config, events}}. Events are local patterns with*and trailing**, so an account-keyed family is declared once. Refused at registration: bad name, a mesh stream name or a reserved prefix (SEAT_,LOG_,KV_,OBJ_,DEAD_), bounds (1-30 days, 1-8192 MiB), anemitsentry a stream covers, overlapping streams of one module, a grant whose value is not a trusted (terminal) key, a grant pattern without exactly one{key}; across the catalogue, two modules declaring one stream name.<NAME>onmesh.stream.<module>.event.<pattern>(no overlap with EVENTS), limits retention, its age and size. Asserted with every raise and every send inassertBusObjects, before the consumers.consumesnaming the emitter literally is narrowed to the stream's patterns and, for a restricted stream, to the keys the provider's value lists for it (mesh layer under the machine's layer, per machine running the provider,<machine>.<module>for one machine). Only then: a durable consumer<node>_<module>on the stream, the account's INFO / MSG.NEXT / ACK on it, subscribe on the filters, and the membership'shears. A wildcard emitter (**) never reaches a module stream. What a stream carries leaves EVENTS' consumes.PruneHeard), so a consumer that loses its grant loses what it reads through on that send. Memberships of assignments that hear a module stream on machines the send does not reach are re-issued as last issued with onlyhearschanged.streams(stream, events, subject) andhears(stream, consumer).Nothing changes on the bus while no manifest declares
streams(ADR 0262).Order of delivery
streams, bind eachhearsconsumer.The mesh-config half (compose on
config-changedonce config moves to mesh-config, ADR 0348) is issue 724.Checks
go vet ./...clean;go test ./internal/... ./cmd/...pass locally.mesh-controller.tryon the head: see the comment once it answers.Reviewer checklist: the grant can never be composed from
consumesalone for a restricted stream; a wildcard emitter never reaches a module stream; EVENTS consumer filters never include amesh.stream.subject; a consumer losing its grant is removed in the same assertion; nothing changes for manifests withoutstreams.Delivery
novox/mesh-controller@743e6478a76c— delivered since 2026-10-14T20:20:11ZDelivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Machines
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
ede2772bJudged: head
ede2772b3c90merged into trunkc2ec0a601acb; read beside it: mesh-catalogfadf5025cc5a, mesh-controller-mainc2ec0a601acb, 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, route-proxy)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Run by the build seat on shanks as
build-1792007842533777312(builds --log build-1792007842533777312).Merge check at
743e6478Judged: head
743e6478a76cmerged into trunkc2ec0a601acb; read beside it: mesh-catalogfadf5025cc5a, mesh-controller-mainc2ec0a601acb, 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, route-proxy)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Run by the build seat on shanks as
build-1792008356329597819(builds --log build-1792008356329597819).