mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-12 01:07:46 +00:00
A promotion to staff delivers the `control_root` inside the Grant edition itself (CORD-04 §3). Amethyst drains that on its Concord revision tick, but that logic lived only in `AccountConcordActions`, so `amy` could hold a rank it could never write under: the fold seated it as staff and every moderation verb still refused with `forbidden`. That is also why #3873's delivery path shipped without a CLI test — the harness could not accept a promotion. Extracts the decision into `commons` as `ConcordReceive`, pure and shared: - `deliveredControlRoot` — the whole fail-closed check (are we staff by our OWN fold, does a Grant carry a wrap, does it open under the pairwise key, name this epoch, and derive to the `control_pk` we already hold). - `withAdoptedRoot` — the entry rewrite a base rotation produces, banking the leaving epoch's address for the anti-rollback floor. - `isAuthorizedRotator` — the ban-aware rotator check. Amethyst now calls the shared versions (no behaviour change; its persist + publish and Guestbook re-announce stay put). amy adopts during the Control Plane drain every moderation command already performs, since it has no tick of its own, and returns the refreshed record so a freshly promoted staffer can pass the secret on in its own Grant. Adoption is local to amy's store on purpose: Amethyst republishes the kind-13302 list so a user's other devices follow, and doing that here would mean rebuilding and signing the whole list from the CLI. Verified end to end against a loopback geode: bob is refused before the promotion, alice promotes him, bob's stored `control_root` is blank, his next command adopts and persists it, and his BAN lands and is honored by alice's independent fold. A role edition he lacks MANAGE_ROLES for is still dropped on fold — possession remains a spam gate, never authority. Still Android-only: `recoverStrandedConcordCommunities`, which needs invite re-resolution over the network. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>