A want's self comes from the current placement alone, so a node no longer placed gets the controller's composition instead of a stale self want (issue 1126)
#86
Merged
mesh-toolsmerged 1 commits from fix/1126-self-wants into main2026-10-27 15:25:21 +00:00
Issue 1126 note 27 (cause, quick vs thorough, acceptance 1126/AC-SW1..3).
Live: after the placement seed's revert (#521) want.g14.systemd-resolved, want.g14.forticlient and want.shanks.forticlient kept {self:true}; g14's haves read failed 'the node cannot compose it ... g14 has no placement in the catalogue'. Cause (modules/mesh-delivery-assigner): self was set only in yeses() for placed nodes; Wants' held branch copied the old want (next = before) and the rule branch wrote {FP, Composed: before.Composed} with an empty composition, refused by Want.check, so the stale self want stayed.
assign.Module.Self(node), set once from the placement in pass.go, is the one source; a step selfDerived ends every branch of Wants: a placed node's want is Self with no composition; a want left Self on a node no longer placed gets the controller's composition at the fingerprint the rule keeps (F when held at F, the older fingerprint's when held back), Yes cleared, through mustAsk for a record module; no composition -> the old want stays (rule 7).
yeses() reads m.Self.
Quick vs thorough: quick = fill Composed in the held and rule branches only; thorough chosen = one derivation of self ending every branch (the kind: a placement-derived field carried along by any rule that holds a want).
No version moves (selfDerived never changes FP); placed nodes behave as before.
Tests: eight rows in TestEachRuleHoldsTheWantBack (7 fail without the fix); go vet, go vet -tags integration, go test -race pass; test functions unchanged (589/76).
Note kept for later (review): a kept stale self want held at rule 7 is not said in the journal (sayNoWant skips a node with a live want).
Issue 1126 note 27 (cause, quick vs thorough, acceptance 1126/AC-SW1..3).
Live: after the placement seed's revert (#521) want.g14.systemd-resolved, want.g14.forticlient and want.shanks.forticlient kept {self:true}; g14's haves read failed 'the node cannot compose it ... g14 has no placement in the catalogue'. Cause (modules/mesh-delivery-assigner): self was set only in yeses() for placed nodes; Wants' held branch copied the old want (next = before) and the rule branch wrote {FP, Composed: before.Composed} with an empty composition, refused by Want.check, so the stale self want stayed.
- assign.Module.Self(node), set once from the placement in pass.go, is the one source; a step selfDerived ends every branch of Wants: a placed node's want is Self with no composition; a want left Self on a node no longer placed gets the controller's composition at the fingerprint the rule keeps (F when held at F, the older fingerprint's when held back), Yes cleared, through mustAsk for a record module; no composition -> the old want stays (rule 7).
- yeses() reads m.Self.
Quick vs thorough: quick = fill Composed in the held and rule branches only; thorough chosen = one derivation of self ending every branch (the kind: a placement-derived field carried along by any rule that holds a want).
No version moves (selfDerived never changes FP); placed nodes behave as before.
Tests: eight rows in TestEachRuleHoldsTheWantBack (7 fail without the fix); go vet, go vet -tags integration, go test -race pass; test functions unchanged (589/76).
Note kept for later (review): a kept stale self want held at rule 7 is not said in the journal (sayNoWant skips a node with a live want).
Reviewed-by: review-selfwant@shanks at bb63d83f849e250275714210cfbe2705c03a5067
After the placement seed's revert the rules that hold a want (a hold, rules 3 and 5) kept g14's and shanks's Self wants: the held branch copied them whole, and the rule branch wrote a want naming no composition, which EncodeWant refuses. Module.Self, set once from the placement, is now the one source, and every want the rules write or keep is derived from it: an unplaced node's kept want names the controller's composition of the same fingerprint, asked as any record move; with none, it stays and rule 7 says why.
Deliverynovox/mesh-delivery@bb63d83f849e — merged since 2026-10-27T15:25:21Z
Source — source.main moved to novox/mesh-delivery@c38e81c7f5. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.
Transitions
2026-10-27 15:23 (new) → proposed (announced): novox/mesh-delivery#86's head announced
2026-10-27 15:23 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-10-27 15:25 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@bb63d83f849e` — **merged** since 2026-10-27T15:25:21Z
**Source** — source.main moved to novox/mesh-delivery@c38e81c7f5e9. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves.
**Transitions**
- 2026-10-27 15:23 (new) → proposed (announced): novox/mesh-delivery#86's head announced
- 2026-10-27 15:23 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-10-27 15:25 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`.
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.
Issue 1126 note 27 (cause, quick vs thorough, acceptance 1126/AC-SW1..3).
Live: after the placement seed's revert (#521) want.g14.systemd-resolved, want.g14.forticlient and want.shanks.forticlient kept {self:true}; g14's haves read failed 'the node cannot compose it ... g14 has no placement in the catalogue'. Cause (modules/mesh-delivery-assigner): self was set only in yeses() for placed nodes; Wants' held branch copied the old want (next = before) and the rule branch wrote {FP, Composed: before.Composed} with an empty composition, refused by Want.check, so the stale self want stayed.
Quick vs thorough: quick = fill Composed in the held and rule branches only; thorough chosen = one derivation of self ending every branch (the kind: a placement-derived field carried along by any rule that holds a want).
No version moves (selfDerived never changes FP); placed nodes behave as before.
Tests: eight rows in TestEachRuleHoldsTheWantBack (7 fail without the fix); go vet, go vet -tags integration, go test -race pass; test functions unchanged (589/76).
Note kept for later (review): a kept stale self want held at rule 7 is not said in the journal (sayNoWant skips a node with a live want).
Reviewed-by: review-selfwant@shanks at
bb63d83f84Delivery
novox/mesh-delivery@bb63d83f849e— merged since 2026-10-27T15:25:21ZSource — source.main moved to novox/mesh-delivery@c38e81c7f5. Whether it reached the machines is
mesh-delivery-view's, derived fromsource.main, the wants and the haves.Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition of this change up to its merge:git log --notes=mesh-plan.