Design 47: the lead's answers for a placed module whose build failed (a small fix on main, issue 1966) #584

Merged
mesh-tools merged 2 commits from design/47-unpublished-placed-module into main 2026-11-12 15:28:10 +00:00
@@ -0,0 +1,34 @@
---
layer: to-be
status: draft
updated: 2026-11-12
decisions: ["ADR 0593", "ADR 0606", "ADR 0429"]
code: [mesh-host, mesh-catalog]
---
# A placed module whose build failed: the lead's answers for a small fix on main
The small fix of a provisioner held unhealthy since 2026-11-09: a placed module whose newest build the builder holds
failed (a Go package, which the builder refuses today) is never published by the node-engine, so the provisioner waits
for its composition at every pass, says itself unhealthy, and the assigner holds every new provisioner build. The fix
goes alone on main and milestone G joins it, since G rewrites the same files.
- **U1** (who answers): the node-engine, which publishes for every placed module (ADR 0593 §6), writes a refused key at
the newest fingerprint for a placed module whose newest build is failed, with the build's words; a build queued or
running stays unpublished (P2, P3).
- **U2** (the Go package build itself, against ADR 0606 §1 and §7): not in this fix; milestone G builds it (P5).
- **U3** (whether mesh-wireguard is a module the mesh provides): not in this fix; the node-engine's special case stays
until a design says otherwise (P7).
- **U4** (a lasting unpublished hold in the provisioner's own health): not in this fix; noted on the issue the fix runs
under (P7).
- **U5** (held fingerprints of superseded provisioner builds): after the fix is delivered, the eight older holds are
released through the assigner's hold ask, told to the operator in one line; their cleanup by the assigner is noted
(P3, P7).
- **U6** (the provisioner's comment at holder.go:113-114 says an unpublished module stops retirement on the whole node;
the code keeps only that module's keys): the comment is corrected to the code, in the same group (P3, P8).
- **U7** (the provisioner's retiring asks whose id is over 64 characters are refused at every pass, and the key's why says
it waits for an open ask): the ask id is bounded, made from the key, and a refused ask is said in the key's why and
in provisioner_health, in the same group (P3).
- **U8** (develop, U1's trigger): the node-engine writes U1's refused key on the event that the placed module's newest
build ended failed, not at the next pass some other input starts; a refusal written late is a wait nobody can read
(P1, P3).