Files
buzz/desktop
Wes 8953cbfff5 fix(desktop): keep managed agent avatars usable across communities (#7732)
## Summary

Fix Desktop-managed agents losing avatars after joining another
community. The saved persona/instance stores one desired source URL, but
authenticated media belongs to a community. Republishing community A’s
URL in B does not make that image accessible in B.

- Before comparing or publishing kind-0, reuse or copy
configured-community avatar media into the pinned destination. Keep
exact image bytes, including animation, and leave the saved source
unchanged.
- Keep the previous profile on transfer/publication failure so existing
reconciliation can retry. Reuse destination bytes during source outages;
after source removal, reuse only an already-published signed destination
picture with the same original content hash.
- Refresh source permissions through narrow, serialized IPC without
reconnecting or resetting the active community. Startup waits until the
latest permission update completes before restoring agents.

### Related issue

Refs #2366 (avatar portion only, not runtime availability). Related
#2659 deliberately excludes avatar/media mirroring; this change
addresses that media boundary without introducing runtime fan-out.
Searched existing issues/PRs for `avatar community` before opening.

## Contract and safety

Desktop-managed profiles still follow the saved persona source; this
does not introduce community-specific persona editing. Agent-managed
profiles still opt out of automatic reconciliation.

Authenticated transfer requests use the fixed agent key/NIP-OA tag,
origin-scoped Blossom auth, and the pinned destination, never mutable
active-workspace owner credentials. They refuse redirects, enforce
30-second request timeouts and bounded bodies, verify SHA-256 and
detected image MIME, and validate the returned descriptor’s
origin/hash/MIME/size. Source permission is rechecked after an awaited
destination HEAD miss. The removed-source fallback verifies the
destination profile’s signature, kind, signer, origin, and
original-media hash without contacting the removed source.

Ordinary external images retain passthrough behavior and receive no
community credentials. No public-media policy change, image-reader URL
rewriting, new persistence, background service, or global profile merge.

## Testing

Normal commit and push hooks passed on exact head
`925781eece66d5f6a4b084b3b3abd6309cda357e`; working tree clean before
and after:

- Desktop formatting/lint, typecheck, and **6,508 tests**.
- Full native workspace suite, including **3,204 desktop-library tests**
(19 ignored), integration tests, terminal crates, and doc tests.
- Native Clippy on default and `mesh-llm` workspace/all-target
configurations with warnings denied; repository file-size and
branch-skew gates.

Regression coverage exercises production reconciliation/shared
publication against two local HTTP fixtures: add/edit/restart, upload
and rejected-publication retry, removed-source local-image preservation,
fixed signer/destination, redirect/hash/descriptor/size failures,
revocation during pending HEAD, and opt-out no-I/O. Mounted
initialization tests cover inactive-list changes without workspace
reset, two deferred permission updates, and rejection of either update.

Earlier working-tree validation at base
`4ab4f786085a23fe6126529861840eff6048ceee` also passed the E2E frontend
build and four Chromium mock-bridge community flows (boot, switch,
active removal/fallback, leave-final/setup). Subsequent production
changes only serialize permission writes and wait for a stable latest
update; the complete suites above cover the final commit. Mutations
independently removing serialization or stable waiting failed the new
regression.

## Remaining validation and limitations

- No live production avatar was changed. Native GUI rendering against
two hosted communities remains to be verified with a build containing
this fix; local HTTP fixtures and the browser mock bridge do not
establish that outcome.
- A removed/unreachable source with no existing destination copy cannot
be recovered automatically. Choose a reachable image/source in that
case.
- This is a publication/reconciliation fix, not a visual redesign. No
before/after native GUI screenshots are claimed. Broad repository CI
remains required; it was not duplicated locally.

## Review

Independent security/scope and caller/ordering reviews are clear after
the bounded fixes. Final hook-ordering reread covered the staged tree
that became this commit. Commit authorship/sign-off use the implementing
Carl identity and configured Carl signing key.

Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
2026-09-18 06:14:28 -06:00
..
2026-03-09 13:02:11 -07:00
2026-06-11 15:06:24 +00:00
2026-03-09 13:02:11 -07:00

Buzz

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 frontend
  • pnpm tauri dev - run the desktop app
  • pnpm build - typecheck and build frontend
  • pnpm typecheck - TypeScript checks
  • pnpm lint - Biome lint
  • pnpm 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