pacman keeps one mirror list for the mesh and reads each node's own packages; the provisioner composes once (ADR 0585, ADR 0565 §6, ADR 0570; issues 1876, 1953, 1954)
#588
Merged
mesh-toolsmerged 9 commits from feat/node-packages into main2026-11-01 17:02:29 +00:00
What it does: (1) each node's engine writes its own declared packages (bucket mesh-host_packages, key ) only when a composition changes them, and the node seat answers packages beside the controller mirror and their difference; pacman reads it and names its source (the last unkept controller read before the lease write, per mesh-grants.grants_lease_check). Deviation said: the read is named mesh-host.packages (the engine's module bucket, as disk-load reads mesh-host.data), not node-engine.packages. (2) mesh-provisioner composes a node once over one read with a bounded take-in cache and reads its own states from the watched copy with write-through; per-phase timings in provisioner_compose. Measured on captured novox inputs: 11.7 s -> 0.49 s per compose, identical plans over nine runs. (3) pacman keeps one mirror list for the mesh on the bus, ranked inside the write that opens a weekly round; each node writes /etc/pacman.d/mirrorlist from it through the root helper, and a round's run starts only once the file holds the round's list; reflector's timer is disabled.
Quick vs thorough: thorough for all three (the slow reader's third instance; the decided per-node packages; the decided mirror list). Test counts unchanged in every repository. Local reproduction: unit and integration of every changed module, go vet -tags integration of all 134 go.mod files, offline build with -mod=readonly. Review: reviewerP@shanks, three rounds (round 1: the opener upgraded before its file was written; round 2: a committed binary removed; round 3: the timing-test fix below kept three upper bounds under the production timeouts).
This member: pacman (state mirrors, ranking in the round's opening write, the root-helper verb mirrorlist, pacman_mirrors with refresh refused during a round, a run refused until the file holds the round's list; reads mesh-host.packages); mesh-provisioner (one Composition per node, watched own states, Took timings, BenchmarkComposeNode). Both pin mesh-sdk b2a27ed5.
Also in this member (issue 1814, met a third time on this group's first check 98ce55efa892, which failed on i3's TestAtItsStartTheWatcherReloadsWhatTheRunningI3HasNotLoaded): every catalogue test that waited a fixed time for concurrent work now waits on the event or a condition (52 test files in 32 modules, test code only, counts unchanged; stress-run -count=5 -cpu 1,4 -race under load). Quick fix (the i3 test) weighed against the thorough fix (the kind): thorough, the third instance.
Reviewed-by: reviewerP@shanks at 5ccce4967a
Pushed-by: lead-47@shanks
Delivery group feat/node-packages (mesh-sdk, mesh-host, mesh-catalog, mesh-delivery), one check, one Approve. Issues 1953 (design 47 L5), 1954 (L6), 1876. Decisions: ADR 0565 clauses 1, 6, 14, 15; ADR 0570; ADR 0580; ADR 0585.
What it does: (1) each node's engine writes its own declared packages (bucket mesh-host_packages, key <node>) only when a composition changes them, and the node seat answers `packages` beside the controller mirror and their difference; pacman reads it and names its source (the last unkept controller read before the lease write, per mesh-grants.grants_lease_check). Deviation said: the read is named mesh-host.packages (the engine's module bucket, as disk-load reads mesh-host.data), not node-engine.packages. (2) mesh-provisioner composes a node once over one read with a bounded take-in cache and reads its own states from the watched copy with write-through; per-phase timings in provisioner_compose. Measured on captured novox inputs: 11.7 s -> 0.49 s per compose, identical plans over nine runs. (3) pacman keeps one mirror list for the mesh on the bus, ranked inside the write that opens a weekly round; each node writes /etc/pacman.d/mirrorlist from it through the root helper, and a round's run starts only once the file holds the round's list; reflector's timer is disabled.
Quick vs thorough: thorough for all three (the slow reader's third instance; the decided per-node packages; the decided mirror list). Test counts unchanged in every repository. Local reproduction: unit and integration of every changed module, go vet -tags integration of all 134 go.mod files, offline build with -mod=readonly. Review: reviewerP@shanks, three rounds (round 1: the opener upgraded before its file was written; round 2: a committed binary removed; round 3: the timing-test fix below kept three upper bounds under the production timeouts).
This member: pacman (state mirrors, ranking in the round's opening write, the root-helper verb mirrorlist, pacman_mirrors with refresh refused during a round, a run refused until the file holds the round's list; reads mesh-host.packages); mesh-provisioner (one Composition per node, watched own states, Took timings, BenchmarkComposeNode). Both pin mesh-sdk b2a27ed5.
Also in this member (issue 1814, met a third time on this group's first check 98ce55efa892, which failed on i3's TestAtItsStartTheWatcherReloadsWhatTheRunningI3HasNotLoaded): every catalogue test that waited a fixed time for concurrent work now waits on the event or a condition (52 test files in 32 modules, test code only, counts unchanged; stress-run -count=5 -cpu 1,4 -race under load). Quick fix (the i3 test) weighed against the thorough fix (the kind): thorough, the third instance.
Reviewed-by: reviewerP@shanks at 5ccce4967a98e2e368f9e24558574f829999eaa9
Pushed-by: lead-47@shanks
https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
The read node-engine.packages named a bucket node-engine_packages that nothing writes:
the engine's manifest is mesh-host's, so its state is mesh-host_packages, read as
disk-load reads mesh-host.data. The view still names which source answered, the
engine's key or the controller's mirror.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
Each node's reflector ranked its own list on its own timer, and on 2026-10-31 one node's
lagging first mirror left it a Node.js version behind the rest. The list is now the
module's state mirrors, key list: the node that opens a week's round ranks it with the
module's reflector options, keeps only mirrors whose last sync is no older than the
newest found, and the round's key names the list's revision. Every keeper writes
/etc/pacman.d/mirrorlist whole from the key through the root helper's new verb
mirrorlist, when the key changes and when the file differs, and never writes an empty
or unreadable list. reflector.timer is declared stopped and disabled, and reflector.conf
saves nothing. pacman_mirrors answers the shared list, its ranker and age and whether
this node's file matches; with refresh it asks this node's keeper to rank again,
refused while a round runs, naming it. The round's integration test proves the opening
write and both nodes' files.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
provisioner_compose took 2.6-13.6 s per node with nothing changed, CPU
bound. The node is now composed at its wanted and its newest builds over
one read (frombus.PlansHeldTwice, whose composer resolves each machine
once), its own plans, provisions and refusals and the providers' entries
are read from the watched copy, its own writes taken in at once, and a
provider's manifest once by digest: no read by key per composition is
left. The result says where the time went, phase by phase, and a slow
composition that changed nothing says it in the log.
BenchmarkComposeNode times it over a mesh captured with the read tools
(MESH_COMPOSE_CAPTURE): novox 11.7 s to 0.49 s, ace 0.49 s, g14 and
shanks 0.39 s; plans and provisions identical to before over nine
compositions of the four nodes.
Needs mesh-sdk feat/compose-once (5d26c65); go.mod still pins the old
mesh-sdk until the group pins its head.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
The delivery group feat/node-packages pins one mesh-sdk head in every member: pacman reads EnginePackagesRead from it, and mesh-provisioner composes a node once with it.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
mesh/delivery-group group feat/node-packages rejected: composed together: the checker's verdict at the members' heads (98ce55efa892): unit: i3/cmd/i3-tools.Tes…
The opener ranked the list and took its turn in the same step, so its upgrade started
before the keeper's change hook wrote /etc/pacman.d/mirrorlist, and a failed write on
any node was only logged. A round's run now writes the list first and checks the file
holds the revision the round opened with; otherwise the run is refused with why and
tried again an hour later, as every refused run is. A refresh asks again for a running
round right before its write, since ranking takes minutes.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
Deliverynovox/mesh-catalog@5ccce4967a98 — merged since 2026-11-01T17:02:42Z
Source — source.main moved to novox/mesh-catalog@3483f603ae. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.
composed together: pass — the checker's verdict at the members' heads (0388ac1f351b)
Transitions
2026-11-01 16:28 (new) → proposed (announced): novox/mesh-catalog#588's head announced
2026-11-01 16:28 proposed → ready (accepted): a verdict names this commit and the trunk's head as its trunk commit, the gate passed or warned, and the repository's own check did not fail; or the check gates no merge (check-gates-merge false)
2026-11-01 17:02 ready → merged (merged): on the trunk its modules follow: merged there
The commit's note under refs/notes/mesh-plan keeps every transition of this change up to its merge: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-catalog@5ccce4967a98` — **merged** since 2026-11-01T17:02:42Z
**Source** — source.main moved to novox/mesh-catalog@3483f603ae3d. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves.
**Group** `feat/node-packages`: novox/mesh-catalog@5ccce4967a98, novox/mesh-delivery@b18c62f671e1, novox/mesh-host@74ecda8ea2cf, novox/mesh-sdk@b2a27ed5cec4
- composed together: pass — the checker's verdict at the members' heads (0388ac1f351b)
**Transitions**
- 2026-11-01 16:28 (new) → proposed (announced): novox/mesh-catalog#588's head announced
- 2026-11-01 16:28 proposed → ready (accepted): a verdict names this commit and the trunk's head as its trunk commit, the gate passed or warned, and the repository's own check did not fail; or the check gates no merge (check-gates-merge false)
- 2026-11-01 17:02 ready → merged (merged): on the trunk its modules follow: merged there
The commit's note under `refs/notes/mesh-plan` keeps every transition of this change up to its merge: `git log --notes=mesh-plan`.
A test that slept a fixed time and then asserted what a goroutine, process or
watcher did failed under the checker's load. Each now waits for its positive
evidence (a started baseline, a call counted, a state reached) within 30 s, and
the concurrency-limit tests meet at a barrier instead of overlapping by sleep.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
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.
Delivery group feat/node-packages (mesh-sdk, mesh-host, mesh-catalog, mesh-delivery), one check, one Approve. Issues 1953 (design 47 L5), 1954 (L6), 1876. Decisions: ADR 0565 clauses 1, 6, 14, 15; ADR 0570; ADR 0580; ADR 0585.
What it does: (1) each node's engine writes its own declared packages (bucket mesh-host_packages, key ) only when a composition changes them, and the node seat answers
packagesbeside the controller mirror and their difference; pacman reads it and names its source (the last unkept controller read before the lease write, per mesh-grants.grants_lease_check). Deviation said: the read is named mesh-host.packages (the engine's module bucket, as disk-load reads mesh-host.data), not node-engine.packages. (2) mesh-provisioner composes a node once over one read with a bounded take-in cache and reads its own states from the watched copy with write-through; per-phase timings in provisioner_compose. Measured on captured novox inputs: 11.7 s -> 0.49 s per compose, identical plans over nine runs. (3) pacman keeps one mirror list for the mesh on the bus, ranked inside the write that opens a weekly round; each node writes /etc/pacman.d/mirrorlist from it through the root helper, and a round's run starts only once the file holds the round's list; reflector's timer is disabled.Quick vs thorough: thorough for all three (the slow reader's third instance; the decided per-node packages; the decided mirror list). Test counts unchanged in every repository. Local reproduction: unit and integration of every changed module, go vet -tags integration of all 134 go.mod files, offline build with -mod=readonly. Review: reviewerP@shanks, three rounds (round 1: the opener upgraded before its file was written; round 2: a committed binary removed; round 3: the timing-test fix below kept three upper bounds under the production timeouts).
This member: pacman (state mirrors, ranking in the round's opening write, the root-helper verb mirrorlist, pacman_mirrors with refresh refused during a round, a run refused until the file holds the round's list; reads mesh-host.packages); mesh-provisioner (one Composition per node, watched own states, Took timings, BenchmarkComposeNode). Both pin mesh-sdk b2a27ed5.
Also in this member (issue 1814, met a third time on this group's first check 98ce55efa892, which failed on i3's TestAtItsStartTheWatcherReloadsWhatTheRunningI3HasNotLoaded): every catalogue test that waited a fixed time for concurrent work now waits on the event or a condition (52 test files in 32 modules, test code only, counts unchanged; stress-run -count=5 -cpu 1,4 -race under load). Quick fix (the i3 test) weighed against the thorough fix (the kind): thorough, the third instance.
Reviewed-by: reviewerP@shanks at
5ccce4967aPushed-by: lead-47@shanks
https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
Delivery
novox/mesh-catalog@5ccce4967a98— merged since 2026-11-01T17:02:42ZSource — source.main moved to novox/mesh-catalog@3483f603ae. Whether it reached the machines is
mesh-delivery-view's, derived fromsource.main, the wants and the haves.Group
feat/node-packages: novox/mesh-catalog@5ccce4967a, novox/mesh-delivery@b18c62f671, novox/mesh-host@74ecda8ea2, novox/mesh-sdk@b2a27ed5ceTransitions
The commit's note under
refs/notes/mesh-plankeeps every transition of this change up to its merge:git log --notes=mesh-plan.