Files
buzz/desktop
Duncan 936c1009ee feat(desktop): move persisted secrets from JSON into keyring via gen-ref protocol
All three secret tiers (global env vars, per-agent env/auth_tag/
provider_config, definition env vars) now move from plaintext JSON
into the existing SecretStore keyring blob using an immutable
generation-reference protocol:

  - Each write creates a new immutable generation entry under a UUID-
    keyed coordinate (e.g. agent:<pubkey>:env:<gen>). The stripped JSON
    carries a non-secret *_ref field; the atomic JSON write is THE commit
    point.
  - Crash before JSON commit: old ref stays authoritative, orphaned gen
    is swept by GC. Crash after: new ref is authoritative, old gen swept.
  - Empty vs unavailable distinguished by ref presence: no ref = field
    intentionally empty (agent runs); ref present but entry missing =
    unavailable, fail closed (nsec-style refusal).
  - Inline precedence: on keyring write failure (Windows TooLong /
    backend error) value stays inline in 0o600 JSON with a named warning
    and the ref is cleared. Inline is authoritative over any keyring state
    for that boot; extraction retries next boot.
  - Two-cycle GC: sweep 1 marks unreferenced generations as candidates in
    the blob; sweep 2 (next verified boot) deletes still-unreferenced
    candidates. Saves cancel their generation's candidacy before the JSON
    commit. GC is a no-op when either JSON store is absent, unreadable,
    or changes between reference collection and blob mutation.
  - Boot migration runs at the end of run_boot_migrations_inner (after
    materialize_agent_runtimes) so raw-JSON migrations see inline values.
  - OSS keyringless builds are unchanged (inline 0o600 JSON).

Coordinates:
  global:env:<gen>
  agent:<pubkey>:env:<gen>
  agent:<pubkey>:auth_tag:<gen>
  agent:<pubkey>:provider_config:<gen>   (entire BackendKind::Provider.config)
  definition:<id>:env:<gen>

Files changed:
  secret_store.rs              — add remove_keys() for batch blob deletion
  managed_agents/mod.rs        — expose secret_projection module
  managed_agents/secret_projection.rs — new: full gen-ref protocol impl + tests
  managed_agents/types.rs      — add auth_tag_ref, env_vars_ref, provider_config_ref
  managed_agents/global_config — add env_vars_ref, hydrate-on-load/strip-on-save
  managed_agents/storage.rs    — hydrate/strip seam, migration helpers
  migration.rs                 — boot migration + two-cycle GC
  commands/agents.rs           — new ref fields initialised to None
  commands/personas/snapshot/import.rs — same
  commands/team_snapshot.rs    — same

Deferred (noted in PR body, not a separate issue): existing nsec blob
(~2.8 KB) already exceeds the Windows 2,560-byte cap — pre-existing,
same accepted-risk class as the overflow path added here.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-08-10 11:48:43 -04:00
..
2026-08-03 21:51:17 -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