Summary
First: vector-core 0.5.0's citation fix works — verified live today. A bot-issued ban's banlist edition and refounding are now honored by Armada, and the community survives the read-cut with all members advancing together. Thank you for cutting the release (#80).
This surfaced the next-layer bug: set_member_banned unconditionally publishes the ban's Grant-strip edition (grant_roles(target, vec![])) regardless of whether the acting identity holds MANAGE_ROLES. Grant editions (vsk 3) are reader-gated by MANAGE_ROLES + outrank — so a moderator holding BAN but not MANAGE_ROLES (a completely normal moderation-bot grant) emits a guaranteed-rejected edition at the target's Grant coordinate on every ban.
Compliant readers drop it, and Armada's suspicious-activity detector then flags the ban — an unauthorized edition at someone's Grant coordinate is exactly the shape of a privilege-manipulation attempt. Routine automated moderation reads as an incident.
Code path (present in 0.5.0 and on master @ 2152459)
crates/vector-core/src/lib.rs (set_member_banned, ~line 2971):
crate::community::v2::service::set_banlist(&transport, &community, &list).await…?; // BAN-gated: accepted
if banned {
crate::community::v2::service::grant_roles(&transport, &community, &pk, vec![]).await…?; // MANAGE_ROLES-gated: rejected
}
…
crate::community::v2::service::refound_community(&transport, &community, &[pk]).await…?; // BAN-gated: accepted
grant_roles (v2/service.rs:3157) publishes with no local authority pre-check — contrast edit_channel_metadata, which mirrors its reader gate locally via ensure_channel_manager precisely so an unauthorized device doesn't "advance its own edition floor onto a head every reader rejects" (its own comment). The Grant path has no such mirror. Note that floor-wedging concern applies here too: the rejected strip advances the publisher's local floor at the target's Grant entity.
Observed live (2026-08-02)
v2 community, human owner, bot granted a Moderator role with permissions 568 = KICK | BAN | MANAGE_MESSAGES | MENTION_EVERYONE (no MANAGE_ROLES, bit 0). Bot bans a spammer via Member::ban():
- banlist → applied in Armada's audit log
- grant strip → "not applied" + suspicious-activity banner
- refounding → applied; community intact
Every automod ban reproduces this: the ban is fully effective, but the audit surface reports a rejected authority action and raises an alarm.
Why the rejected strip costs nothing to skip
Reader folds already drop a banned member's authority editions once the banlist edition is honored (CORD-04 §4 — Armada tests this explicitly: "drops a banned npub's authority editions, banlist aside"). The explicit strip is belt-and-braces; when the actor can't authorize it, publishing it buys nothing and produces the false alarm.
Suggested fix
Either:
- Mirror the reader gate locally (the
ensure_channel_manager pattern): skip the Grant-strip phase when the local authority view says the actor lacks MANAGE_ROLES (or lacks outrank), relying on the §4 auto-drop. Least invasive; keeps readers strict.
- Or, at the spec level, define the in-ban Grant strip as authorized under
BAN and update reader folds to accept it in that context.
(1) seems clearly preferable — it's a two-line guard and changes no wire semantics.
Related
Armada-side display report (stale-plane rendering + the suspicious-activity UX around this) filed on the Armada Nostr repo: event 18cff094508a0ef191f9845b4f2b40ff7f94b240aaa478f052fd4061ad236f7c (gitworkshop.dev).
Summary
First: vector-core 0.5.0's citation fix works — verified live today. A bot-issued ban's banlist edition and refounding are now honored by Armada, and the community survives the read-cut with all members advancing together. Thank you for cutting the release (#80).
This surfaced the next-layer bug:
set_member_bannedunconditionally publishes the ban's Grant-strip edition (grant_roles(target, vec![])) regardless of whether the acting identity holdsMANAGE_ROLES. Grant editions (vsk 3) are reader-gated byMANAGE_ROLES+ outrank — so a moderator holdingBANbut notMANAGE_ROLES(a completely normal moderation-bot grant) emits a guaranteed-rejected edition at the target's Grant coordinate on every ban.Compliant readers drop it, and Armada's suspicious-activity detector then flags the ban — an unauthorized edition at someone's Grant coordinate is exactly the shape of a privilege-manipulation attempt. Routine automated moderation reads as an incident.
Code path (present in 0.5.0 and on
master@ 2152459)crates/vector-core/src/lib.rs(set_member_banned, ~line 2971):grant_roles(v2/service.rs:3157) publishes with no local authority pre-check — contrastedit_channel_metadata, which mirrors its reader gate locally viaensure_channel_managerprecisely so an unauthorized device doesn't "advance its own edition floor onto a head every reader rejects" (its own comment). The Grant path has no such mirror. Note that floor-wedging concern applies here too: the rejected strip advances the publisher's local floor at the target's Grant entity.Observed live (2026-08-02)
v2 community, human owner, bot granted a Moderator role with permissions
568=KICK | BAN | MANAGE_MESSAGES | MENTION_EVERYONE(noMANAGE_ROLES, bit 0). Bot bans a spammer viaMember::ban():Every automod ban reproduces this: the ban is fully effective, but the audit surface reports a rejected authority action and raises an alarm.
Why the rejected strip costs nothing to skip
Reader folds already drop a banned member's authority editions once the banlist edition is honored (CORD-04 §4 — Armada tests this explicitly: "drops a banned npub's authority editions, banlist aside"). The explicit strip is belt-and-braces; when the actor can't authorize it, publishing it buys nothing and produces the false alarm.
Suggested fix
Either:
ensure_channel_managerpattern): skip the Grant-strip phase when the local authority view says the actor lacksMANAGE_ROLES(or lacks outrank), relying on the §4 auto-drop. Least invasive; keeps readers strict.BANand update reader folds to accept it in that context.(1) seems clearly preferable — it's a two-line guard and changes no wire semantics.
Related
Armada-side display report (stale-plane rendering + the suspicious-activity UX around this) filed on the Armada Nostr repo: event
18cff094508a0ef191f9845b4f2b40ff7f94b240aaa478f052fd4061ad236f7c(gitworkshop.dev).