Issue 1945 (note 101: at 09:21 CET on 2026-10-27 the user list lost nine seats' grants after the placement seed).
Cause: records.go heldWherePlaced kept a mesh seat only where this node's placement holds named its module; the seed's holds listed twelve seats on one node and none elsewhere, so every other seat lost its holder. The loss guard covered memberships, never the user list.
Fix (mesh-grants only):
heldWherePlaced follows mesh-sdk's on-record rule: a seat no placement holds is held by derivation wherever its claimant is placed.
One pure guard, Holdings.LastHolders, for the user list (after take-over) and memberships: held only when a seat (or @) that has a holder in force has none composed while an assigned module still claims it. Dropped tools, fields and seat moves are published (the earlier any-loss hold would freeze the list after an ordinary release, against ADR 0547 §7).
Holdings.CapabilitiesLost keeps a membership that would drop a capability its holder still asks for (verified-sender: dropped on a failed controller word, which cut the operator's approvals that day).
A loaded list that cannot be read holds the list.
Quick or thorough: quick (chosen) in mesh-grants; thorough would export the on-record rule from mesh-sdk catalogue. Only mesh-grants reads placement holds itself, so a group delivery for a few lines costs more than it protects (rules-are-weighed). Noted on 1945.
Today's state is unchanged for the bus: novox follows the controller's list (shadow), and with no placement on the bus heldWherePlaced is not applied. Memberships now publish a dropped tool, field or seat move, as decided.
Tests: rows in the existing TestGrants table from live captures (seeded placement, the licence manager's manifest, novox.node-tools' live subjects); each fails without its fix (the reviewer reverted each). mesh-grants: 1 test function, 52 subtests, no integration test.
Issue 1945 (note 101: at 09:21 CET on 2026-10-27 the user list lost nine seats' grants after the placement seed).
Cause: records.go heldWherePlaced kept a mesh seat only where this node's placement holds named its module; the seed's holds listed twelve seats on one node and none elsewhere, so every other seat lost its holder. The loss guard covered memberships, never the user list.
Fix (mesh-grants only):
- heldWherePlaced follows mesh-sdk's on-record rule: a seat no placement holds is held by derivation wherever its claimant is placed.
- One pure guard, Holdings.LastHolders, for the user list (after take-over) and memberships: held only when a seat (or <seat>@<node>) that has a holder in force has none composed while an assigned module still claims it. Dropped tools, fields and seat moves are published (the earlier any-loss hold would freeze the list after an ordinary release, against ADR 0547 §7).
- Holdings.CapabilitiesLost keeps a membership that would drop a capability its holder still asks for (verified-sender: dropped on a failed controller word, which cut the operator's approvals that day).
- A loaded list that cannot be read holds the list.
Quick or thorough: quick (chosen) in mesh-grants; thorough would export the on-record rule from mesh-sdk catalogue. Only mesh-grants reads placement holds itself, so a group delivery for a few lines costs more than it protects (rules-are-weighed). Noted on 1945.
Today's state is unchanged for the bus: novox follows the controller's list (shadow), and with no placement on the bus heldWherePlaced is not applied. Memberships now publish a dropped tool, field or seat move, as decided.
Tests: rows in the existing TestGrants table from live captures (seeded placement, the licence manager's manifest, novox.node-tools' live subjects); each fails without its fix (the reviewer reverted each). mesh-grants: 1 test function, 52 subtests, no integration test.
Reviewed-by: review-1945b@shanks at ec0b7e2dcc067a7d9c29740d0d78b3ed13672cf7
The user list of 2026-10-27 09:21 granted no holder for nine seats: the seeded
placements hold only the seats the controller had on record, and the grants part
read those holds as every holder (records.go heldWherePlaced). A placement's
holds are now the holders on record, as catalogue.World's Holdings are: a mesh
seat no placement holds is held by derivation, wherever its claimant is placed.
The membership loss guard (Losses) did not cover the user list: after take-over
the list that lost those seats went out. UserLosses applies the same guard per
user against the loaded list, and holdsBack holds a list that would lose a grant,
or whose loaded grants cannot be read, raising the held warning.
Quick fix chosen over moving the on-record rule into mesh-sdk: mesh-grants is the
only part reading placement holds itself; the others pass them to the catalogue.
Holding the user list on any loss would freeze it after take-over at the
first release that drops a tool or moves a seat (ADR 0547 §7), with nothing
to accept a deliberate loss; memberships had the same gap. The lead's decision
in review round 1: one pure guard, Holdings.LastHolders, holds the list and
each membership only when a seat held in force would have no holder in what
is composed now while an assigned module still claims it, the 09:21 kind.
A dropped tool, verb or field, or a seat handed to another node, is written.
A dropped verified-sender comes from a root-free word that failed for one
pass, not from a release, and losing it cut the operator's approvals on
2026-10-27. Holdings.CapabilitiesLost holds such a membership with its own
reason while the holder is assigned and its manifest still asks for it; a
dropped tool or field and a moved seat stay published.
Deliverynovox/mesh-delivery@ec0b7e2dcc06 — merged since 2026-10-27T20:14:06Z
Source — source.main moved to novox/mesh-delivery@da51481620. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.
Transitions
2026-10-27 20:00 (new) → proposed (announced): novox/mesh-delivery#88's head announced
2026-10-27 20:00 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 20:14 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@ec0b7e2dcc06` — **merged** since 2026-10-27T20:14:06Z
**Source** — source.main moved to novox/mesh-delivery@da514816204b. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves.
**Transitions**
- 2026-10-27 20:00 (new) → proposed (announced): novox/mesh-delivery#88's head announced
- 2026-10-27 20:00 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 20:14 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 1945 (note 101: at 09:21 CET on 2026-10-27 the user list lost nine seats' grants after the placement seed).
Cause: records.go heldWherePlaced kept a mesh seat only where this node's placement holds named its module; the seed's holds listed twelve seats on one node and none elsewhere, so every other seat lost its holder. The loss guard covered memberships, never the user list.
Fix (mesh-grants only):
Quick or thorough: quick (chosen) in mesh-grants; thorough would export the on-record rule from mesh-sdk catalogue. Only mesh-grants reads placement holds itself, so a group delivery for a few lines costs more than it protects (rules-are-weighed). Noted on 1945.
Today's state is unchanged for the bus: novox follows the controller's list (shadow), and with no placement on the bus heldWherePlaced is not applied. Memberships now publish a dropped tool, field or seat move, as decided.
Tests: rows in the existing TestGrants table from live captures (seeded placement, the licence manager's manifest, novox.node-tools' live subjects); each fails without its fix (the reviewer reverted each). mesh-grants: 1 test function, 52 subtests, no integration test.
Reviewed-by: review-1945b@shanks at
ec0b7e2dccDelivery
novox/mesh-delivery@ec0b7e2dcc06— merged since 2026-10-27T20:14:06ZSource — source.main moved to novox/mesh-delivery@da51481620. 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.