Issue 774 (design 47): nothing is left with the controller — enrolment and rotation. ADRs 0587, 0589, 0583, 0588.
The engine dials as node.<n> or node.<n>--b as the vault's node-logins says; switches only after a test-dial, confirms as the new login, drops the old value at rotation-done, falls back and says node-account-fallback in its health report.
mesh-host enrol redeems through the seat and keeps only an answer signed by the token's key; before the lease write it falls back to the controller's path.
Pins mesh-sdk at the group's head.
Delivery group: the four pull requests on branch feat/l3-enrol (mesh-sdk, mesh-catalog, mesh-delivery, mesh-host), one check, one Approve, merged in one pass in the order mesh-sdk → mesh-catalog → mesh-delivery → mesh-host. Rebased on main after the removal group merged (2026-11-02 01:35); every member pins mesh-sdk at dff0ce2abb21 (this group's head). Issuing and rotation stay off until the lease write (ADR 0561 §3, ADR 0587 §4).
Tested locally before the push (GOWORK=off, GOFLAGS=-mod=readonly, GOPROXY=off, GOSUMDB=off): go vet, go vet -tags integration and the untagged unit suite of every touched module pass. Integration tests that exercise the change, against an embedded bus: ./internal/link incl. the rotation test against a real bus whose list is reloaded: ok.
Reviewed-by: review-g2@shanks at 44db32c31b
Pushed-by: lead-47@shanks
Issue 774 (design 47): nothing is left with the controller — enrolment and rotation. ADRs 0587, 0589, 0583, 0588.
- The engine dials as `node.<n>` or `node.<n>--b` as the vault's `node-logins` says; switches only after a test-dial, confirms as the new login, drops the old value at rotation-done, falls back and says node-account-fallback in its health report.
- `mesh-host enrol` redeems through the seat and keeps only an answer signed by the token's key; before the lease write it falls back to the controller's path.
- Pins mesh-sdk at the group's head.
**Delivery group:** the four pull requests on branch `feat/l3-enrol` (mesh-sdk, mesh-catalog, mesh-delivery, mesh-host), one check, one Approve, merged in one pass in the order mesh-sdk → mesh-catalog → mesh-delivery → mesh-host. Rebased on main after the removal group merged (2026-11-02 01:35); every member pins mesh-sdk at dff0ce2abb21 (this group's head). Issuing and rotation stay off until the lease write (ADR 0561 §3, ADR 0587 §4).
**Tested locally before the push** (GOWORK=off, GOFLAGS=-mod=readonly, GOPROXY=off, GOSUMDB=off): `go vet`, `go vet -tags integration` and the untagged unit suite of every touched module pass. Integration tests that exercise the change, against an embedded bus: `./internal/link` incl. the rotation test against a real bus whose list is reloaded: ok.
Reviewed-by: review-g2@shanks at 44db32c31bbed9b7dd87e4477ea3fb2a64bdaf6e
Pushed-by: lead-47@shanks
https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
A membership may name its Logins (ADR 0583 §1): the login in use and the password of each login held, kept beside the
identity, so a restart dials as the login in use. The engine follows its own key of node-logins as a watch on every link
and dials as the login it names when it holds its value, with the node's one inbox; with no key, or a key naming the first
login, it dials node.<n> with the membership's password as before. A change of the login in use drops the link so it is
opened again as the new one, and the vault is asked in the name of the login dialled (the subject names the caller).
Tests: one added, paid by merging the pinned-broker test with the malformed-pin test (two into one).
(issue 774, 774/S61)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
On node-logins' ready the engine fetches the new value through the vault's own hand-out (own/<node>/mesh-host/<login>, opened
with its sealing key), dials a second connection as the new login on the pinned certificate, and switches only if that
authenticates, then calls mesh-vault.node-account-confirm over the link as the new login (the vault is asked in the name of
the login the open link authenticated as, and only once that link is open). It keeps the old value until the key says the
rotation is done and drops it then, never before; an abandon, after the switch before or after the confirmation, switches
back before the new value is dropped; repeated refusals of the new login's credentials before rotation-done bring it back
to the old one, said as the finding node-account-fallback (in the journal: no route for an engine's finding to the watchman
is decided), and the same rotation is not tried again. Tests: two added, paid by merging two identity sealing tests into one;
more to be paid by deleting the identity token tests that move to mesh-sdk with the token (774/S64).
(issue 774, 774/S62, 774/S63)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
The engine dials as enrol.<node> on the pinned certificate, calls redeem with the public halves of its keys and a proof over
them (the SDK's RedeemProof, which binds the node and the keys and never the token's secret), asks again while the holder
says to, and verifies the vault's answer against the key its token carries before it keeps anything: an answer signed by
another key, naming another signer or node, or altered is refused and nothing is kept. A signed one is kept (membership,
login, keys), then the node dials as the login it was given, reads its key of node-logins, and calls confirm; nothing is
applied until its placement names a module. When the bus does not serve the seat to the token (the controller still holds its
lease) the controller's enrolment subject is used as before. The token's shape is mesh-sdk's now: identity keeps its names as
aliases. Tests: one added, paid by merging three identity token tests into one (net two fewer).
(issue 774, 774/S64)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
A stand-in vault reloads a nats-server's users as the grants part's list is loaded, and the engine's own rotation code runs
against it with real test-dials and a real confirmation request: at every step at least one login authenticates; the engine
switches only once the list holds both logins and confirms in the new login's name; at rotation-done the old login is
retired and its value dropped; with the list never loaded the test-dial is refused and the engine never switches; and an
abandon after the switch brings the engine back to the old login before the new value goes (ADR 0583 §2-§6). One integration
test; mesh-host holds seven of fifty. The real vault and the real engine together are proven live on g14 first.
(issue 774, 774/S65)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
A fall back to the old login during a rotation is now delivery.NodeHealth's Fallback (the node, the login fallen back from,
why, when), written with the node's health report, from which the watchman raises node-account-fallback; it is said no more
once the vault's key of the node moves on (blocker 7, ADR 0583 §6). mesh-host enrol's fall back to the controller's
enrolment subject says it is the path before the lease write, which the bus refuses once the lease is written. Tests: rows
in the existing rotation test; none added.
(issue 774)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
Deliverynovox/mesh-host@44db32c31bbe — merged since 2026-11-02T07:56:46Z
Source — source.main moved to novox/mesh-host@14a12cc7b6. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.
composed together: fail — the checker's verdict at the members' heads (3820753740cd): integration: mesh-mail-reader/cmd/mesh-mail-reader.TestAcceptanceOneMatteringMailSendsExactlyOneTellNamingIt
Transitions
2026-11-02 00:52 (new) → proposed (announced): novox/mesh-host#195's head announced
2026-11-02 00:52 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 07:56 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-host@44db32c31bbe` — **merged** since 2026-11-02T07:56:46Z
**Source** — source.main moved to novox/mesh-host@14a12cc7b6f9. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves.
**Group** `feat/l3-enrol`: novox/mesh-catalog@c84dfb5e0bcd, novox/mesh-delivery@63c8687166e6, novox/mesh-host@44db32c31bbe, novox/mesh-sdk@dff0ce2abb21
- composed together: fail — the checker's verdict at the members' heads (3820753740cd): integration: mesh-mail-reader/cmd/mesh-mail-reader.TestAcceptanceOneMatteringMailSendsExactlyOneTellNamingIt
**Transitions**
- 2026-11-02 00:52 (new) → proposed (announced): novox/mesh-host#195's head announced
- 2026-11-02 00:52 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 07:56 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 774 (design 47): nothing is left with the controller — enrolment and rotation. ADRs 0587, 0589, 0583, 0588.
node.<n>ornode.<n>--bas the vault'snode-loginssays; switches only after a test-dial, confirms as the new login, drops the old value at rotation-done, falls back and says node-account-fallback in its health report.mesh-host enrolredeems through the seat and keeps only an answer signed by the token's key; before the lease write it falls back to the controller's path.Delivery group: the four pull requests on branch
feat/l3-enrol(mesh-sdk, mesh-catalog, mesh-delivery, mesh-host), one check, one Approve, merged in one pass in the order mesh-sdk → mesh-catalog → mesh-delivery → mesh-host. Rebased on main after the removal group merged (2026-11-02 01:35); every member pins mesh-sdk at dff0ce2abb21 (this group's head). Issuing and rotation stay off until the lease write (ADR 0561 §3, ADR 0587 §4).Tested locally before the push (GOWORK=off, GOFLAGS=-mod=readonly, GOPROXY=off, GOSUMDB=off):
go vet,go vet -tags integrationand the untagged unit suite of every touched module pass. Integration tests that exercise the change, against an embedded bus:./internal/linkincl. the rotation test against a real bus whose list is reloaded: ok.Reviewed-by: review-g2@shanks at
44db32c31bPushed-by: lead-47@shanks
https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
Delivery
novox/mesh-host@44db32c31bbe— merged since 2026-11-02T07:56:46ZSource — source.main moved to novox/mesh-host@14a12cc7b6. Whether it reached the machines is
mesh-delivery-view's, derived fromsource.main, the wants and the haves.Group
feat/l3-enrol: novox/mesh-catalog@c84dfb5e0b, novox/mesh-delivery@63c8687166, novox/mesh-host@44db32c31b, novox/mesh-sdk@dff0ce2abbTransitions
The commit's note under
refs/notes/mesh-plankeeps every transition of this change up to its merge:git log --notes=mesh-plan.