Skip to content

feat: emit a system message when a channel is renamed #5618

Description

@AaronGoldsmith

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 noneupdate_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 <id> --topic "control probe" ← control
  3. buzz channels update --channel <id> --name rename-probe-renamed
  4. buzz messages get --channel <id> --kinds 40099

Result — exactly two events:

{"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":"<hex>","name":"<new>","previous_name":"<old>"} 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 (feat: Slack-parity per-channel notification settings — levels, temporary mute, mute-and-hide, broadcast opt-out #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:

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions