buzz-acp: dynamic subscription replays from the membership notification timestamp — messages sent before the notification is processed are silently dropped
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
**Describe the bug**
When `buzz-acp` receives a `KIND_MEMBER_ADDED_NOTIFICATION` for a channel it isn't yet subscribed to, it subscribes with a replay floor equal to the **notification event's own `created_at`**:
```rust
// crates/buzz-acp/src/lib.rs (main @ ac4fa13b8)
let ts = buzz_event.event.created_at.as_secs(); // line 1914
...
if let Err(e) = relay.subscribe_channel_from(ch, filter, Some(ts)).await { // line 1971
```
`replay_since` is stored as the channel's `subscribe_since` (`relay.rs:1268-1275`), and `channel_since()` (`relay.rs:1128`) uses it as the `since` of the NIP-01 REQ. So any event whose `created_at` is **older than the membership notification** is excluded relay-side and never delivered — silently: no log line, no 👀, no reply.
In practice this drops any message posted between channel creation and the moment the notification is processed. For DMs this is the common case: the sender creates the channel and immediately sends their first message, and that first message — often the only one carrying the `p`-tag mention that `subscribe=Mentions` requires — falls inside the blind window.
The doc comment on `subscribe_channel_from` (`relay.rs:757-761`) says replaying from the membership event timestamp "closes that race", but it only closes the race for events **at or after** the notification's timestamp. Events between channel creation and the notification remain permanently invisible.
**Steps to reproduce**
1. Run a managed agent with `subscribe=Mentions`.
2. From another client, create a new DM channel with the agent and immediately send a message that `p`-tags the agent (before the harness processes the member-added notification — in the wild the relay's notification `created_at` can trail the first message by several seconds).
3. The harness logs `membership notification: subscribing to new channel` and subscribes with `since` = the notification's timestamp.
4. The first message predates that `since` and is never delivered. No error, no delivery, no reaction.
Reproduced live on 2026-08-03 (times UTC):
| Time | Event |
|---|---|
| ~16:52:3xZ | DM channel `892b1bd8` created |
| 16:52:34Z | Owner's first message arrives on the relay, correct `p`-tag on the agent's pubkey |
| 16:52:41Z | Harness processes the member-added notification and subscribes with `since` past 16:52:34 |
| — | Agent never sees the 16:52:34Z message |
The message is stored on the relay and readable via the CLI; the agent is a channel member; the filter and allowlist are satisfied. Later messages in the same channel are delivered normally — only the pre-notification window is lost.
**Expected behavior**
Every event posted to a channel from the moment the agent became a member (in a DM: from channel creation) should be delivered once the subscription is established.
**Suggested fix**
Subscribe from the **channel's `created_at`** instead of the notification's `created_at` — or, if the channel creation time isn't available at that point, from `ts - LOOKBACK` for a small fixed lookback window (e.g. 60s). Over-replay is safe: the existing dedup layer (`dedup=Queue`) already drops events the harness has seen, so widening the replay window can't double-deliver.
**Version and platform**
- Buzz version: 0.5.3-dev (source build, `main` @ ac4fa13b8)
- OS: Windows 11 Pro (10.0.22631)
- Harness: `buzz-acp`, `subscribe=Mentions`, `dedup=Queue`
**Logs / additional context**
Related but distinct: #4452 reports dynamically subscribed channels that deliver **nothing at all**, including events posted well after the subscribe — a different mechanism (fire-and-forget subscribe latching as success). This issue is a bounded blind window that exists even when the dynamic subscription itself works: events **before** the notification's timestamp are structurally excluded by the `since` filter. Fixing #4452 alone would not recover the 16:52:34Z message above.
Contributor guide
Research direction
Start by tracing the subscription flow in crates/buzz-acp/src/lib.rs around lines 1914 and 1971, then read relay.rs at channel_since(), subscribe_channel_from(), and lines 1268-1275. Reproduce the pre-notification message case or inspect the existing dedup=Queue behavior. Done means events posted from channel creation or membership are replayed after dynamic subscription without duplicate delivery.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100