Files
buzz/desktop
npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7andWill Pfleger 7fe049359c feat(desktop): add workspace-scoped agent definition store scope model
Introduce the `WorkspaceAgentScope` type and the scaffolding for a
four-stage workspace transition state machine (Phase 1 foundation).

## Scope model (managed_agents/scope.rs)

- `WorkspaceAgentScope { scope_id, relay_url, owner_pubkey, definitions_dir,
  generation }` — the single scope authority for a workspace's agent
  definition store. Immutable; callers capture one scope at operation
  entry and thread it through `_at(scope)` APIs.
- `derive_scope_id(relay_url, owner_pubkey)` — the canonical sha256
  derivation, byte-identical to the retention DB derivation. Both
  subsystems now go through one shared helper so "same scope" can never
  disagree between definitions and retention.
- `next_scope_generation()` / `current_scope_generation()` — global
  monotonic counter incremented on every scope change or identity-import
  clear. Long-running operations read at entry and revalidate before
  commit; a stale commit aborts.
- `WorkspaceApplyResult { applied, degraded }` — typed result for the
  four-stage transition machine (prepare / drain / commit / post-commit).
- Scoped layout: `agents/scopes/<scope_id>/{managed-agents.json,
  teams.json, global-agent-config.json}`.

## AppState additions (app_state.rs)

- `identity_mutation: AsyncMutex<()>` (was `Mutex<()>`) — Layer 1 async
  lock; callers may `.await` while holding it. Converted so the workspace
  transition machine can hold it across awaits without blocking the
  executor.
- `workspace_transition: AsyncMutex<()>` — serializes workspace
  transitions (`apply_workspace` and live identity import). Lock order:
  identity_mutation → workspace_transition → Mesh rearm → mesh_llm_runtime.
- `active_agent_scope: Mutex<Option<WorkspaceAgentScope>>` — `None` from
  boot until the first successful `apply_workspace`. Every agent command
  fails closed on `None`; there is NO fallback to the legacy unscoped root.

## Retention parity (retention.rs)

- `scoped_retention_db_path` now delegates to `derive_scope_id` instead
  of inlining its own sha256, making the hash provably identical.
- `scope_for_arrival` / `arrival_retention_scope` extended to match on
  both relay AND owner pubkey. An in-flight old-owner event on the same
  relay can no longer land in the new owner's active store after an
  identity switch.

## Inbound reconcile (commands/personas/inbound.rs)

- Both `arrival_retention_scope` call sites pass the event's pubkey as
  the owner dimension, closing the identity-switch cross-contamination gap.

## Caller updates

- `identity.rs`: three `identity_mutation.lock().map_err()` callers
  converted to `.blocking_lock()` (Tokio async mutex's sync-context
  variant, safe from `spawn_blocking` threads).
- `identity_key_backup_tests.rs`: test thread mirror updated to match.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-08-02 22:45:00 -04: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