mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 16:33:27 +00:00
A staff-making Grant delivers the `control_root` inside the fold itself (CORD-04 §3), so it lands on an entry whose session was built as a read-only member long before. `ConcordSessionRegistry.sync` only rebuilt a session when `root`/`rootEpoch` changed, and `ConcordCommunitySession` derived `controlKeys` once at construction — adoption changes neither, so the live session kept `signer = null` and `canWrite == false` for the rest of the process. The promoted staffer saw their new role badge appear (that half reads the folded `state` flow) while every write affordance stayed hidden and `controlKeysForWrite` refused, until the app was restarted. Rebuilding the session on the change is not the fix: the new session starts with no buffered Control Plane wraps, so the community folds to "No channels yet" until every wrap happens to be re-delivered. Instead refresh the key material in place. Nothing about the plane moves — adoption is gated on the secret deriving to exactly the `control_pk` already held (CORD-02 §5) — so the address, read key, buffered wraps and subscription set are all invariant, and only the signer appears. `adoptControlMaterial` fails closed on a different community/root/epoch or an address change, leaving those to a rebuild. Verified on device (SM-T220, Android 14) against a loopback geode relay: an account promoted to staff while sitting on the community screen gains the edit/create affordances with no restart, keeps its folded channel list, and its next Control edition lands on the wire signed by `control_pk`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>