Summary
Multiple successful Member::ban() calls do not accumulate on the community banlist. Each call returns Ok(()), but the folded banlist grows by fewer entries than bans issued, and fewer banlist editions are published than bans made.
Versions
vector-core / vector_sdk built from master (e66f5c9)
- Community minted by armada (Concord v2, split control plane)
Observed
One run of a moderation bot against 11 throwaway spam identities. The bot's own audit log, recorded immediately after each SDK call returns:
ban enforced=true x4 ← 4 distinct npubs, all Ok(())
ban enforced=false x1 (unrelated: write-key race at startup)
kick enforced=true x3
warn enforced=true x6
The four enforced=true bans were confirmed to be 4 distinct npubs (not escalation re-bans of one identity):
npub1pzx60ar6vlaqux03t5n…
npub1ukkl5cxk8heanjwg5k0…
npub1ug90snrv57yw8tfhnpg…
npub13sx4zjwhnjef5qhm8l0…
Resulting state:
bot banlist 90 → 92 entries (+2 for 4 successful bans)
banlist head v6 → v8 (2 publishes for 4 bans)
So two of the four bans produced no banlist edition at all, and the two that did are the only ones that stuck.
Independent confirmation from a second member
An ordinary member (separate identity, separate process) folding the same community during the run:
bot banlist 92 entries, folded v8, published v8
observer banlist 0 entries, folded v0
Across an earlier run the two agreed exactly (88 entries, v4 on both), so the fold path works in general — but bans issued during a run do not reach other members.
Caller side
The bot's entire involvement is one call per decision:
No retry, no batching, no local banlist manipulation, and no reconcile logic. Every call in the sample above returned Ok(()).
Reproduce
- Community with a moderator holding
BAN (verified: role permissions 2943, bit 4 = BAN set).
- Have several distinct identities join and post.
- Call
Member::ban() on each in quick succession, checking each returns Ok(()).
- Compare the number of successful calls against
communities.banlist length and banlist_at version.
Bans issued with gaps between them appear more likely to stick than bans issued in quick succession, which is consistent with a read-modify-write of the banlist entity racing itself — each publish derived from a snapshot taken before the previous one landed.
Impact
ban() reporting success while the ban neither persists nor reaches members is silent moderation failure: staff and bots believe an account is banned, and members keep seeing it. For automated moderation the loss rate scales with how fast abuse arrives, which is exactly when it matters most.
Summary
Multiple successful
Member::ban()calls do not accumulate on the community banlist. Each call returnsOk(()), but the folded banlist grows by fewer entries than bans issued, and fewer banlist editions are published than bans made.Versions
vector-core/vector_sdkbuilt frommaster(e66f5c9)Observed
One run of a moderation bot against 11 throwaway spam identities. The bot's own audit log, recorded immediately after each SDK call returns:
The four
enforced=truebans were confirmed to be 4 distinct npubs (not escalation re-bans of one identity):Resulting state:
So two of the four bans produced no banlist edition at all, and the two that did are the only ones that stuck.
Independent confirmation from a second member
An ordinary member (separate identity, separate process) folding the same community during the run:
Across an earlier run the two agreed exactly (88 entries, v4 on both), so the fold path works in general — but bans issued during a run do not reach other members.
Caller side
The bot's entire involvement is one call per decision:
No retry, no batching, no local banlist manipulation, and no reconcile logic. Every call in the sample above returned
Ok(()).Reproduce
BAN(verified: role permissions2943, bit 4 =BANset).Member::ban()on each in quick succession, checking each returnsOk(()).communities.banlistlength andbanlist_atversion.Bans issued with gaps between them appear more likely to stick than bans issued in quick succession, which is consistent with a read-modify-write of the banlist entity racing itself — each publish derived from a snapshot taken before the previous one landed.
Impact
ban()reporting success while the ban neither persists nor reaches members is silent moderation failure: staff and bots believe an account is banned, and members keep seeing it. For automated moderation the loss rate scales with how fast abuse arrives, which is exactly when it matters most.