block / block/buzz

feat: multiparty / per-participant read receipts for messages

Open
#3,000 4 comments 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

## Summary
Add first-class, per-participant read/consumption receipts so it is verifiably known which
participants (humans **and** agents) in a channel/DM have received — and, distinctly, have
**processed** — a specific message.

## Problem
There is currently no attributable, auditable way to know whether a given participant has
consumed a message. For human+agent teams this is the core coordination primitive:

- A sender cannot distinguish "delivered," "seen," and "acted on" — so coordination degrades
to re-pinging or to agents polling for changes, which is wasteful at scale.
- There is no way to know an agent has actually ingested context before depending on it.
- Accountability in multi-party threads is asserted, not verifiable.

## Desired Behavior
- **Two receipt classes, both first-class:**
1. **Rendered** — a participant's client displayed the message (the human semantic).
2. **Processed** — the participant attests it has consumed the message (read into context /
acted upon). For agents this is published by the agent or its harness at processing time,
with no dependency on any UI or "active view" — headless and API-driven consumers are the
primary case, not an edge case.
- Receipts are **signed events attributable to the participant** (or its delegated key), and
**append-only**: a receipt is never deleted or mutated; corrections are superseding events.
- UI can render "Read by: Alice, Bob, Agent-X" / "Processed by 3/5" with an expandable list.
- Works in channels and DMs.
- **Enables sender-side policy:** because read-state is queryable, senders can implement
escalation ("unprocessed after T → re-notify / escalate") and gating ("proceed only after
X has processed Y") — replacing both blind re-pings and consumer-side polling loops.
- Privacy controls: participants can disable emitting receipts per-scope (channel/DM), with
the trade-off visible to counterparties (a participant with receipts off reads as
"unknown," never as "read").

## Open Questions
- Event kind: new NIP vs. extension of existing kinds; one kind with a `state` tag
(rendered|processed) vs. two kinds?
- Visibility: receipts public to the channel vs. visible only to the message author
(+ admins)? Per-scope configurability?
- Idempotency/dedup expectations for relays when the same receipt is republished.
- Retention/expiry — and whether expiry is compatible with auditability requirements.

## Motivation
Teams of humans + agents live or die on knowing what has actually been consumed. Today that
knowledge is either faked (assumed from delivery) or bought expensively (polling). Making
consumption a signed, append-only protocol citizen turns coordination from assertion into
verification — and makes multiplayer agent collaboration on Buzz practical at team scale.

Contributor guide

Open the contributing guide

Research direction

No files or tests are named. Start by resolving the open questions around event kind, visibility, idempotency, and retention, then map the existing message, channel/DM, relay, UI, and API paths. Done means a decided protocol design covering signed append-only rendered and processed receipts, privacy behavior, and sender-side queries.

Written by the indexing model from the issue text.

Assessment

Domain
backend-api-design, distributed-systems, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.