feat: emit a system message when a channel is renamed
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
**Motivation**
A channel rename leaves no trace in the channel. Members see the sidebar label change with no record of who changed it, when, or what it was called before — and threads, links, and docs referencing the old name become quietly wrong with nothing in the room to explain it.
This is inconsistent rather than intentional. `handle_edit_metadata` (`crates/buzz-relay/src/handlers/side_effects.rs`, main `4b3570671`) already emits a `kind:40099` system message for every other privileged metadata tag:
| kind:9002 tag | system message |
|---|---|
| `topic` | `topic_changed` (:1471-1485) |
| `purpose` | `purpose_changed` (:1486-1500) |
| `visibility` | `visibility_changed` (:1501-1538) |
| `ttl` | `ttl_changed` (~:1562) |
| `archived` | `channel_archived` / `channel_unarchived` (~:1579, ~:1594) |
| **`name`** | **none** — `update_channel(name:)` and nothing else (:1444-1456) |
| **`about`** | **none** — same silent path (:1457-1470) |
Rename and description are the only two edits that mutate persisted channel state without narrating it.
**Verified at runtime, not just read**
Against a hosted relay on current main, using only supported CLI paths:
1. `buzz channels create --name rename-probe --visibility private --type stream`
2. `buzz channels topic --channel --topic "control probe"` ← control
3. `buzz channels update --channel --name rename-probe-renamed`
4. `buzz messages get --channel --kinds 40099`
Result — exactly two events:
```json
{"actor":"…dabf","type":"channel_created"}
{"actor":"…dabf","topic":"control probe","type":"topic_changed"}
```
`buzz channels get` confirmed `"name":"rename-probe-renamed"`, so the rename applied and the DB row was updated. The control (`topic_changed`) proves the emit path is healthy in the same channel, same session, seconds apart. No `name_changed` event exists to miss.
**Proposed solution**
Emit `{"type":"name_changed","actor":"","name":"","previous_name":""}` from the `name` arm, and render it in both clients.
Three touch points, all already-established patterns:
1. **Relay** — add an `emit_system_message` call to the `name` arm of `handle_edit_metadata`. `previous_name` needs the pre-update read; the `visibility` arm at :1502-1507 already does exactly this (`get_channel` before `update_channel`) so the shape exists. Drop `previous_name` if maintainers would rather not add a read.
2. **Desktop** — one `case "name_changed"` in the `SystemMessageRow.tsx` switch (`case "topic_changed"` at :573 on main) and a `name`/`previous_name` field on `SystemMessagePayload`.
3. **Mobile** — one arm in `SystemEvent.fromContent` (`timeline_message.dart:56` on main) plus the enum variant and row rendering.
`kind:40099` is already in the known-kinds list (`crates/buzz-core/src/kind.rs:437`, `KIND_SYSTEM_MESSAGE`), so no protocol surface changes.
**Open questions for maintainers**
- Include `previous_name`? It's the part that makes the message genuinely useful ("renamed #old-name to #new-name") and costs one read that a sibling arm already pays.
- Should `about` get the same treatment? Same silent path, weaker case — a description edit is less likely to break references. Happy to scope this to `name` only.
- Should it push-notify, or timeline-only? Other `40099` types are timeline records; I'd keep parity and not add a push, but per-channel prefs work (#3160) may have an opinion.
**Alternatives considered**
- *Client-side diffing of kind:39000 group metadata* — clients can already see the name change on the replaceable event. Rejected: it produces no durable, attributed record, so anyone scrolling back later still can't tell who renamed it or when, and each client would have to reimplement the inference.
- *Do nothing* — defensible if maintainers consider rename low-signal. But then `topic_changed` and `purpose_changed` are arguably over-notifying, and the current split is hard to justify either direction.
**Additional context**
Searched all 1207 issues (open + closed) and all 4397 PRs — no duplicate. Closest related, all distinct:
- #4739 / PR #5243 — group DMs cannot be renamed at all (authorization, not notification).
- #2797 — community name is device-local, never syncs from relay.
- #1823 — agent rename doesn't notify running agents mid-session.
- #3160 / PR #3233 — per-channel notification settings (delivery preferences, not event emission).
Contributor guide
Assessment
This issue has not been assessed yet.