## Summary Removed private-channel members can currently download attachments if they know the URL. With `BUZZ_MEDIA_READ_MODE=enforce`, fresh GET, HEAD and Range requests check current membership and readable references on the primary database. Removed members receive 404; remaining members retain access, and rejoining restores access. Thumbnail aliases use the parent attachment’s permissions. Publication checks also prevent copied private URLs from granting new access. They cover attachments, link previews, profile pictures, banners, group pictures and emoji. Persona creation and changed-avatar edits, plus team and individual snapshot imports, transfer animated posters and animations under the agent’s signer before profile publication. Failed persona transfers preserve existing local records; import failures appear in the results. Authorization uses bounded queries, a two-second statement deadline and transaction-local JIT suppression. An index on edit targets avoids broad scans. Publications have a 512-reference limit, and capacity waits up to 500 ms before refusal. Protection defaults off. Existing downloaded bytes cannot be recalled. All modes stop creating immutable HTTP cache entries. ### Related issue Related approaches: #7565, #5185, #8451 and #8444. This change evaluates live stored references directly. ### Testing Published head: `3d1aa7431cc495a001a0f13e95e2e422c5a77ab1`, rebased on main `2cd40badb85de059a6916206e133da7a0a88fb2e`. Push hooks were **SKIPPED** with explicit author approval. Current-head HTTP, full package, PostgreSQL migration/media and profile-filter mutation checks are pending; CI is pending. The earlier complete HTTP journey passed at `f20b449262` (identical source tree), with its evidence attributed separately. Earlier failing preview/report-fixture runs are preserved; they do not count as passes. The HTTP journey covers upload/publication, fresh GET/HEAD/Range revocation and rejoin, emoji replacement, edited previews, persona visibility and non-reference decoys. The migration regression forces an index timeout, verifies no 0086 history or media tables, then proves a migrator through the base's 0085 can restart. Human attachment removal/rejoin testing passed on the pinned `1f08a8e0fd2edf19dc94321f7258518149fe1bf6` trial. Native animated persona edits and team/individual import acceptance remain incomplete. That old-snapshot database stays intact and cannot run the reconciled binary; a new trial needs a separate fresh database. ### Rollout prerequisites - Build and verify the reference index before shadow mode. Small databases can auto-migrate through one atomic 0086 migration within the configured timeouts. It builds the index before creating the media tables, so failure records no new migration version. Large deployments must disable auto-migration and prebuild indexes concurrently. - **Enforce remains blocked unless the operator can rule out SDK/CLI attachment edits and the unverified agent-harness edit producer.** SDK/CLI edits still omit attachment metadata. That behavior is deferred, not fixed. Removing this blocker requires latest-effective attachment metadata across successive edits, no restoration of removed files, and an upload → successive edits → GET/HEAD regression. - Validate client signer compatibility and split emoji publications above 512 references before enforce mode. - Complete the human workflows above in an isolated community with enforce enabled. - Follow the [index deployment guide](https://github.com/block/buzz/blob/honor/private-channel-media/docs/private-media-index-deployment.md) and [operator guidance](https://github.com/block/buzz/blob/honor/private-channel-media/docs/operator-private-media.md) for rollout and rollback. The [prebuild timeout finding](https://github.com/block/buzz/pull/9077#discussion_r4486221478) and [avatar-transfer finding](https://github.com/block/buzz/pull/9077#discussion_r4486221458) are implemented and independently reviewed. ### Schema change checklist - [x] Additive expand and code deployment; no backfill or contract phase. Prebuild/verify before shadow under either schema deployment path. - [x] No SQL function, trigger, procedure, rule or foreign key added. Signed events are untouched. - [x] No migration mutates existing rows. - [x] Migration and desired-state schema match. Catalog parity, target parsing, future partition inheritance and upgrade refusal are covered. - [x] Old/new binaries coexist for serving. Suspend community deletion during expansion and while rolled back to a binary with the old deletion catalog. - [x] Keep auto-migration disabled on old binaries after schema expansion; sqlx rejects unknown versions. - [x] Migration lock timeout 1 s; statement timeout 5 s. Small populated databases build inline within those budgets; large deployments use concurrent child-index prebuild/attachment with auto-migration off. Missing, invalid or wrong indexes fail verification. Generated with Codex --------- Signed-off-by: Brad Seiler <seiler@squareup.com> Co-authored-by: Honor <e0bf479eeebe47dde1e35705212a4df70616a7bc834d907ddfb18cf0405f8b1b@seiler-test.communities.public.builderlabstaging.xyz>
Buzz
Important
This is the deprecated Buzz 0.X desktop app. Buzz 1.0 lives in block/buzz-app. Build new desktop features there. Change this directory only to fix a 0.X bug, or to keep it compiling after a shared crate change.
Desktop chat shell with:
- Tauri + React + TypeScript + Vite
- Tailwind CSS
- shadcn/ui-ready shared components
- Biome (lint/format/check)
- Feature-driven frontend structure
Scripts
pnpm dev- run the web frontendpnpm tauri dev- run the desktop apppnpm build- typecheck and build frontendpnpm typecheck- TypeScript checkspnpm lint- Biome lintpnpm format- Biome format (write)pnpm check- Biome check
Structure
src/shared- reusable app-wide code (ui,lib,styles)src/features- feature modules (vertical slices)src/app- top-level app composition
Required-community guidance in the legacy app
The legacy desktop reads public NIP-11 metadata before each WebSocket connection.
Only requires_nip_fi: true shows the upgrade card. Missing/false requirements
keep the existing connection flow. Discovery failures retain an unknown-policy
state and continue the existing socket/authentication path; the relay enforces
admission. Query/fragment URLs keep their existing socket behavior; the native
discovery reader rejects them before making an HTTP request. Credentials never
reach a fallback dial. Only explicit required policy opens the upgrade modal. Switching
communities invalidates pending checks. The card does not
reset keys or remove saved communities.
The upgrade card directs public users to the fixed https://buzz.xyz URL to
download an up-to-date Buzz client on every supported desktop platform and for
every required community.
If the browser cannot open, the card shows the public URL for manual navigation.
Discovery never supplies a trusted download or sign-in origin.