Put a version of a module on a node with one tool call: the assigner's put, release and puts (ADR 0546) #49

Merged
mesh-tools merged 5 commits from feat/put-version into main 2026-10-25 20:52:06 +00:00
Member

ADR 0546 (approved by the operator 2026-10-25). The operator's ask: "putting version x of module y on node z should be a simple tool call". No seat and no compose verb, so the controller takes no change: the put reads only the compositions and grants the controller already writes (one function, composedFor, so a later owner can take them over).

Tools (the assigner's own, served by its bundle through the tool runner), address <node>/mesh-delivery-assigner.<tool>:

  • assigner_put {node, module, version, hold?, why}: version is newest, a whole src2: fingerprint, or its first 12+ hex digits matching one build. Answers once the put waits on a person or the node, or after 20 s, with its steps and a follow line.
  • assigner_release {node, module, why}: hands the want back to the rules.
  • assigner_puts {node?, module?}: read-only.
    Each step (asked, build, compose, person, snapshot, wanted, holding, done, released, refused) is the event mesh-delivery-assigner.put, so a caller follows it with mesh_wait. New state puts.

What it does: refuses a module not assigned to the node, a failed build, an older unbuilt fingerprint; waits up to 10 minutes for a composition at that fingerprint and a grant naming the node's accounts, then refuses naming the hand path. The bus always asks the operator (approve-level, bound to node, module, fingerprint and composition, checked with Performs before the want), then snapshots through the node's backup holder (read back within 15 minutes), then writes the want held and records the warrant (mesh-controller.warranted). A module of policy record asks an ordinary yes when the move recreates a container, moves data or cannot be judged. Each put asks under its own asking number, so an earlier yes or no never counts for a later put; an expired unanswered ask refuses the put; a put released or replaced meanwhile writes no want. While a put is open the assigner's rules leave that node's want alone (a held bus still takes a user-list change).

mesh-sdk part: mesh-sdk #82 (merged, db26f7e8); the assigner and the teller pin it.

Note for delivery: the new state puts needs its grant in the bus user list; until ADR 0547's bridge is delivered the list reaches the bus by the operator's hand step, and until then the put tools answer that no put is taken further (the assigner keeps writing wants).

Checked: go test -race and go vet -tags integration pass in the assigner and the teller; mesh-controller.try (try-1792961322701334396) passed the integration level of all of mesh-delivery (251 tests) at 22d4cbd1 after the first merge check failed on TestTheAssignerStartsAndSaysWhatItKeeps (it counted four states; it now reads the declared states from module.json). No top-level test functions added (rows in existing tests; the repository is over its 500/50 budget and this change does not raise it).

Review: round 1 blocked on two faults (an old answer reused across puts; a want written for a put no longer standing), both fixed in round 2; then rebased onto 82180bf with the pin moved (range-diff unchanged); then the test fix confirmed. Notes kept: two puts within the same millisecond would share an ask id (not a real case: one tool call each); the snapshot read-back relies on restic's last_backup.

Reviewed-by: review-put@shanks at 22d4cbd144

ADR 0546 (approved by the operator 2026-10-25). The operator's ask: "putting version x of module y on node z should be a simple tool call". No seat and no compose verb, so the controller takes no change: the put reads only the compositions and grants the controller already writes (one function, composedFor, so a later owner can take them over). **Tools** (the assigner's own, served by its bundle through the tool runner), address `<node>/mesh-delivery-assigner.<tool>`: - `assigner_put {node, module, version, hold?, why}`: version is `newest`, a whole `src2:` fingerprint, or its first 12+ hex digits matching one build. Answers once the put waits on a person or the node, or after 20 s, with its steps and a follow line. - `assigner_release {node, module, why}`: hands the want back to the rules. - `assigner_puts {node?, module?}`: read-only. Each step (asked, build, compose, person, snapshot, wanted, holding, done, released, refused) is the event `mesh-delivery-assigner.put`, so a caller follows it with mesh_wait. New state `puts`. **What it does:** refuses a module not assigned to the node, a failed build, an older unbuilt fingerprint; waits up to 10 minutes for a composition at that fingerprint and a grant naming the node's accounts, then refuses naming the hand path. The bus always asks the operator (approve-level, bound to node, module, fingerprint and composition, checked with Performs before the want), then snapshots through the node's backup holder (read back within 15 minutes), then writes the want held and records the warrant (mesh-controller.warranted). A module of policy record asks an ordinary yes when the move recreates a container, moves data or cannot be judged. Each put asks under its own asking number, so an earlier yes or no never counts for a later put; an expired unanswered ask refuses the put; a put released or replaced meanwhile writes no want. While a put is open the assigner's rules leave that node's want alone (a held bus still takes a user-list change). mesh-sdk part: mesh-sdk #82 (merged, db26f7e8); the assigner and the teller pin it. **Note for delivery:** the new state `puts` needs its grant in the bus user list; until ADR 0547's bridge is delivered the list reaches the bus by the operator's hand step, and until then the put tools answer that no put is taken further (the assigner keeps writing wants). Checked: go test -race and go vet -tags integration pass in the assigner and the teller; mesh-controller.try (try-1792961322701334396) passed the integration level of all of mesh-delivery (251 tests) at 22d4cbd1 after the first merge check failed on TestTheAssignerStartsAndSaysWhatItKeeps (it counted four states; it now reads the declared states from module.json). No top-level test functions added (rows in existing tests; the repository is over its 500/50 budget and this change does not raise it). Review: round 1 blocked on two faults (an old answer reused across puts; a want written for a put no longer standing), both fixed in round 2; then rebased onto 82180bf with the pin moved (range-diff unchanged); then the test fix confirmed. Notes kept: two puts within the same millisecond would share an ask id (not a real case: one tool call each); the snapshot read-back relies on restic's last_backup. Reviewed-by: review-put@shanks at 22d4cbd14423856dc79d4e70c19b3afce8b5099d
mesh-tools added 4 commits 2026-10-25 20:38:28 +00:00
Author
Member

Delivery novox/mesh-delivery@22d4cbd14423 — merged since 2026-10-25T20:52:06Z

Source — source.main moved to novox/mesh-delivery@71a6a5bf77. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.

Transitions

  • 2026-10-25 20:48 (new) → proposed (announced): novox/mesh-delivery#49's head announced
  • 2026-10-25 20:50 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
  • 2026-10-25 20:52 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-delivery@22d4cbd14423` — **merged** since 2026-10-25T20:52:06Z **Source** — source.main moved to novox/mesh-delivery@71a6a5bf7717. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves. **Transitions** - 2026-10-25 20:48 (new) → proposed (announced): novox/mesh-delivery#49's head announced - 2026-10-25 20:50 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 - 2026-10-25 20:52 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`.
jschoubben added 1 commit 2026-10-25 20:48:34 +00:00
The assigner's start test expects every state its manifest declares, read from module.json, not a count: the state puts broke the count of four (ADR 0546)
mesh/delivery merged: source.main moved to novox/mesh-delivery@71a6a5bf7717
mesh/check pass 22d4cbd14423 on 82180bffd2c6 | unit 22 run, 578 kept | integration 251 run, 425 kept | composition passed on 2 machines
22d4cbd144
mesh-tools merged commit 71a6a5bf77 into main 2026-10-25 20:52:06 +00:00
mesh-tools deleted branch feat/put-version 2026-10-25 20:52:06 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-delivery#49