block / block/buzz

buzz-acp: dynamic subscription replays from the membership notification timestamp — messages sent before the notification is processed are silently dropped

Open
#4,564 1 comment 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.