Skip to content

vector-core 0.4.0: control editions omit CORD-04 §5 authority citations — fixed on main, needs a release #80

Description

@derekross

Summary

vector-core 0.4.0 — the latest release on crates.io — publishes every v2 control edition without a CORD-04 §5 authority citation. Any control edition authored by a non-owner is therefore rejected by spec-compliant readers, silently.

This is already fixed on main (required_authority_citation() in crates/vector-core/src/community/v2/service.rs). This issue is a request to cut a release, since downstream consumers on crates.io can't reach the fix — main still reads version = "0.4.0", matching the published crate.

Impact

I maintain concord-bots, a Concord bot framework built on vector_sdk. A bot is by definition a non-owner acting under a granted role, so it hits this on every moderation action:

  • ban silently no-ops. set_member_banned()publish_control_edition(…, None). The wrap publishes without error and the SDK reports success, but no compliant reader honors it.
  • kick works, because kick_member() publishes a guestbook rumor (kind 3309), not a control edition — no citation gate.
  • Same silent failure applies to grant_roles, set_role, edit_community_metadata, and edit_channel_metadata.

Evidence

All nine publish_control_edition call sites in 0.4.0 pass None:

$ grep -c 'publish_control_edition(transport.*None)' src/community/v2/service.rs
9
// vector-core-0.4.0/src/community/v2/service.rs:2271
pub async fn set_banlist<T: Transport + ?Sized>(...) -> Result<(), String> {
    ...
    publish_control_edition(transport, community, &session, vsk::BANLIST, &eid, &content, None).await
                                                                                          // ^^^^
}

main fixed exactly this, and the commit message says so better than I can:

// CORD-04 §5: a non-owner names the exact Grant edition it claims its rank
// under. Computed here rather than passed in — the citation is a property of
// WHO IS ACTING, identical for every entity kind, so deciding it per call
// site is nine chances to forget (and nine were, silently: every site passed
// None). The owner cites nothing; their rank is the community id itself.
let citation = required_authority_citation(community, &my_pk)?;

Why it fails silently

The Rust and TS folds disagree on whether the citation is mandatory:

reader emits citation verifies citation verdict
vector-core 0.4.0 no noapply_control_fold gates on permissions + banned only accepted
Armada (TS) yescitationSatisfied() rejected, fail-closed

So the publisher writes an uncited edition, reads it back with a fold that doesn't ask for one, and concludes success. Armada asks, gets nothing, and folds the banlist to empty per "unauthorized head → empty (fail closed)".

Reproduction

Against a v2 community where the bot holds a role with BAN (perms 568 = KICK|BAN|MANAGE_MESSAGES|MENTION_EVERYONE) and the human owner is someone else:

  1. Bot calls Member::ban().
  2. SDK returns Ok(()); local DB shows banlist = ["<target>"] and server_root_epoch advances.
  3. Armada's audit log shows the ban was not applied; the target is not banned.

Confirmed live on 2026-08-02: automod: ban succeeded, server_root_epoch = 1, banlist populated locally — and the Armada client showed no ban.

Ask

Cut a vector-core / vector_sdk release containing the citation fix. Happy to test a prerelease against a real bot deployment if that's useful.

I recognise main has moved well past 0.4.0 (active_signer(), seal_control_edition_signed()), so a release may be gated on other work — if there's a preferred branch or tag to build against in the meantime, that would help too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions