Skip to content

vector_sdk 0.7.1: private channels work — two gaps that still make a granted bot look mute #83

Description

@ngmisl

vector_sdk 0.7.1: private channels work — two gaps that still make a granted bot look mute

Follow-up to #82, which 0.7.0 closed. First: it works. Verified live today against a
Concord v2 / Armada community, in this order — enumerate (Community::channels() with
is_private() / is_readable()), admin grants access, key vends and is adopted, history
back-fills, a live message arrives on the private plane and the bot replies, and the bot
can send into the channel by id. Nothing below asks for that to change.

Two things still make a correctly granted, correctly running bot indistinguishable
from a broken one, and they compose badly. Both cost us hours today, after the upgrade.

1. Back-filled messages never reach the message handler

When the vended key is adopted, follow calls VectorCore::v2_backfill_channel(...) and
then handler.on_channel_keyed(...). The back-fill takes no handler argument, so the
messages it writes to local state are never dispatched — correct as a design (history is
not delivery), and invisible as a consequence.

From the operator's chair this is exactly the #82 symptom:

  • the bot is in the private channel and readable,
  • the client shows the question sitting in the channel,
  • the bot answers nothing, with no error,
  • and it stays that way forever, because the message it would answer is already history.

Only a new message sent after the grant reaches the handler. Nothing in the changelog
or the ChannelKeyed docs says so; the changelog says ChannelKeyed fires "so a granted
bot acts on the transition", which reads as though the transition hands you the room.

We only found it by noticing that the two messages in the channel had received_at
timestamps fifteen seconds after the key landed and a created_at from before it, while
our handler — which logs unconditionally on entry — had never been called.

Suggested fix, cheapest first:

  1. Document it, on BotEvent::ChannelKeyed and in the 0.7.0 changelog entry: "messages
    that predate the grant are back-filled to local state and are NOT delivered to your
    handler; ask the sender to re-send." One sentence would have saved the whole hunt.
  2. Give a bot a supported way to read what was back-filled — e.g.
    Channel::history(limit) on the SDK. v2_backfill_channel is core-only, so today an
    SDK consumer has no way to see the messages it can prove are in its own database.
  3. Optionally, carry the count on the event: ChannelKeyed { .., backfilled: usize }.
    "You were handed 2 messages you will never be called for" is the whole diagnosis.

2. A cold start has a window with no v2 community subscription, and no signal for it

listen() calls community::v2::realtime::refresh_subscription at startup, but phase 1
of that function waits up to ~6s for a relay to connect and then primes stream AUTH across
every community relay. Several of ours time out or refuse AUTH. V2_SUB_SET is only
assigned in phase 2, after that gauntlet.

Measured on a cold start against our real relay set (six relays, several dead or
AUTH-gating):

t after listen() subscribed_author_set()
0s … 60s empty
≤ 95s registered (a live message was delivered)
360s populated, stable

So for at least the first minute the bot holds no v2 subscription at all — it is
genuinely deaf to community traffic, not merely unreported. The only public observable is
subscribed_author_set(), and during that window it is empty, which is also what it
returns when nothing is subscribed at all. A bot sampling it early cannot tell
"still connecting" from "subscribed to nothing".

Suggested fix: emit a BotEvent when the community subscription registers (or expose
a subscription_ready() / Instant of last successful refresh_subscription). A bot that
wants to log its own health has nothing else to read.

Why the two compose

A message sent inside the startup window is not delivered live, and when it is later
back-filled it is not dispatched either. So it is never seen by the bot — not late, never.
We did not reproduce that specific loss (the messages we lost were lost to the keyless
case in §1), but it follows from the two behaviours above and is worth closing.

Environment

vector_sdk 0.7.1, vector-core 0.6.1, Rust, Linux. Concord v2 community, protocol 2,
one private channel at epoch 2 granted to the bot by an admin.

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