A bootstrapped seat counts as read by every node-engine, and node users get the seat list (issue 1966, recovery) #174

Merged
mesh-tools merged 2 commits from fix/1966-seat-reads-bootstrap into main 2026-11-08 03:45:01 +00:00
Member

Recovery group fix/1966-seat-reads-bootstrap (mesh-delivery, mesh-host, mesh-tools), issue 1966 notes 78-89.

Cause. ace's node-engine states no seat names (it computes its reads once, before its seat list loads), so the assigner holds the newest node-engine on ace for seat:mesh-catalog, and restic for seat:node-backup; every other node waits for ace. Both are bootstrapped seats every reader carries from its start (ADR 0636 §2), so the hold is a deadlock. Separately, grants gives a node user the node-engine manifest's consumes but not its invokes, and grants the seat's events on the module's subject, so node. may not ask the seat list (nats_user_can, live).

Change. sdk/graph/reads.go graph.MissingReads: a seat: need of a bootstrapped seat counts as read; the assigner's readerLacking and the indexer's hold use it. mesh-grants: the node user gets the engine manifest's invokes in its own caller token and the seat events on the seat's subject; nothing granted before is removed.

Evidence. Rows in wants_test.go (mesh-host seat:mesh-catalog and restic seat:node-backup move, seat:mesh-vault still held), holds_test.go, graph_test.go, grants_test.go; each fails without its change. go vet (both tags) and unit suites pass.

Undo. Revert this merge.

Reviewed-by: mesh-code-reviewer@shanks at ee6fd92b4d

https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5

Recovery group fix/1966-seat-reads-bootstrap (mesh-delivery, mesh-host, mesh-tools), issue 1966 notes 78-89. **Cause.** ace's node-engine states no seat names (it computes its reads once, before its seat list loads), so the assigner holds the newest node-engine on ace for seat:mesh-catalog, and restic for seat:node-backup; every other node waits for ace. Both are bootstrapped seats every reader carries from its start (ADR 0636 §2), so the hold is a deadlock. Separately, grants gives a node user the node-engine manifest's consumes but not its invokes, and grants the seat's events on the module's subject, so node.<n> may not ask the seat list (nats_user_can, live). **Change.** `sdk/graph/reads.go` graph.MissingReads: a seat: need of a bootstrapped seat counts as read; the assigner's readerLacking and the indexer's hold use it. mesh-grants: the node user gets the engine manifest's invokes in its own caller token and the seat events on the seat's subject; nothing granted before is removed. **Evidence.** Rows in wants_test.go (mesh-host seat:mesh-catalog and restic seat:node-backup move, seat:mesh-vault still held), holds_test.go, graph_test.go, grants_test.go; each fails without its change. go vet (both tags) and unit suites pass. **Undo.** Revert this merge. Reviewed-by: mesh-code-reviewer@shanks at ee6fd92b4d1a4375b03ea963e952a7592be4c0d7 https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
mesh-tools added 2 commits 2026-11-08 02:55:40 +00:00
The grants part built the node-engine's declaration with its consumes alone,
so a node's account was granted none of the engine manifest's invokes: ace's
engine could not publish mesh.seat.mesh-catalog.call.seat-definitions.node~ace,
read no seat list and composed nothing new. And its consumes of
mesh-catalog's seat-definition events were granted on the emitter's subject
only, where the engine subscribes the seat's (ADR 0636 §4).

The engine's declaration now carries its invokes and the seats it watches,
split by the same consumedOf a placed module's consumes are; the node's
account is granted the invokes as a module's are (in its own caller token
by callerNamed) and the watched events on each seat's subject by the same
watchedEvents a module's use. Its consumes stay granted on the emitter's
subjects too, so nothing granted before is taken away.

Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
The assigner and the indexer's hold count a bootstrapped seat as read (issue 1966)
mesh/delivery merged: source.main moved to novox/mesh-delivery@7f412185525e
mesh/delivery-group group fix/1966-seat-reads-bootstrap merged: every member is merged
mesh/check failed (2): mesh-delivery-checker: no published of the tagged version of go-sdk of mesh-delivery…; and 1 more | ee6fd92b4d1a on 7f412185525e
ee6fd92b4d
Every reader of the seat list holds the bootstrapped seats from its start
(ADR 0636 §2), so a manifest naming one is read by every node-engine
whatever its statement names. graph.MissingReads, in the Delivery domain's
SDK, is the one rule both holds judge with; mesh-sdk is not changed.

ace's engine states no seat, so the want of the node-engine's own build
0bd8cbad (needing mesh-catalog) and of restic (needing node-backup) were
held on ace: the engine that would state them could not be delivered. The
indexer's hold judges only mesh-wide reads today, so its verdicts do not
change; it takes the rule so the two stay one.

Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
Author
Member

Delivery novox/mesh-delivery@ee6fd92b4d1a — merged since 2026-11-08T03:45:04Z

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

Group fix/1966-seat-reads-bootstrap: novox/mesh-delivery@ee6fd92b4d, novox/mesh-host@9ab85ef92e, novox/mesh-tools@7572627aff

  • composed together: fail — the checker's verdict at the members' heads (cb2ce203891b): mesh-delivery-checker

Transitions

  • 2026-11-08 02:55 (new) → proposed (announced): novox/mesh-delivery#174's head announced
  • 2026-11-08 02:55 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-08 03:45 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@ee6fd92b4d1a` — **merged** since 2026-11-08T03:45:04Z **Source** — source.main moved to novox/mesh-delivery@7f412185525e. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves. **Group** `fix/1966-seat-reads-bootstrap`: novox/mesh-delivery@ee6fd92b4d1a, novox/mesh-host@9ab85ef92e6c, novox/mesh-tools@7572627affde - composed together: fail — the checker's verdict at the members' heads (cb2ce203891b): mesh-delivery-checker **Transitions** - 2026-11-08 02:55 (new) → proposed (announced): novox/mesh-delivery#174's head announced - 2026-11-08 02:55 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-08 03:45 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-tools merged commit 7f41218552 into main 2026-11-08 03:45:01 +00:00
mesh-tools deleted branch fix/1966-seat-reads-bootstrap 2026-11-08 03:45:02 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-delivery#174