A named push's cascade (hq ADR 0083) sent every machine whose declaration differed from its last send. Under the upgrade policy record, or while a plan waits on its first machine (ADR 0218), that is every machine running the module. So push <anchor> sent all four machines the held build (hq issue 259).
What changes
Migration 0061 adds node.sent_builds jsonb, mapping each module to the built_from commit it was sent at. NULL means not known: the machine was sent before this was kept, or sent by hand.
Inventory.RecordSent(ctx, node, digest, builds) (nil records NULL), Inventory.SentBuilds, Inventory.CurrentBuilds (built_from + roll-out policy, one read).
declarationWith fills sendable.Builds on the send path (carriedBuilds). A module that was left out keeps its last build. overTheBus.declare records the builds. declare by hand records nil.
heldBack (a pure function) decides whether a machine is held: a module moves to a build its policy records, or that an open plan has not sent this machine yet (planStillToSend). A module never sent counts as a move. NULL counts as held. heldMachines is the store-backed wrapper.
The cascade is pulled out into flushBehind. It skips held machines and names each one with the module, the builds, the reason, and that push <node> sends it. A bus holder that is behind and would be added to a named push is held the same way. The push says that the bus may refuse new grants until that machine is sent.
Unchanged: the named machine itself, a whole-mesh push, push --behind (the remedy record names), and plan and upgrade sends.
Tests
Pure tests: heldBack for record, roll-out, nothing moved, NULL and never-sent. Plan holding at the first machine, sent everywhere, failed or closed. carriedBuilds.
Postgres-gated tests:
TestANamedPushLeavesAMachineAPolicyHoldsBack: the laptop's sent digest is unchanged and the output names it. Held and owed a peer change: not sent, and both are said. With roll-out it is sent and the new build is recorded.
TestANamedPushStillSendsAConsequenceNothingHolds: the issue 057 case is still flushed, and a send made by hand is held.
TestASendKeepsTheBuildsItCarried: round trip, including NULL.
gofmt -l, go vet ./... and go test -p 1 ./... with MESH_TEST_POSTGRES all pass.
A named push's cascade (hq ADR 0083) sent every machine whose declaration differed from its last send. Under the upgrade policy `record`, or while a plan waits on its first machine (ADR 0218), that is every machine running the module. So `push <anchor>` sent all four machines the held build (hq issue 259).
## What changes
- **Migration 0061** adds `node.sent_builds jsonb`, mapping each module to the `built_from` commit it was sent at. NULL means not known: the machine was sent before this was kept, or sent by hand.
- `Inventory.RecordSent(ctx, node, digest, builds)` (nil records NULL), `Inventory.SentBuilds`, `Inventory.CurrentBuilds` (built_from + roll-out policy, one read).
- `declarationWith` fills `sendable.Builds` on the send path (`carriedBuilds`). A module that was left out keeps its last build. `overTheBus.declare` records the builds. `declare` by hand records nil.
- `heldBack` (a pure function) decides whether a machine is held: a module moves to a build its policy records, or that an open plan has not sent this machine yet (`planStillToSend`). A module never sent counts as a move. NULL counts as held. `heldMachines` is the store-backed wrapper.
- The cascade is pulled out into `flushBehind`. It skips held machines and names each one with the module, the builds, the reason, and that `push <node>` sends it. A bus holder that is behind and would be added to a named push is held the same way. The push says that the bus may refuse new grants until that machine is sent.
- Unchanged: the named machine itself, a whole-mesh push, `push --behind` (the remedy `record` names), and plan and upgrade sends.
## Tests
- Pure tests: `heldBack` for record, roll-out, nothing moved, NULL and never-sent. Plan holding at the first machine, sent everywhere, failed or closed. `carriedBuilds`.
- Postgres-gated tests:
- `TestANamedPushLeavesAMachineAPolicyHoldsBack`: the laptop's sent digest is unchanged and the output names it. Held and owed a peer change: not sent, and both are said. With roll-out it is sent and the new build is recorded.
- `TestANamedPushStillSendsAConsequenceNothingHolds`: the issue 057 case is still flushed, and a send made by hand is held.
- `TestASendKeepsTheBuildsItCarried`: round trip, including NULL.
`gofmt -l`, `go vet ./...` and `go test -p 1 ./...` with `MESH_TEST_POSTGRES` all pass.
hq side: novox/hq branch `decision/0221-a-push-sends-no-held-build`.
A named push flushed every other machine whose declaration differed from
what it was last sent (hq ADR 0083). Under an upgrade policy of `record`,
or a plan still waiting on its first machine (ADR 0218), every machine
running the module differs, so `push <one>` sent the held build to all of
them (hq issue 259).
Each send now records which build of each module it carried
(node.sent_builds, migration 0061). The cascade, and the bus holder added
to a named push, skip a machine any of whose modules would move to a
build its policy records or an open plan has not sent it, and say which
module, which build, why, and that `push <node>` sends it. A machine
whose last send was not recorded is held until it is named. The named
machine itself, a whole-mesh push and `push --behind` are unchanged.
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
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
Transitions
2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#64 merged; its head was not heard by this owner, so it is made from the forge's word
2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-controller@002d5e578cb3` — **held** since 2026-10-06T23:05:28Z
Held for a person: merged without a passing check: only a person decides that it goes on — `mesh-delivery.release` with why lets it go on.
**Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- tier 2: route-proxy
- ace: receives build-agent, route-proxy
- g14: receives build-agent
- novox: receives mesh-controller, build-agent, route-proxy
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- 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
**Transitions**
- 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#64 merged; its head was not heard by this owner, so it is made from the forge's word
- 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
A named push's cascade (hq ADR 0083) sent every machine whose declaration differed from its last send. Under the upgrade policy
record, or while a plan waits on its first machine (ADR 0218), that is every machine running the module. Sopush <anchor>sent all four machines the held build (hq issue 259).What changes
node.sent_builds jsonb, mapping each module to thebuilt_fromcommit it was sent at. NULL means not known: the machine was sent before this was kept, or sent by hand.Inventory.RecordSent(ctx, node, digest, builds)(nil records NULL),Inventory.SentBuilds,Inventory.CurrentBuilds(built_from + roll-out policy, one read).declarationWithfillssendable.Buildson the send path (carriedBuilds). A module that was left out keeps its last build.overTheBus.declarerecords the builds.declareby hand records nil.heldBack(a pure function) decides whether a machine is held: a module moves to a build its policy records, or that an open plan has not sent this machine yet (planStillToSend). A module never sent counts as a move. NULL counts as held.heldMachinesis the store-backed wrapper.flushBehind. It skips held machines and names each one with the module, the builds, the reason, and thatpush <node>sends it. A bus holder that is behind and would be added to a named push is held the same way. The push says that the bus may refuse new grants until that machine is sent.push --behind(the remedyrecordnames), and plan and upgrade sends.Tests
heldBackfor record, roll-out, nothing moved, NULL and never-sent. Plan holding at the first machine, sent everywhere, failed or closed.carriedBuilds.TestANamedPushLeavesAMachineAPolicyHoldsBack: the laptop's sent digest is unchanged and the output names it. Held and owed a peer change: not sent, and both are said. With roll-out it is sent and the new build is recorded.TestANamedPushStillSendsAConsequenceNothingHolds: the issue 057 case is still flushed, and a send made by hand is held.TestASendKeepsTheBuildsItCarried: round trip, including NULL.gofmt -l,go vet ./...andgo test -p 1 ./...withMESH_TEST_POSTGRESall pass.hq side: novox/hq branch
decision/0221-a-push-sends-no-held-build.Delivery
novox/mesh-controller@002d5e578cb3— held since 2026-10-06T23:05:28ZHeld for a person: merged without a passing check: only a person decides that it goes on —
mesh-delivery.releasewith why lets it go on.Delivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.