You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Sidebar channel sections are per-user only — no way to share a section layout across a team #5469
Sidebar channel sections are a per-user construct. channelSectionsSync.ts filters kinds: [KIND_CHANNEL_SECTIONS], authors: [this.pubkey], so a section layout never
leaves the person who made it.
For a team using Buzz for real project work this is the blocker. We run a self-hosted
relay for a small company (design/AV projects). Each project gets a set of channels — <project>-design, -quotes, -logistics, -email and so on. One person scaffolds
the project, and every other member then has to recreate the same grouping by hand, one
project at a time. New channels created by a colleague appear ungrouped for everyone
else. In practice people stop grouping at all and the sidebar becomes a flat list of
hundreds of channels.
Proposal
A shared, read-only base layer, with the personal layer kept as an overlay:
A designated org/steward identity publishes a sections document in the existing shape.
Clients additionally subscribe with authors: [ORG_PUBKEY] and merge: shared sections
first, personal sections after; a personal assignment or same-id section wins.
Writes are unchanged — a user only ever publishes their own document.
If no org pubkey is configured, or the document is missing/invalid, behaviour is
exactly as today.
UI hides rename/delete/reorder on shared sections (a per-user "hide" would be fine).
One constraint worth flagging
Personal documents are nip44EncryptToSelf-encrypted, so another author's document
can't be decrypted by anyone else. A shared document therefore needs plaintext content
(still signed by the org identity), or a group-encryption scheme if that's preferred.
That choice seems like a maintainer call, which is why I'm raising an issue rather than
opening a PR.
Willing to contribute
We're building this for our own deployment now and are happy to submit it as a PR if the
approach above is one you'd accept — or to rework it to whatever shape you prefer.
Following up with results, since we went ahead and implemented this downstream. It has been running in production for a week, so here is what we found in case it is useful to the upstream design.
What we built - client-side only, no relay changes, on top of 119a848:
A steward/org identity publishes a single kind-30078 sections document. Clients subscribe to their own sections exactly as today and additionally with authors: [ORG_PUBKEY], then merge org-base under personal-overlay: org sections are read-only, a personal section with the same id wins, and a personal channel assignment beats the org one. ORG_PUBKEY is a build constant (VITE_BUZZ_ORG_PUBKEY); when it is unset or malformed the client behaves exactly as upstream does today.
Two files changed, one added:
desktop/src/features/sidebar/lib/useChannelSections.ts - shared-layer state, merged output, sharedSectionIds
desktop/src/features/sidebar/lib/channelSectionsStorage.ts - stop stripping a personal assignment that targets an org section
desktop/src/features/sidebar/lib/sharedChannelSections.ts (new) - reads the org document and merges; never writes or republishes anything
The design constraint worth flagging: the shared document has to be published in plaintext. channelSectionsSync.ts uses nip44EncryptToSelf / nip44DecryptFromSelf, so a document published in the personal shape is undecryptable by anyone else. We lost time before spotting that. Any upstream implementation will need a separate unencrypted (or differently-keyed) path for a shared document.
The bug that cost us the most, and which you may want to fix independently of this feature: the relay rate-limits a client's startup query burst - rate-limited: quota exceeded; retry in 5s. Our first implementation did a single fetch on mount and swallowed the error, so the shared layer stayed empty forever and the feature appeared simply not to work. The fix is retry-with-backoff plus refetch on reconnect, which is what the personal sections path already does. If any other startup subscription in the app does a one-shot fetch, it has the same latent failure - that part is worth a look regardless of what happens to shared sections.
Status: in daily use by a small team since 11 August. We deliberately kept our build's version string identical to upstream so it upgrades in place and users stay signed in.
Happy to open a PR if you want it - either the whole feature, or just the rate-limit retry fix if shared sections are heading in a different direction. Equally happy to leave it downstream if you would rather own the design. No expectations either way.
Activity
obsidianaddict commentedon Aug 18, 2026
Following up with results, since we went ahead and implemented this downstream. It has been running in production for a week, so here is what we found in case it is useful to the upstream design.
What we built - client-side only, no relay changes, on top of 119a848:
A steward/org identity publishes a single kind-30078 sections document. Clients subscribe to their own sections exactly as today and additionally with authors: [ORG_PUBKEY], then merge org-base under personal-overlay: org sections are read-only, a personal section with the same id wins, and a personal channel assignment beats the org one. ORG_PUBKEY is a build constant (VITE_BUZZ_ORG_PUBKEY); when it is unset or malformed the client behaves exactly as upstream does today.
Two files changed, one added:
desktop/src/features/sidebar/lib/useChannelSections.ts - shared-layer state, merged output, sharedSectionIds
desktop/src/features/sidebar/lib/channelSectionsStorage.ts - stop stripping a personal assignment that targets an org section
desktop/src/features/sidebar/lib/sharedChannelSections.ts (new) - reads the org document and merges; never writes or republishes anything
The design constraint worth flagging: the shared document has to be published in plaintext. channelSectionsSync.ts uses nip44EncryptToSelf / nip44DecryptFromSelf, so a document published in the personal shape is undecryptable by anyone else. We lost time before spotting that. Any upstream implementation will need a separate unencrypted (or differently-keyed) path for a shared document.
The bug that cost us the most, and which you may want to fix independently of this feature: the relay rate-limits a client's startup query burst - rate-limited: quota exceeded; retry in 5s. Our first implementation did a single fetch on mount and swallowed the error, so the shared layer stayed empty forever and the feature appeared simply not to work. The fix is retry-with-backoff plus refetch on reconnect, which is what the personal sections path already does. If any other startup subscription in the app does a one-shot fetch, it has the same latent failure - that part is worth a look regardless of what happens to shared sections.
Status: in daily use by a small team since 11 August. We deliberately kept our build's version string identical to upstream so it upgrades in place and users stay signed in.
Happy to open a PR if you want it - either the whole feature, or just the rate-limit retry fix if shared sections are heading in a different direction. Equally happy to leave it downstream if you would rather own the design. No expectations either way.