The lease write's contract: the seat mesh-grants, the lease cut, processes follow their membership from state alone (issue 774) #156

Merged
mesh-tools merged 9 commits from feat/l3-removal into main 2026-11-02 00:35:20 +00:00
Member

Issue 774 (design 47): nothing is left with the controller — the removal before the lease write. ADRs 0582, 0588, 0571 §13, 0567 §11, 0564 §9.

  • The seat mesh-grants (verbs lease-write, lease-hand-back; events lease-handed, lease-altered, removal-failed) (ADR 0582 §1).
  • Records.LeaseCut: once handed, the controller loses its write on the lease key and the bucket; mesh-grants writes holder alone; the bus module's tools account may update the lease's stream.
  • The lease value gains ask and at; the grants part's user-list key gains lease-handed.
  • The controller-dependence judge moves here (catalogue.ManifestRefusals, phase write) (ADR 0571 §13).
  • A process follows its membership from the state memberships alone; nobody subscribes to mesh.assignment any more.
  • WatchmanHears gains the seat's three events and the deletion advisory of ASSIGNMENTS.

Delivery group: the five pull requests on branch feat/l3-removal (mesh-sdk, mesh-catalog, mesh-delivery, mesh-host, mesh-tools), one check, one Approve, merged in one pass in the order mesh-sdk → mesh-catalog → mesh-delivery → mesh-host → mesh-tools. Every member pins mesh-sdk at c21d8fd969 (this group's head). Every new behaviour is dormant until the lease write, which is asked separately on the operator's Approve.

Tested locally before the push (GOWORK=off, GOFLAGS=-mod=readonly, GOPROXY=off, GOSUMDB=off): gofmt, go vet and go vet -tags integration, and the whole untagged unit suite of every touched module pass. Integration tests that exercise the change, against an embedded bus: TestFollowMembershipHearsWhatIsIssuedToTheAccount (go/process): ok, 8.8 s.

Reviewed-by: review-g1@shanks at c21d8fd969
Pushed-by: lead-47@shanks

https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL

Issue 774 (design 47): nothing is left with the controller — the removal before the lease write. ADRs 0582, 0588, 0571 §13, 0567 §11, 0564 §9. - The seat `mesh-grants` (verbs lease-write, lease-hand-back; events lease-handed, lease-altered, removal-failed) (ADR 0582 §1). - `Records.LeaseCut`: once handed, the controller loses its write on the lease key and the bucket; mesh-grants writes `holder` alone; the bus module's tools account may update the lease's stream. - The lease value gains `ask` and `at`; the grants part's user-list key gains `lease-handed`. - The controller-dependence judge moves here (`catalogue.ManifestRefusals`, phase write) (ADR 0571 §13). - A process follows its membership from the state `memberships` alone; nobody subscribes to `mesh.assignment` any more. - `WatchmanHears` gains the seat's three events and the deletion advisory of ASSIGNMENTS. **Delivery group:** the five pull requests on branch `feat/l3-removal` (mesh-sdk, mesh-catalog, mesh-delivery, mesh-host, mesh-tools), one check, one Approve, merged in one pass in the order mesh-sdk → mesh-catalog → mesh-delivery → mesh-host → mesh-tools. Every member pins mesh-sdk at c21d8fd9692c (this group's head). Every new behaviour is dormant until the lease write, which is asked separately on the operator's Approve. **Tested locally before the push** (GOWORK=off, GOFLAGS=-mod=readonly, GOPROXY=off, GOSUMDB=off): gofmt, `go vet` and `go vet -tags integration`, and the whole untagged unit suite of every touched module pass. Integration tests that exercise the change, against an embedded bus: `TestFollowMembershipHearsWhatIsIssuedToTheAccount` (go/process): ok, 8.8 s. Reviewed-by: review-g1@shanks at c21d8fd9692c1714dc93440ab25a677747ff9c6e Pushed-by: lead-47@shanks https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
mesh-tools added 9 commits 2026-11-01 23:57:59 +00:00
ADR 0582 clause 1 makes the lease write a verb of the seat mesh-grants: lease-write and lease-hand-back, each
taking a why, and the events lease-handed, lease-altered and removal-failed. The indexer's judge reads seats
through catalogue.SeatNamed, so it accepts mesh-grants' claim once it pins this head.

Test: TestTheGrantsSeatPromisesTheLeaseWrite (new), paid by merging the two ssh tests of filtering_test.go into
TestSSHIsOpenFromTheMeshEvenWhenNothingIsAssigned.

(issue 774, 774/S1)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
ADR 0582 clause 3 composes the bus's user list without the controller's write on the lease key and update of
the lease's bucket. Records.LeaseCut, set by the grants part from the write's second step, drops the
controller's $KV grant on the lease, denies it the bucket's update, purge, delete and message delete (its
$JS.API.> reaches them), and lets the grants part write the key holder alone. The bus module's tools account
may read and update the lease's bucket, for the expiry tool the write and the hand-back call. Without the cut
the lists equal the controller's golden.

Tests: rows added to TestTheCopiedComposerComposesAsTheControllers' tables (the cut on and off; the tools
account's lease grants); no new test function.

(issue 774, 774/S2)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
ADR 0582 clause 3 writes the key holder "with the why, the ask and the time": LeaseHolder gains ask and at,
which LeaseHandedAway ignores (it reads handed-to alone). The grants part's user-list key gains lease-handed,
so the bus node's engine follows the grants part's list alone once the lease is handed (ADR 0571 clause 8)
and never falls back to the controller's; a key written before reads false.

Tests: a row in the lease table of TestTheCopiedComposerComposesAsTheControllers; the old key (shaped as
EncodeGrantsUserList writes it today) and the flag's round trip added to the existing user-list case in
delivery_test.go; no new test function.

(issue 774, 774/S3)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
ADR 0571 §13 names a test in mesh-catalog, mesh-delivery and mesh-tools that refuses a manifest depending on
the controller beyond the lease and the entries kept. The judge lived in mesh-grants (leasecheck.go); it moves
here whole (the kinds, the phases, KeepList, EndedBy, Dependencies, Judge) with ManifestRefusals(manifests,
phase) for those tests. Kept is renamed KeptDependency (catalogue already has a Kept), and a gap is Unread.
mesh-grants re-exports it in its own commit; the keep list is the one at mesh-delivery 4a84370.

Test: TestTheLeaseWritesCheckJudgesEveryDependencyOnTheController, moved from mesh-grants'
leasecheck_test.go (its manifest rows and the keep-list test, which mesh-grants deletes), with the
conditions row of 774/S4/AC1 added; not a new test.

(issue 774, 774/S4)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
ADR 0571 clause 10: the grants part publishes memberships on mesh.assignment until the lease write and stops
then. FollowMembership now reads and watches its own key of the state memberships and nothing else, and refuses
to follow, naming the state, when it cannot read it (there is nothing else to follow, and a silent follow of
nothing is the fault). A module's principal and the runtime lose their subscribe on mesh.assignment; the grants
part's publish grant stays until the write (S21 stops the publishing).

Tests: TestFollowMembershipHearsWhatIsIssuedToTheAccount (integration) edited: no state is a refusal, a
membership put in the state is applied, one published on the subject is not; run locally against its
embedded bus. Rows added to TestTheCopiedComposerComposesAsTheControllers: nobody subscribes mesh.assignment,
and the controller's golden grant of it is the one row the copy now lacks. No new test function.

(issue 774, 774/S5)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
It said which placement changes waited for the lease write while the assigner called the controller's assign,
unassign, pin and unpin (ADR 0567 §8). Since the assigner calls no controller verb (774/S25), nothing reads it.

Test: its table in TestPlacement goes with it.

(issue 774, 774/S25)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
ADR 0571 §13: the lease write's own delivery drops every entry but the builder's artifacts-gone, the artifact
sweep's collect and the engine's following of the controller's user list. Every module of this group stops
its read, invoke or consume of the controller (pacman, the keeper, mesh-config, the hand-act log's readers, the
watcher, messenger, the assigner, mesh-grants), so the list shrinks to the three and a read put back is
refused in either phase. Supersedes the keep of pacman's read at mesh-delivery 4a84370.

Tests: rows of TestTheLeaseWritesCheckJudgesEveryDependencyOnTheController changed (the keeper's read put back
is refused; the sweep's collect passes); no new test function.

(issue 774, 774/S30)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
ADR 0582 clauses 4 and 6 have mesh-grants say lease-altered and removal-failed "as a finding the watchman
raises". WatchmanHears, the one list its grant and its subscriptions come from, gains the seat mesh-grants'
three events and the advisory of ASSIGNMENTS deleted (which, with the controller's consumer deleted that it
hears already, clears a failed removal). Core subjects, read-only, no durable consumer.

Test: rows added to the watchman's subjects in TestTheCopiedComposerComposesAsTheControllers; no new function.

(issue 774, 774/S22)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
Fold the seat mesh-grants' test into the seat-verb test, within the test budget
mesh/delivery merged: source.main moved to novox/mesh-sdk@5758e9fb57ab
mesh/delivery-group group feat/l3-removal merged: every member is merged
mesh/check failed: mesh-build-go: the check of novox/mesh-catalog#590: the ask mvyhumdm860c7f's step on shanks did not end within 30m0s of its start |…
c21d8fd969
The repository is over its unit budget and a change may not raise the count: the case of the seat mesh-grants
(ADR 0582 clause 1) runs as a subtest of TestTheDeliverySeatPromisesChecks instead of a function of its own.

(issue 774, 774/S1)

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

Delivery novox/mesh-sdk@c21d8fd9692c — merged since 2026-11-02T00:35:21Z

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

Group feat/l3-removal: novox/mesh-catalog@2c5e9c9a98, novox/mesh-delivery@17ef1d577d, novox/mesh-host@c27fad5c6e, novox/mesh-sdk@c21d8fd969, novox/mesh-tools@29fd452628

  • composed together: fail — the checker's verdict at the members' heads (49fb3ed27c03): mesh-build-go

Transitions

  • 2026-11-01 23:58 (new) → proposed (announced): novox/mesh-sdk#156's head announced
  • 2026-11-01 23:58 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-02 00:35 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-sdk@c21d8fd9692c` — **merged** since 2026-11-02T00:35:21Z **Source** — source.main moved to novox/mesh-sdk@5758e9fb57ab. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves. **Group** `feat/l3-removal`: novox/mesh-catalog@2c5e9c9a9847, novox/mesh-delivery@17ef1d577d4f, novox/mesh-host@c27fad5c6e36, novox/mesh-sdk@c21d8fd9692c, novox/mesh-tools@29fd452628ec - composed together: fail — the checker's verdict at the members' heads (49fb3ed27c03): mesh-build-go **Transitions** - 2026-11-01 23:58 (new) → proposed (announced): novox/mesh-sdk#156's head announced - 2026-11-01 23:58 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-02 00:35 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 5758e9fb57 into main 2026-11-02 00:35:20 +00:00
mesh-tools deleted branch feat/l3-removal 2026-11-02 00:35:20 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-sdk#156