A snapshot: read at commit 707a04c7ce8 on 2026-10-18T00:06:01Z by majordomus 0.29.0. Nothing on this page is read again. See it live
I2705
A node key can be rotated, peers follow the new key, and the old key is refused
Where it stands
devtask.issue- Readiness
- ready no dependency and no gate holds it; nobody has started it
- Status
- READY
- Can start
- startable
- Milestone
- Milestone status
- ACTIVE
- Wave
1- Waiting on
- none
- Holds back
- none
- Behind it in all
0- Evidence
0of1
Moves
plan.transitionWhat it is
- Objective
- Offer a node key rotation that peers which trusted the old key can follow to the new one, after which the old key's hello is refused, and purge a withdrawn key's events from the running journal without waiting for a restart.
- Why
- Split from I2134 on 2026-10-14. I2134 made a key withdrawn from trust.allow lose its links without a restart (Cooperation::retrust), and its desired_state said 'Not done here' of rotating a node key and of purging a withdrawn key's events from the running journal, while its acceptance criteria still required rotation, so it could never close. A compromised key can now be cut off live, but it cannot be replaced: there is no rotate flow (threat T11). Baseline audit of 2026-10-09 at master 1fb8d6be44, mesh gap 6 and the identity row.
- Now
- The node identity is created once and loaded from its key file (apps/majordomus-cli/src/mesh/identity.rs); nothing replaces it, and no message tells a peer that a key it trusts is succeeded by another. Cooperation::retrust (apps/majordomus-cli/src/mesh/cooperation.rs), called from the live reload (apps/majordomus-cli/src/live.rs) through capability::builtin::mesh::retrust, ends the links of keys no longer trusted; a withdrawn key's events stay in the running journal until the next restart's reload applies the trust in force (I2124). The key file is written at the umask's mode and chmodded to 0600 afterwards (apps/majordomus-cli/src/mesh/identity.rs); session prismatic-majordomus-6e is fixing exactly that on its own branch, and it is not this issue's work.
- Wanted
- A command rotates this node's key: the new identity is signed for by the old one, peers that trusted the old key accept the succession and link to the new key, and the old key's next hello is refused. A key withdrawn from the trust in force has its events dropped from the running journal at the reload that withdrew it. docs/MESH.md describes rotation and what a peer does on it.
- Done when
- unknown: the record declares no `completion`
- Risk
- unknown: the record declares no `risk`
Acceptance
- After a rotation, peers that trusted the old key link to the new one, and the old key's next hello is refused
- A key withdrawn from trust.allow on a running runtime has its events dropped from the running journal at the reload that withdrew it, with no restart
- Validation
bin/majordomus plan validatecargo test --test mesh_cooperationcargo test --lib mesh::identity- Evidence required
key_rotation_test- Evidence present
- unknown: the record carries no `evidence` entries
Scope
- Touches
apps/majordomus-cli/src/mesh/identity.rsapps/majordomus-cli/src/mesh/trust.rsapps/majordomus-cli/src/mesh/cooperation.rsapps/majordomus-cli/src/mesh/journal.rsapps/majordomus-cli/src/capability/builtin/mesh.rsapps/majordomus-cli/tests/mesh_cooperation.rsdocs/MESH.md- Not
Ending a withdrawn key's links without a restart, which I2134 deliveredCreating the key file owner-only from its first byte, which session prismatic-majordomus-6e is fixing on its own branch under I2134The journal reload applying the trust in force, which is I2124's- Depends on
- Priority
- p0
- Profile
- implementation
- Parallel safe
- false
- Owner
- unknown: the record declares no `owner`
The work so far
- Branches
- none
- Merged
- none
- Commits
0- Trunk
- master
- Sessions
- none
- Created
- 2026-10-14
- Updated
- 2026-10-14
- Started
- unknown: the record declares no `started_at`
- Verified
- unknown: the record declares no `verified_at`
- Completed
- unknown: the record declares no `completed_at`
Synchronisation
- Adapter
scripts/github-sync- Repository
- unknown: the derived plan's header carries no repository
- External issue
- unknown: a live GitHub state; this executable makes no network call, so only `scripts/github-sync --check` can answer it
- State there
- unknown: a live GitHub state; this executable makes no network call, so only `scripts/github-sync --check` can answer it
Findings
| Level | Code | Message | Reproduce |
|---|---|---|---|
| WARN | scope_conflict | shares apps/majordomus-cli/src/mesh/journal.rs with I2706; they may not run concurrently | majordomus plan validate |
| WARN | scope_conflict | shares apps/majordomus-cli/src/mesh/cooperation.rs with I2708; they may not run concurrently | majordomus plan validate |
| WARN | scope_conflict | shares apps/majordomus-cli/src/mesh/identity.rs with I2709; they may not run concurrently | majordomus plan validate |