The Agents page uses one app-owned native controller for creating, importing, editing and running local agents. Inventory cards join records by exact public key; managed actions remain keyed by native identity/community record. Browser-only access keeps the read-only old library; it cannot run agents. The only product entry point is ordinary desktop startup.
Run from the feature worktree with bin/just desktop, not a management-only
launcher. The command prepares the pinned agent runtime before starting Tauri;
the first build may take several minutes. Later launches verify and reuse matching
resources, rebuilding missing, stale or corrupt ones. Preparation failure stops
launch rather than opening a desktop that cannot run agents. This opens Buzz Foundation using the ordinary live-development
configuration and persistent native settings. Coordinate the native rebuild/relaunch;
quit other Foundation copies first. Saved enabled agents can restore on startup.
Keep imported agents disabled and old Buzz running until an attended handover.
Open Agents for discovered and imported identities grouped by known community associations. Compact individual-agent cards open View profile on click, without expanding the grid. The three-dot menu keeps Manage agent, Edit, Duplicate, and Delete separate. Manage agent opens the configured destinations’ Start / Stop, recovery, and identity/source controls in a dialog; it is also the card-click fallback when no profile panel is available. Closing Manage does not cancel Start/Stop or discard its failure reason. Reopening retains that result until another action from Manage or Edit, or an observed process-status transition, supersedes it. Retained failures expose Review agent status on the card. Duplicate seeds Create with editable settings and a fresh identity; write-only environment values require re-entry. Delete stops the local process and removes this app's settings and Keychain key after confirmation. The key remains while another setup of the same identity still uses it. Delete does not archive the relay identity or erase messages. Deployed remote records are refused. Actions use native ID/revision, never the display name. Older hosts without parked inventory retain the Individual agents and collapsed read-only Other agents sections. Managed controls remain available when discovery is disconnected, unavailable or archived.
Create agent shares the Edit fields and model browser. In the development desktop, Create generates a native key, obtains the captured viewer's owner authorization, saves the agent, starts it, then publishes its profile. A failed Start or profile publication retains the saved identity and offers a retry for that step; it never creates another identity. A native Start response can confirm a saved agent while reporting that its process could not run. During Create, Start, or profile setup, Close leaves the operation running and keeps recovery Stop available through Manage agent. Late completion never closes a subsequently opened dialog. If an operation cannot be confirmed, refresh status before repeating it.
Create is blocked with an explanation if this app’s runtime is unavailable; existing agents and profile retry remain intact. Without the dev broker, the native identity signs the owner authorization only for the key this host prepared for the pending Create. Native owner-scoped community resolution is also available; other broker-only helpers remain unavailable. Packaged support still requires attended native acceptance.
New agents, including clones and duplicates, start with BUZZ_ACP_AGENTS=10 in
the existing Environment overrides. Replace or remove it there to choose the
worker count. With Each thread conversation context, separate threads can
use different workers while retaining separate histories. Existing saved agents
keep their settings; add the variable and restart them to enable more workers.
Pi and Goose apply permitted Environment overrides after saved fields and
imported settings. For example, BUZZ_ACP_MODEL, BUZZ_ACP_SYSTEM_PROMPT, and
BUZZ_ACP_AGENTS take precedence at launch; worker counts must be from 1 to 32.
Removing an override restores the saved/default setting. Identity keys, the relay
URL, executable commands, saved response policy, and team instructions remain
protected, along with specific host controls: session policy, presence, inactivity
exit, idle-pool sleep, setup payload, and replay floor. Pi and Goose still permit
subscription, relay observer, deduplication, and event-handling overrides, as old
Buzz did. Device-wide overrides are inherited only by harnesses that permit them;
BUZZ_ACP_MODEL also requires the same default harness. Buzz Agent keeps its key
restrictions; its worker override takes precedence over imported parallelism.
Pi model browsing and connection tests use the
Provider/Model fields; ACP overrides apply to the listener's sessions at launch.
Hermes Agent is an externally installed ACP harness. Settings → Agents →
Harnesses → Add harness shows executable availability and a manual setup
guide; Check again refreshes discovery. Buzz uses hermes-acp with no default arguments and does not
install Hermes or manage its provider credentials. Configure its default model
and sign-in with hermes model in your terminal. The agent form uses those
defaults and offers no Provider, Browse models or Test connection controls for
Hermes yet. Existing model/provider values remain visible for recovery: select
Use Hermes Agent defaults, then Save, before starting. Native launch rejects those
selectors, and Hermes does not permit BUZZ_ACP_MODEL environment overrides.
Saved executable paths survive detection refresh; choose the newly discovered
Hermes option explicitly to replace an old path. Device defaults and old-agent
import do not offer Hermes in this slice.
Clone to this community opens the existing creation dialog with only the old agent’s name and resolved instructions. Review that text for embedded secrets. Runtime settings and workspace use this app’s defaults and remain editable. Clone generates a new native identity; it does not copy identity keys, environment values, command arguments, paths, history or membership. Saving leaves the new agent stopped. The source is read-only and no legacy credential access occurs.
Import preserves the selected old-installation identity and private key. It requires an explicit destination and a fresh source/destination-bound preview. Successful import saves a configured, stopped setup and moves keyboard focus to the persistent card’s Review agent status button (or Actions for a row). It does not start a listener, invite an agent, or modify the source installation. An identity already held locally cannot be imported again into another community; use Clone instead. The native prepare and commit boundaries both enforce that exact-key rule.
The unified inventory offers Import only under Available to import, once per exact public key. Multiple old installations require an explicit source choice. The selected row opens the import review. Without a selected community, such as in Personal space, the review asks for the destination before it loads a fresh preview. Each startup reads every old installation again: an identity deleted from all of them, or whose installation is removed, leaves the list. A damaged source keeps its previous entries. Source read failures remain visible. Older hosts retain the separate installation browser as a compatibility path.
Use here is recovery for older incomplete local imports, not a normal next
step after Import. It retains the identity/key, requires owner-authorized community
confirmation, and leaves the recovered setup stopped with app-launch start off.
The development broker and the packaged desktop app both provide that
confirmation; the desktop app signs it natively (relay_agent_resolve). Native
code refuses a new
community when that identity already has a configured setup elsewhere. A retry
for the already recovered destination is harmless. Existing historical setups
remain visible and controllable; this rule does not move or delete them.
Local team-linked imports snapshot the deployment team's instructions from the
chosen library's agents/teams.json, alongside the resolved persona prompt.
The existing ACP team-instructions input receives that snapshot; later edits in
old Buzz are not synchronized. As in old Buzz, a deleted team or a directory-only
legacy binding without a deployment team ID contributes no team instructions.
Remote backends and relay mesh remain unsupported.
Older imports missing this snapshot show Import or repair from old Buzz. Choose their original source library and destination, then Repair team import. This adds only the missing team instructions and advances the saved revision; it preserves the identity, credentials, prompt, model, environment and enabled intent, and never starts/restarts an agent. Source changes or changed saved settings reject the repair. No Keychain read is needed for repair. Before Start, perform the same attended old-Buzz handover as for a fresh import.
To use an agent, open a channel and select it from @ mentions. Both mention menus include the selected community’s people directory alongside channel members and configured managed agents. Directory reads are bounded; narrow the search for more people. A nonmember is labeled Not in channel · Choose whether to add when you send. Selection alone does nothing. Send asks, as block/buzz desktop does: Invite or Do nothing. Without add permission, the only action is Send anyway. Invite uses the existing durable member-add operation and confirms membership before addressed delivery. It does not start an agent before the outgoing message. Do nothing and Send anyway send nonmembers as reference mentions, without granting access or notifying them; channel-member mentions remain addressed. Close or Escape keeps the draft. Failed additions keep the draft and allow retry of the same pending operation. A definitively failed addition older than 15 minutes must be dismissed in Outbox before a new add; unknown outcomes are never silently replaced. Channel, thread, and forum-channel composers share this behavior. DM participants and session admission rules are unchanged.
Once an identity is configured by Import or legacy Use here recovery, a confirmed outgoing channel or thread mention starts that exact local agent (public key + community), without a separate Start click. Import itself remains non-starting. Stop cancels earlier pending mention wakes and active work; a later deliberate mention can start the agent again. Plain name text without recipient selection, received history and unconfirmed sends do not start agents. Start failures appear separately as “Message sent, but…”; do not resend merely because execution failed. The old-Buzz ownership guard remains in force.
Mention startup carries the earliest relevant pending send timestamp into the bundled runner's existing replay input (bounded by its 15-minute catch-up limit). Already-running agents are not restarted. Mentions during queued or pending startup attach their earliest timestamp to that same launch, without another credential read or listener. Stop and changed saved revisions retire that input. If launch has already finished or the host cannot attach it, the send shows a separate replay warning instead of silently treating Waiting as Running. Attachment is not proof of delivery; a later credential/launch failure remains visible in Agents. Process state is not proof of a live reply; imported identities require old Buzz stopped before handover.
The focused Add/Edit dialog contains Name and Agent instructions, followed by AI configuration in dependency order: Harness → Provider → Model. Provider choices come from the selected harness; model discovery uses the current draft. Existing/custom values remain intact when another field changes. Workspace, arguments and write-only environment patches remain under Advanced; Start/Stop/Restart and exact identity are under Runtime and identity. Save uses native ID/revision and restarts the agent only if it is running and its effective settings changed (see saving). Dirty drafts resist backdrop/Escape; explicit Cancel/Close discards. Page navigation/reload still discards page-local drafts.
For Buzz Agent, Browse models requests the current Databricks catalog on explicit button
activation, including when typing has already opened the local popup. Typing,
focus and ArrowDown navigation never start a model-host request. Existing
app-isolated credentials are used/refreshed first; only an authentication failure
can open browser sign-in. No separate Connect button is required. Errors/cancellation
need explicit Retry; Refresh in Advanced model settings stays headless.
Choose a result or enter a custom ID (blank is allowed); Enter or leaving the field
commits typed text, Escape abandons the query. Save, close and reopen to check it.
If no workspace is configured, edit the agent and set Databricks workspace (HTTPS origin)
under Advanced → Model. App maintainers can instead supply the nonsecret
DATABRICKS_HOST build default below and rebuild the app.
Native builds read these inputs from the repository-root, ignored .env.local,
or from the build process environment. A process value wins by presence,
including an empty value. Both just desktop and release Cargo/Tauri builds use
the same controller-owned configuration. For example:
BUZZ_BUILD_BUZZ_AGENT_PROVIDER=databricks_v2
BUZZ_BUILD_AGENT_ENV='DATABRICKS_HOST=https://workspace.example.com
DATABRICKS_MODEL=your-model-id
DATABRICKS_MODEL_FILTER=team-*'
# Optional capability: any present value, even empty/0/false, enables it.
BUZZ_BUILD_AGENT_ACCESS_OWNER_ONLY=1BUZZ_BUILD_AGENT_ENV is multiline KEY=value content, not a file path. Only
DATABRICKS_HOST, DATABRICKS_MODEL and DATABRICKS_MODEL_FILTER are accepted;
tokens, unknown/duplicate keys and malformed HTTPS origins fail the build without
echoing values. These are public, nonsecret defaults compiled into the binary
and available in the native editor snapshot. Never put credentials here. No
organization-specific host, provider or model is supplied by the app.
- Blank saved provider/model selectors inherit the build floor for
buzz-agentonly (including its absolute executable path); other harnesses do not. Saved selectors win over the floor, and savedBUZZ_AGENT_PROVIDER/BUZZ_AGENT_MODELenvironment overrides win over selectors, including explicit empty strings.DATABRICKS_MODELis a provider fallback below an explicit Model selector. - An absent saved Databricks pair inherits the build host/filter; an explicit
pair, including blanks, wins. Saved
DATABRICKS_HOST/DATABRICKS_MODEL_FILTERenvironment overrides win over either. The same resolution supplies model discovery, credential requests and worker startup. Untouched Create or name-only Edit/Save never copies build defaults into storage. Editing either workspace/filter field intentionally saves both displayed values. - Presence of
BUZZ_BUILD_AGENT_ACCESS_OWNER_ONLYclamps the local listener to owner-only after saved settings/environment and removes its response allowlist. This includes the runner's verified same-owner agent semantics. It does not rewrite imported policy or saved records; remove the flag from both file and process to disable the clamp. Empty/0/falsedo not disable it.
Changing, adding or removing native inputs requires a native rebuild and app
restart; Cargo tracks the file and all three process keys, including removal.
Running agents are not hot-reconfigured. Explicit empty process values clear the
provider or environment floor; boolean capabilities must be absent to disable.
Runtime resources remain separately built from pinned sources with private build
settings stripped. The app-owned relay/key/OAuth boundaries are unchanged:
BUZZ_RELAY_URL is not an agent destination, saved destinations remain explicit,
and DATABRICKS_TOKEN still conflicts with app-isolated persistent OAuth.
See configuration parity for development routing, release flag exclusions and the supported deployment boundary.
Local agents retain access to installed tools without inheriting the desktop's
identity or provider-credential environment. On Unix the controller warms the
user's interactive login-shell PATH in the background with a cleared environment
and a fifteen-second bound. Discovery and Start wait outside the native operation
queue; Stop remains available during shell startup. Only successful probes are
cached for the app process; Check again can retry a failed probe. Restart the
app after changing an already-discovered shell PATH. An unavailable or failed
probe falls back to inherited machine directories, ~/.local/bin, Homebrew, and
system directories. Startup helpers are retired with the probe's owned session,
including separate job-control groups. Windows retains its native tool PATH.
Bundled Buzz tools and harness-owned pinned runtimes remain first. Explicit agent PATH directories are also included, but cannot displace those tools. Empty, relative, and duplicate Unix directories are omitted. Only PATH comes back from the shell: other variables exported by startup files are not copied into the agent. Agent launches use the environment allowlist, explicit saved provider settings, and managed identity overrides. This is tool discovery, not an OS sandbox or a restriction on access to files on the machine.
Individual-agent configuration stays on the Agents page; Settings → Agents owns installation guidance and device-wide defaults.
The native agent-controller::HarnessConfigurationPolicy is projected through
each harnessOptions[].configurationPolicy. Create/Edit and Agent defaults
consume that policy for provider discovery, authentication ownership, model
requirements, and selector environment keys. Provider-specific credential fields
remain with their provider owners; authentication ownership is not a claim that
every provider requires an API key.
| Harness | Authentication owner | Provider configuration | Model selection |
|---|---|---|---|
| Buzz Agent | Selected provider | Scalar selector | Existing defaults and overrides |
| Goose | Harness, with provider-specific overrides | Scalar selector | Existing defaults and overrides |
| Pi | Harness, with provider-specific overrides | Discovered provider selector | A selected provider requires a model |
| Custom executable | External executable | External configuration | Existing saved value |
Policy does not migrate saved records or change validation timing. Pi selection checks stay at discovery/launch and default-save admission. Custom provider values remain readable and editable, but an unmapped provider is still refused at launch. Worker selector keys are shared with native launch resolution; environment values never appear in the policy. Older hosts without the policy retain the existing editor behavior.
supportedModes is currently empty for every integration. Legacy blank-field
inheritance is not managed Default intent. Admission and persistence of explicit
Default/Advanced modes belong to the later Codex persistence layer. Likewise,
effortDiscovery: "unknown" means no model-specific capability evidence is
available; it does not mean effort is unsupported. The existing Agent defaults
effort suggestions remain editable suggestions, not allowed-value validation.
This is PR 1 of the reviewed Codex harness plan. Codex registration, binding, discovery, connection validation, and mode controls are separate layers.
For native acceptance, use the Buzz community in the ordinary development app. Open Create, Edit, and Agent defaults for Buzz Agent, Goose, and Pi. Check provider/setup fields and harness switching, preserve saved/custom values, and save/reopen a disposable configuration. Existing agent settings must not change merely from opening the forms. Mounted form tests cover these controls; controller tests cover stored-record preservation, selector precedence, and launch rejection; a Tauri IPC test checks the actual serialized snapshot.
The Harnesses card always lists Buzz Agent, Goose, Pi, and Claude Code. Claude Code is also a choice in Create/Edit once its tools are installed. Add harness opens the Tier 2 Hermes chooser and setup details. Hermes also appears in the main list once its executable is detected.
Buzz supplies buzz-dev-mcp to Buzz Agent for developer tools and Hermes
Agent for its authenticated shell path: Hermes's native terminal can strip the
Buzz signing key. Launch and runtime snapshots use the same native harness
policy's include_buzz_dev_mcp flag. Every supported harness declares its choice
explicitly. The shared preset definition requires includeBuzzDevMcp; omission
is invalid. Unknown custom harnesses fall back to false. Available tools depend
on the harness and its configuration.
| Harness | include_buzz_dev_mcp |
|---|---|
| Buzz Agent | true |
| Hermes Agent | true |
| Goose | false |
| Pi | false |
| Claude Code | false |
| Codex | false |
| Unknown custom harness | false (fallback) |
Saved absolute paths follow the same policy when the executable retains its
recognized basename (buzz-agent or hermes-acp, including supported suffixes).
A differently named wrapper or symlink is treated as a custom harness.
-
Buzz Agent is bundled and shows Ready.
-
Goose is bundled and always shows Ready. Buzz launches
goose-acpdirectly, with no CLI installation or ACP subcommand. Provider credentials and inference readiness remain separate from executable availability. Buzz Agent remains the default; existing selections are preserved. -
Pi shows Ready, CLI needed, or Adapter needed. On macOS/Linux, Install downloads checksum-verified Node v24.18.0 into app-data, then uses that Node/npm to install Pi and
buzz-pi-acpinto an app-owned npm prefix. Installation has a private log, re-detects the executables, and restarts only enabled Pi agents that previously failed because their executable was missing. User-global Pi installations remain untouched. Windows and unsupported architectures retain manual setup. Settings explains that Install supplies Node.js, Pi, and the adapter automatically. Copyable terminal commands are collapsed under Manual setup within the Pi row (Node.js 22.19 or newer required). Failed installs show the failed step and a bounded npm error excerpt above the expandable private install log; errors do not assume a registry problem. The manual fallback commands are:npm install -g '@earendil-works/pi-coding-agent@>=0.99.0' npm install -g --install-links=true 'git+https://github.com/salman1993/buzz-pi-acp.git#72015de'
-
Hermes Agent shows Ready or CLI needed in Add harness, with a manual setup guide and no Install/Update action. Check again updates the chooser and main list; removing its executable hides the main row again. Discovery searches for the exact
hermes-acplauncher name. Windows.exe/.cmd/.batlaunchers are a known discovery limitation in this slice; saved absolute paths remain recognizable/editable. -
Claude Code shows CLI needed or Adapter needed for missing tools, Sign-in needed when its CLI reports signed out, and Ready once tools and sign-in are confirmed. A failed auth check shows Sign-in unconfirmed. On macOS/Linux x64 and arm64, Install reuses the checksum-verified managed Node and installs
@anthropic-ai/claude-code@2.1.289and@agentclientprotocol/claude-agent-acp@0.85.1into a new app-ownedclaude-tools/releasesdirectory. Both launchers must pass--versionbefore activation; a failed install preserves the previous release. Pi and Claude use separate release storage and share the native install/quit owner, so only one installation runs at a time. Stop remains available for running agents. The result and private log survive leaving Settings, and completion refreshes native detection. Complete external installations take precedence and remain untouched. Windows and unsupported architectures retain manual setup with Node.js 22 or newer. The fallback commands are:npm install -g @anthropic-ai/claude-code@2.1.289 npm install -g @agentclientprotocol/claude-agent-acp@0.85.1
Windows discovery resolves
node.exeand native/Windows npm launchers; the PowerShell sign-in command uses the selected.exe/.cmd/.batpath. While installation runs, Install keeps keyboard focus but blocks activation. Failure leaves it focused for retry. Success moves focus to the status if Install still owns focus, without taking it from another control.Sign in to Claude Code shows the resolved CLI's
auth logincommand, including managed Node on PATH when needed. Settings checks the selected CLI with a bounded, read-onlyauth statuscommand on opening, Check again, and after installation. Only itsloggedInboolean is exposed; account metadata is discarded. Ready rows hide setup guidance; failed installs retain their error and log. This confirms local sign-in, not inference. The ACP adapter bundles its own Claude runtime; the separate CLI provides the sign-in command. Native retainsclaudeSetupfor Settings and reports the selected adapter inharnessOptionsfor Create/Edit. Picker availability confirms installed tools, not sign-in or inference. Claude is not a device-wide default-harness choice yet.Create agent → Harness → Claude Code uses Claude's own model and sign-in. Provider, model browsing and Test connection are not offered in this slice. Saved model/provider fields remain visible for recovery; choose Use Claude Code defaults before saving or starting those agents. Start uses the saved absolute adapter path with empty default arguments. Managed adapters use the pinned managed Node; external adapters prefer a runnable Node beside the adapter, then native discovery. Node and adapter directories precede the existing controlled tools PATH, after bundled Buzz tools. Shell provider credentials are not inherited. Explicit Advanced environment values remain write-only. Buzz points
CLAUDE_CODE_EXECUTABLEat the selected runnable CLI unless Advanced environment explicitly overrides it. An explicit override skips CLI discovery; Node is still required. This avoids relying on the SDK's optional native-binary download. Windows.cmd/.batlogin launchers cannot be used by the JavaScript SDK, so those installations use the SDK's bundled native runtime and must include its platform optional dependency. The pinnedbuzz-acpowns Claude system-prompt append, channel/thread sessions, permissions, cancellation and cleanup. Create, Start/Stop/Restart and retry use the existing native controller, without another identity or lifecycle owner. See View a Claude Code session for local transcripts and tool activity.
Tier 2 definitions live in harness-presets.json,
owned by the controller and read by both Rust and TypeScript. Native discovery
reports executable presence and editing suggestions through harnessOptions.
Settings and create/edit identify presets by executable name using the shared
JSON; setup metadata is not duplicated in IPC. Frontend lookup preserves
saved-path identity on older hosts and does not infer installation.
All presets currently use the harness's own model/provider defaults. Runtime
quirks remain in the pinned buzz-acp; Goose and Pi retain their specialized
setup and model integrations. Adding a preset definition still requires a real
ACP compatibility check; this registry does not implement model browsing.
Check again re-detects installed Harnesses without reopening Buzz. Status is executable detection, not a guarantee of sign-in, ACP readiness or inference. The reviewed Pi adapter revision supports native steering, which needs Pi 0.99.0 or later. Buzz checks the selected Pi CLI's version before agent startup or model browsing. An older or unreadable version fails with an error naming the selected CLI path and the required update. Verification has a five-second limit and receives only basic system environment values, never inherited Buzz or provider credentials. Model Cancel retires the probe and its helpers; probing runs outside the agent controller lock so Stop and status remain available. Start rechecks its ticket and effective Pi settings after verification.
Each app-owned install goes into a new release under
node-tools/releases/<adapter revision>.<time>. Buzz then renames the pi and
buzz-pi-acp shims in node-tools/bin to point at it, so an agent that starts
during an update never sees a partial install. Buzz keeps the previous release
for agents still running from it. When the shims point at a release of an older
adapter revision, a Ready app-owned Pi offers Update Pi, which installs Pi
and the pinned adapter together. Settings shows no update guidance for a ready
user-global installation. To update one at <prefix>/bin/buzz-pi-acp, rerun both
commands above with --prefix <prefix> so npm updates that copy even when the
active npm uses another global prefix. Restart running Pi agents after either
update so new sessions load it.
Add/Edit links to Settings → Agents for setup instead of telling people to reopen
the app. The ACP tooltip says:
Buzz talks to harnesses through the Agent Client Protocol (ACP). Goose ships with Buzz. Pi needs the buzz-pi-acp adapter. Hermes Agent uses its own ACP launcher and sign-in.
The Agent defaults card in Settings → Agents holds a default harness, provider, model, effort and environment variables.
- The default harness is copied into each new agent at creation (Create falls back to Buzz Agent while the default harness is not installed). Changing it later does not switch existing agents.
- Provider, model and effort are looked up at each start for fields an agent
leaves blank, only when the agent uses the default harness; per-agent values
win. The editor shows a blank field as “Use agent defaults (…)”. Effort has no
per-agent field: effort carried by a portable agent or team import is saved as
the agent's own effort and overrides the default, as does an older imported
agent's
effort_level. Effort chosen throughBUZZ_ACP_EFFORT_LEVELis never shown or exported; agents and teams relying on it are refused for export. - Permitted environment variables merge per key; the agent's key wins.
BUZZ_ACP_MODELinherits only within the default harness, while shared controls such as worker count and system prompt can inherit across Pi and Goose. A saved Databricks workspace/filter also wins over the corresponding globalDATABRICKS_HOST/DATABRICKS_MODEL_FILTERpair. Agents without their own workspace/filter inherit the global pair. - Changing the default harness in the card clears the default model and effort; values entered for the new harness before Save are kept.
- The effort picker offers common values for the selected harness and keeps custom values editable; support still depends on the selected model. Known Pi and Goose providers show the same masked API key field as agent Create/Edit. A key entered there is a write-only global environment override, used by model lookup and inherited by agents without their own key. Switching provider or harness drops an unsaved key.
- Model choices include exact IDs. Catalogs over ten models have a local search by name or ID; filtering does not change the selection. Environment removals must be saved before browsing because lookup still inherits saved values.
The store is defaults.json under app-data agent-controller/, not
localStorage, written atomically with owner-only permissions (0600).
Environment values are write-only, like per-agent API keys: only key names are
returned to the UI. This layer applies before
BuildDefaults::resolve(), so a
global value wins over the nonsecret build floor,
which still fills only Buzz Agent blanks. Goose and Pi receive inherited
provider/model through their existing selectors. Inherited values are never
written into saved agents.
Saving an agent or the defaults restarts, through the native supervisor, only
agents that were running before and after the save and whose effective
launch settings changed. Stopped and disabled agents are never started or
enabled; a Stop that lands before the restart wins. Save reports “Saved.” or
“Saved. Restarted N agents.” restartDiff compares effective settings, so it
also flags inherited changes. Both requested updates and ordinary agent edits close after a complete save and show the result in a toast. Save errors, restart failures, and unconfirmed profile publication keep the editor open for recovery.
Edit uses the same draft avatar picker as human Profile settings: upload/drop an
image, paste an HTTPS URL, choose emoji artwork, or remove the picture. Done changes
the form; Save first persists the exact native ID/revision, then publishes to that
agent's saved community without restarting it. Older native hosts without
avatarEditingAvailable retain the display-only avatar.
An omitted picture preserves the saved override; an empty string explicitly removes
it. A changed picture or name durably marks profilePending and remains persisted
across restart/reload until publication is confirmed. A successful profile publication
clears both pending fields atomically at the same saved revision; failures and
superseded receipts leave them available for explicit Retry. The native publisher
reads and verifies the agent's current signed kind-0 profile, changes only
name/display_name for a rename (and picture when requested), and preserves
unrelated content and non-auth tags. Name/bot initialization is only for a missing
profile.
One native publication per agent can run at a time, including across renderer reloads. The host verifies current-profile readback after a matching accepted receipt before clearing pending at the same saved revision. Conflicting or failed reads/publications keep pending for explicit retry; no automatic broadcast or retry loop is introduced. Another client can still replace the profile after this confirmation; this is not a cross-client transaction.
Browser tests use synthetic profiles/media and controller fixtures. Rust checks use temporary stores, public fixture keys and loopback HTTP. They do not establish live relay access, native image rendering or packaged human signing. Camera and recording are outside this avatar slice.
Managed agent keys share one agent-only Keychain item: service
dev.local.buzz.foundation.agents, account agent-bundle-v1. After a successful
read, the native credential owner caches it for the session; starting another
migrated agent does not read another Keychain item. Human identity and old Buzz's
credential blob stay separate. Nothing collects the macOS password or changes
Keychain access controls. Development signing and other credentials can still
cause OS prompts; this is not a promise of exactly one total dialog.
Existing app-owned agent:<key-community> entries are copied lazily on Start or
other explicit credential use, with exact identity validation and secure readback.
The first migration can require multiple approvals. Original entries remain for
rollback; explicit Delete removes both copies before removing settings. New keys
are written only to the bundle, so older versions cannot start newly created keys.
Do not operate older and newer credential writers concurrently during rollback.
Never delete old Buzz's source credentials for this migration.
A short per-OS-user file lock serializes bundle access across cooperating worktrees/profiles. Writes re-read the current bundle under that lock and verify readback; a nonsecret invalidation token in the lock file invalidates other sessions' cached copies before writes. Lock files contain no keys. Busy storage fails visibly and requires explicit Retry; it never waits behind another app's consent prompt or automatically replays a write. This does not coordinate manual Keychain edits or older app versions; quit the app before changing storage outside this owner. A refused unlock is remembered until explicit Start/Retry, Import, Create, profile publication, or Delete; later auto-start rows do not reopen it.
All launch-selected agents appear Waiting to start · unlock Keychain if prompted until their turn finishes acquiring credentials. A successful acquisition advances to Starting process, then process-alive evidence or a specific failure with Retry start. Stop remains available while waiting; pending OS dialogs may still need dismissal, but a late result cannot start a stopped agent. Quit and saved-revision fences remain in force. No frontend polling automatically retries Start. Windows/Linux retain their existing per-agent credential adapter.
Debug builds print [agent-startup] and [agent-keychain] lines to the existing
just desktop terminal. Selection records include the public key/community ID,
effective startOnAppLaunch and enabled intent, then each auto-start attempt records its
final process state. Credential records identify bundle/individual/legacy item
class, operation, begin/end, sanitized failure category and elapsed time. They
never print keys, raw item accounts, relay URLs, environment, agent names or OS
error text. Release builds do not emit these diagnostics; no new log store or
telemetry transport is added. A Keychain API call is not proof of an OS prompt.
For an attended check, retain only these prefixed lines locally, note the dialog's item label (never the password), then quit and relaunch the unchanged binary. Do not manually start agents or send waking mentions during this check: credential lines have no agent ID, so overlapping credential operations cannot be attributed by order. Already-migrated agents should use the bundle, not individual reads. Native signing/OS consent remains a separate observation; do not equate a fixture pass or a Keychain call count with password-dialog acceptance. Auto-start off is a saved preference, not an execution failure: change Start on launch in the agent profile's Runtime tab deliberately rather than rewriting settings.
Native startup opens app_data_dir/agent-controller, never the old library as a
destination. One serialized controller lives for the app lifetime. It restores
agents whose start-on-launch preference is on (legacy records without one follow
saved enabled intent) with app-owned credential custody and verified resources.
Page/plugin/community disposal drops observations, not processes. Quit fences
pending starts and stops owned processes while retaining enabled intent. A pending
OS credential dialog does not hold the controller: Stop, Disconnect and Quit
retire late starts; Save during a credential wait requires an explicit retry.
Synthetic native tests inject rejecting or in-memory credentials and runtime
resources. Production has no disposable storage override or preview launch mode.
Launch-selected agents start relay listeners; their AI worker pools remain lazy
until work arrives. Status reads project configured ACP/MCP paths without reading
or hashing executables. These paths and runtimeAvailable describe the bundle
accepted at initialization, not a fresh integrity check or relay readiness. Every
actual launch still verifies its worker and ACP executables, plus the MCP
executable for Buzz Agent and Hermes Agent, before spawn and exposes verification
failure on the agent. Native Start projects one
final snapshot after recording its outcome. This adds no incoming wake service
for fully stopped listeners and no durable interrupted-turn recovery.
An execed supervisor in the same app binary owns each agent's shared identity lock, isolated listener session, and temporary runtime directory. App Stop/Quit and kernel EOF on forced app death both trigger the existing whole-session teardown; ownership is released only after listener and workers have exited. Unconfirmed teardown keeps the lock and private directory, and normal Quit remains fail-closed. This does not clean up listeners orphaned before this fix, does not contain a worker that deliberately escapes its session, and force-killing the supervisor itself releases ownership without confirmed teardown.
On Windows the session is a kill-on-close job object. The listener starts suspended and runs only after joining it; a failed assignment aborts Start. A watcher opens each process as it joins. Stop terminates the job immediately, without Unix's two-second cooperative cancel, and succeeds only once every process the job ever admitted was opened and has exited. A lost job notification, or a process gone before the watcher opened it, fails Stop closed and keeps ownership. The windowless supervisor can still be ended by an enclosing kill-on-close launcher job. Profile, config and temporary directories inherit Windows ACLs; they are not verified to match Unix 0700/0600 modes.
Non-Pi harnesses get the bundled tools first on PATH, then Windows' native PATH;
on Linux ~/.local/bin and /usr/local/bin precede the system directories, which
are macOS's only entries. On Windows the shell tool needs Git Bash from Git for
Windows, or a BUZZ_SHELL/GIT_BASH override under Advanced → Environment.
Settings says Shell setup not verified; Buzz does not check it before Start.
features/agents/control.ts: camelCase DTOs and app-owned observable projection.control-service.tsconstructs it once at root app composition and exposes itsAgentControlinterface through Cordis injection. Only the app disposes the projection; the author contract exposes neither its disposal nor host construction.control-native.ts: named native IPC commands, including explicit model-request tickets. Browser returns an unavailable capability; no fetch fallback, local storage, signing or runner.bundled/agents/AgentControlPanel.tsx: compose with{ control }independently of selected community or relay connectivity. It owns only observation and UI drafts. Its five-second status refresh runs while visible, including after a read or operation error; reads coalesce and never replay writes. A read rejected specifically because native startup is initializing or its lock is busy stays pending for at most twenty 250ms waits. Other errors or exhausted retries remain visible above the cards, with explicit Retry as well as the next periodic read. Successful reads clear the global warning; native per-agent errors remain on the affected agent, and failed Save/Create/Delete details stay in their dialog. Unmount clears the timer, not enabled intent or processes.- Native host owns persistent state, credential custody, process groups, lock and duplicate ownership checks, source import validation and sanitized diagnostics. Critical sections wait in arrival order through the host's async admission gate and execute on blocking workers; a status read does not reject a concurrent command as busy. The worker retains admission until it finishes, even if its caller disappears. Credential and network waits release admission so recovery Stop can still invalidate pending launches. Shutdown is checked again after acquiring native state. Failed commands are never automatically replayed. It must bound IPC operations and reject with deliberately user-facing strings; raw child/OS/parser errors must never cross into these snapshots or rejections.
-
Start enables host-owned execution; Stop disables automatic resume and stops active work. A later deliberate outgoing mention can enable execution again. Native confirmation, not React optimism, determines displayed state. App Quit stops owned processes but retains enabled intent for the next launch.
-
Start on launch is a separate persisted preference set with
agent_control_start_on_app_launch. It is not a config revision and never starts or stops the running process; a restore it triggers is an ordinary Start. Created and imported agents save it off; only legacy records without one follow enabled intent. A launch restore queued behind another agent's credential prompt skips any agent explicitly started or stopped since the app opened. -
While a process is alive,
restartDiffitemizes saved settings that differ from the settings it was started with. The native side compares raw values and sends only redacted entries: prompt character counts, masked arguments and environment values, and environment keys as added/removed. -
runningis process-alive evidence only, labeled “Process running · relay readiness unverified.” It is not a Listening/Working badge or proof a mention can be received. Native wake/readiness acceptance is separate. The avatar badge is relay presence, which the harness publishes just after the process starts; the card re-reads it briefly after start/stop (see presence). -
Save uses
expectedRevisionand updates only editable fields, then restarts running agents whose effective settings changed (see Global agent defaults and saving). Saved/running revisions remain distinct. Dirty drafts survive refresh and save failure. A newer saved revision blocks overwrite and offers explicit discard; the person can copy their edits before discarding. Drafts are page-local and are not persisted across navigation/reload. -
Arguments use a JSON string array rather than splitting shell text, preserving spaces and literal quoting. Empty/comma-containing arguments are rejected because the current ACP transport cannot represent them faithfully. The executable is a per-agent harness choice; Settings → Agents owns the Harnesses setup card. The host must validate launch configuration and unsupported imported semantics before execution.
-
Harness and Provider choices come from native
harnessOptionsthrough the injected Core snapshot. Buzz Agent offers Databricks v2 and OpenAI; Windows offers only OpenAI, which a new agent without a default uses, and explains an inherited or saved Databricks provider as unsupported. OpenAI uses the masked key field below asOPENAI_COMPAT_API_KEY, per agent or from Agent defaults. Goose is one logical harness choice, resolved to the verified bundledgoose-acpexecutable, and offers common Goose providers plus a custom ID. Switching into Goose supplies no subcommand arguments and clears the previous provider/model; selecting a Goose provider clears the previous model. For Goose, selecting a provider from the dropdown asks Goose ACP for its supported-model list. Opening an existing editor does not start discovery or sign-in; Browse remains available. The picker shows loading and authentication failures; failures require explicit Retry. Provider changes cancel the previous lookup and discard stale results. Credential/context edits retire discovery and wait for Browse or Retry, so typing credentials never repeatedly launches sign-in. Custom provider IDs still require Browse, so typing an ID does not start a lookup per keystroke. The exact returned ID is saved; an unlisted ID remains possible but is flagged after discovery. The picker shows at most ten matches while filtering the full list. Saved write-onlyGOOSE_PROVIDERoverrides remain native; native uses the effective provider before asking Goose. Goose has no separate Refresh action because its catalog lookup can start OAuth. Known API-key providers show a masked key field beside Provider. Its write-only environment patch is used for both model lookup and agent launch; a blank field uses Goose's existing credentials. The key field follows a draftGOOSE_PROVIDERoverride. When a saved override's value is hidden, Buzz asks the user to replace or remove it in Advanced → Environment before showing a provider-specific key field. These per-agent keys are stored in the app's localagents.jsonsettings file and its backup with restricted filesystem permissions, not in Goose's keyring. Listing errors prompt the user to enter credentials or retry; manual model entry remains available. Executable detection is not a sign-in or ACP readiness check. Custom command/provider values remain editable, including absolute paths. Buzz Agent retains on-demand Databricks model browsing. A Goose catalog entry does not establish caller EXECUTE permission or successful inference. Advanced arguments remain a literal JSON array. Old native hosts without this metadata fall back to custom entry. -
For Goose and Pi, Test connection appears below the provider/API key and above Model, including before a model is chosen. The shared form and native request lane own cancellation and result display; tests never fill Model.
-
For Goose, a blank Model resolves the selected provider's
defaultModelthrough Goose ACP provider metadata. Buzz keeps no default-model mapping. A nonblank explicit model or effectiveGOOSE_MODELoverride is tested as entered. Test connection sends one small request in the agent workspace using the effective draft provider, model, and write-only environment. Goose keeps its own output and thinking defaults. Bundledgoose-acpuses a hidden temporary session in chat mode with extensions disabled. Buzz checks its recorded conversation for a nonempty assistant reply and rejects error content: ACP can render provider errors and empty token-limit fallbacks as ordinary text notifications. Buzz then deletes only that temporary session before returning, including on inference failure or timeout. Cancellation schedules bounded cleanup, also handling an in-flight session creation. If deletion fails, Buzz reports that the session may remain in Goose history; a crash or unresponsive sidecar can interrupt cleanup. The test consumes a small amount of provider quota. An external full Goose CLI pin retainsgoose run --text --no-session --no-profilewithout saving a session. Success requires nonempty assistant text and reported token usage in its JSON output; Goose can exit successfully with synthetic text after a provider error. Providers that omit usage cannot confirm success through this CLI check. Model browsing does not create a session or fall back to the CLI. Neither check verifies Buzz relay readiness, launches the agent, or changes the draft. Success reports the canonical provider/model tested, except that write-only overrides keep their values hidden. A provider without a default asks for a model; Buzz never substitutes another provider. -
For Pi, with Model blank, Pi chooses from the selected provider's
--models provider/*scope. Buzz checks Pi's actual selection through RPC before sending a short prompt; if Pi falls back to another provider, Buzz stops and asks for credentials. With a model selected, Buzz tests that exact provider/model. Success requires an assistant text reply and reports its canonical model ID without changing the draft. Listing models alone does not verify the API key or inference access. Tests use the agent's effective environment and existing Pi sign-in, create no saved Pi session, and stop on cancellation or timeout. -
Environment values never arrive in snapshots. Inputs are write-only patches: missing key preserves; string replaces (including empty); null removes. Draft
BUZZ_ACP_AGENTSvalues are readable; other inputs stay masked. Undo omits a patch again. Successful save clears entered values from UI state. Browser strings cannot promise zeroization. Unknown native fields stay native. SavedBUZZ_AGENT_MODEL/BUZZ_AGENT_PROVIDER(buzz-agent) andGOOSE_MODEL/GOOSE_PROVIDER(Goose) overrides win over Model/Provider selectors; blank selectors do not erase them. ACP uses the same effective model. Snapshots name the deciding key (launchModelEnv/launchProviderEnv, includingDATABRICKS_MODELor a hidden provider behind a blank buzz-agent model) and omit the resolved value. -
Local browsing reads only the chosen installed/development library without a destination. Native keeps no pending import for that read and invalidates any prior import token. An actionable import preview requires an explicit secure Destination community origin. Old Buzz ignores saved relay pins at runtime; blank, stale or malformed saved pins do not route or hide identities here. Native validates the chosen destination, shows it beside each exact key, and retains it with the preview token through commit. Source or destination edits discard candidates and invalidate late preview results. Each Import action selects one exact identity. Duplicate source keys fail closed even with different old pins; changed sources and duplicate destination ownership are rejected. Only explicit Import actions commit, always stopped. No key minting, membership enrollment or source-store write. After a failed preview, correct the destination/source and choose Load agents or Retry; both refresh status before previewing. Never edit the old library to work around a destination error.
-
Operations are serialized except explicit recovery Stop during a pending Start/Restart, Import, Create or profile-publication credential wait. Stop can reach the native fence for a pending launch or another known enabled/running identity; only one Stop is admitted at a time. Other writes remain blocked until both operations settle. Superseded success, error and finalization cannot overwrite the newer Stop result or unlock its pending operation. Stop does not cancel native credential writes: imported/created rows may still commit stopped, and profiles may publish. Recover these changes by a fresh status read, never by replaying the superseded result. Old pre-write reads cannot overwrite newer command evidence. Failed reads/commands retain the last snapshot and draft with explicit uncertainty. Start/Restart/Save/import require a fresh successful host read before retry. Explicit Stop is the only recovery exception: it remains available for identities in the retained snapshot, even if that stale snapshot says stopped/disabled. Failed durable disable remains unconfirmed; Stop is never automatically retried. No process recovery loop in TypeScript.
- Native
agent_models.rsowns one ticketed, 180-second operation lane, separate from the controller lock. Only the user-intent Connect IPC action (Browse/Retry) can open a browser; it tries headless discovery first. Refresh is always headless. Cancel, context change, page unmount and root disposal retire the ticket. Native admission remains occupied until the old task's future has actually dropped. - The immutable
buzz-agentdependency is pinned insrc-tauri/Cargo.toml; no local-checkout dependency. It owns OAuth PKCE, refresh, catalog parsing/filtering and per-page bounds. It retains current Buzz endpoint/redirect semantics. Native rejects over 10,000 projected models or oversized IDs. - OAuth credentials remain under this app's
agent-controller/buzz-agent/oauth/databricks/<connection-hash>.json. Connect, native catalog, worker catalog and inference share this exact engine layout. Unix directories are owner-only; helper token files are owner-only. They are not Keychain-encrypted; other code running as your OS user can access them. Non-Unix helper persistence remains memory-only, so Windows refuses Databricks Connect, catalog, credential open and Start with an explicit unsupported error (OpenAI is unaffected). No old Buzz cache/Keychain or ambientDATABRICKS_HOST/DATABRICKS_TOKENis read. - Disconnect requires Stop for all owned workers using the displayed workspace, retires pending starts for it, and removes only its app cache (retaining the lock inode). It does not revoke browser sessions or tokens at Databricks. Cancel may happen after successful authentication; use Disconnect if credentials should be removed.
- Save persists workspace/filter with the harness revision; Connect does not save
or start. Saved or draft environment overrides take precedence; conflicting inputs fail before
auth rather than querying a misleading catalog. An effective non-v2 provider,
token override or revision conflict also blocks connection.
BUZZ_AGENT_MODELproduces a visible override warning, never leaks its value or rewrites it. - Catalogs may be partial; no completeness claim. The pinned helper's labelled authenticated-empty defaults are omitted here because they are not discovered IDs. Empty/error states keep manual entry available.
- Nonsecret build defaults supply the workspace, model fallback and filter without copying them into saved agents. Unknown or secret build keys fail closed. With no saved or build workspace, enter one explicitly before browsing models.
Ordinary bin/just desktop and bin/pnpm tauri build prepare these resources
automatically. Direct Cargo builds do not run that JavaScript preparation step.
To prepare/build without launching any app or accessing old credentials:
bin/pnpm install --frozen-lockfile
bin/node scripts/build-agent-runtime.mjs
bin/pnpm build
bin/cargo build -p buzz-foundationruntime/agent-runtime.json pins five Buzz tools
to the same immutable source revision as the native library, plus an independent
Goose revision for goose-acp. The build script fetches both revisions and uses
pinned Cargo with locked dependencies: a release build of the Buzz tools and a
lean Goose build without default features. just desktop builds Goose with
gooseDevProfile instead, which compiles much faster. Packaged builds keep the
pinned profile, and the manifest records the profile actually built. Sources stay
checked out under target/agent-runtime-src, so a rebuild after a pin bump reuses
unchanged crates. An exclusive per-checkout lock covers preparation through
publication; a second preparation fails with a retry message. Ctrl-C releases the
lock. After a force kill, stop its remaining Git/Cargo processes before removing
target/agent-runtime-prepare.lock.
Builds scrub injected Buzz/provider environment and
per-shell compiler overrides (RUSTFLAGS, RUSTC_*, CARGO_PROFILE_*, …), and stages binaries plus
revision/Goose source and build settings/target/SHA256 manifest in
src-tauri/resources/agent-runtime. Worktrees
of one clone reuse a verified bundle cached under the Git common directory, keyed
by the pin, tool list, build arguments and rustc -vV. Native build copies them to
target/debug/agent-runtime. Generated binaries/manifest are not committed.
Startup verifies all six tools, target, both source pins, Goose build settings
and file hashes. Packaged
macOS apps may accept signing-induced hash changes only when the runtime belongs
to the running app and its resource seal verifies under Block's Developer ID.
The final hashes are retained in memory; required launch tools are rehashed before spawn. No PATH/old-bundle fallback or runtime
download. The manifest detects corrupt/mixed resources, not a same-user attacker
who can replace the app and manifest. Inputs are immutable, not a promise of
bit-identical machine-independent binaries. This build is not a signed installer.
Before restoring local agents, the native host installs the embedded buzz-cli
skill at ~/.buzz/.agents/skills/buzz-cli/SKILL.md, including on a fresh machine.
Development builds also use ~/.buzz, so a desktop dev run writes to this real
workspace and may migrate a legacy Claude-only skill there.
On macOS/Linux, Claude, Codex and Goose discover it through relative directory
symlinks under .claude/skills, .codex/skills and .goose/skills in that workspace.
Windows receives the canonical file, matching the old desktop's Unix-only links.
Existing real provider directories and valid links are preserved; dangling links
are repaired. A redirected provider directory is reported and skipped without
blocking the canonical file or the other providers' links. The old Claude-only
layout moves to the canonical location, preserving edited content and supporting files.
crates/agent-controller/src/buzz_cli_skill.md is copied from the old desktop at
the revision in runtime/agent-runtime.json. Its installer uses the old desktop's
.skill-version marker: current or newer installations stay untouched, while
missing content is repaired and older templates are refreshed atomically.
Update CLI_SKILL_VERSION in skills.rs when adopting a newer template, keeping
it aligned with the upstream template version. No skill download or old-app
installation is required. Custom agent workspaces are not modified. Installation
errors are logged without preventing the app from opening.
Update the library pin in src-tauri/Cargo.toml and the bundle pin in
runtime/agent-runtime.json together, then refresh Cargo.lock without unrelated
dependency upgrades. The runtime integration test checks that both pins name the
same repository and immutable revision; the native synthetic manifest reads the
runtime spec rather than carrying another copy of the pin.
When changing the Buzz revision, re-copy
desktop/src-tauri/src/managed_agents/nest_skill.md from that revision into
crates/agent-controller/src/buzz_cli_skill.md. Set CLI_SKILL_VERSION in
skills.rs to upstream's NEST_SKILL_VERSION, preserving its shared version
policy with the old desktop. Check the new file against the pinned CLI behavior.
Goose upgrades change only the goose source/build settings in the runtime spec;
they do not require changing the Buzz library or tool revision. Logical
goose selections use the bundled sidecar, including saved legacy selections
with a leading acp argument. Explicit absolute paths remain external harness
pins and retain their launch arguments. Model browsing resolves the same verified
sidecar; it never searches PATH for a CLI.
Re-run the resource preparation and native build commands above, then validate:
bin/cargo test --locked -p buzz-foundation -p buzz-agent-controller -- --include-ignored
bin/node --test tests/integration/agent-runtime.test.mjsThese checks use isolated fixtures, including the staged binaries; they do not launch the app or access live credentials. Exercise upstream behavior changes with relevant bundled-tool smoke checks. Do not commit generated resources; live handover remains a separate step below.
- While old Buzz still runs, review/import only. Choose the installed/development library and destination under Import options. Import may prompt for the selected legacy secure-storage blob; it creates app credentials in the separate agent-only bundle described above. The source is read-only and imported agents stay stopped. Refused custody is a blocker, never a reason to migrate keys implicitly.
- Review prompt, workspace, harness/provider/model and write-only overrides. Browse models, save explicitly, and verify settings after reopening.
- Before Start or an outgoing mention, stop old Buzz and its listeners with the human's agreement. Native refuses detected legacy paths; it never kills them. Cooperating new-app profiles also hold an exact-key/community OS lock. Neither protects against relaunching unmodified old Buzz: no coexistence claim.
- Observe a real channel/thread reply, idle wake, Stop cancellation and Quit cleanup in the attended workflow. A process-running badge is not relay evidence.
- Stop agents on a workspace before Disconnect. A saved host edit does not change
a running worker. Temporary signing files under private
runs/agent-*disappear only after confirmed teardown. This is lifecycle management, not a sandbox for same-user code that escapes its Unix session. - Roll back with Stop and confirmed new-owner cleanup, then Quit and resume that identity in old Buzz. Never delete the old library or its credentials.
control.test.ts, control-native.test.ts, agent-edit.test.ts cover projection
races, unavailable browser, exact IPC payloads, uncertain result handling,
save/restart feedback, literal arguments and environment patch
semantics.
tests/browser/agent-control.spec.mjs drives the real editor and capability over
the isolated fake host in Chromium/WebKit: dirty refresh, save failure, revisions,
write-only replacement, Stop, unmount without control actions, selected import,
browser unavailability and narrow dark layout. Mounted recovery cases start with
running and stopped snapshots, fail status reads, then exercise explicit Stop
through the real capability; failed durable disable retains uncertainty and drafts.
These browser fixtures do not prove native IPC or persistence.
src/app/agent-control.integration.test.ts exercises real app composition, Agents
registration, plugin management, community selection and the native adapter with
synthetic IPC/relay transports. The same injected capability remains functional
through disable/re-enable, two real community session switches and Personal space.
Captured IPC contains only snapshots during those transitions; root disposal fences
further reads without sending Stop. This is not a mounted native GUI test.
src/plugins/author.test.mjs builds declarations and independently compiles a plugin
consumer with no host source, checking Context injection and non-exported ownership.
src-tauri/src/agents/tests.rs uses the actual command handler and Tauri mock runtime
with temporary disk stores for Save/CAS/Stop, source preview, rejecting test credentials/runtime and
shutdown fencing. These checks do not establish secure custody, process teardown
or a working listener.
The isolated browser fixture (tests/fixtures/agent-control.*) remains test-only:
no dotenv loading, live broker, native credentials or actual process execution.
It supports the controller, editor-grid and model browser regression suites, not
an alternative product launch mode. Check results belong in the PR at their exact
snapshot rather than as permanent checkpoint claims here.
Local execution currently uses Unix containment; native credential import/create is macOS-only. Custom harnesses require an absolute executable and are not certified by bundled Buzz Agent tests. Unsupported settings stay editable but Start refuses them. OAuth files are owner-only, not Keychain-encrypted. A failed import can leave create-only app custody for retry but no enabled/configured agent. No remote/mesh runtime, live team synchronization or conditional attestation is added. Synthetic checks do not establish actual Keychain ACLs, production TLS/inference, live replies, forced native quit, signed packaging or other-platform behavior.
On macOS/Linux, Settings → Agents offers Install for a missing Pi CLI or
adapter. It uses an app-owned Node and npm prefix; manual setup still works.
Choose Check again to re-detect without reopening the app. Pi appears
alongside Buzz Agent and Goose.
Availability means the executables were found, not that authentication or
inference has been verified. This
integration uses the adapter's Pi argument forwarding after -- (verified with
buzz-pi-acp 0.0.33) and Pi's get_available_models RPC (verified with Pi 0.86.1).
Choose Pi → LLM Provider → Browse models, or leave Provider unset and Browse to see all locally available providers. The returned provider/model pair is saved as separate fields; model IDs retain namespace slashes and punctuation. Browse also adds extension-provided providers to the provider choices. Pi provider changes filter the loaded catalog without launching another lookup. Workspace, arguments or environment changes retire it and clear discovered provider suggestions. Custom provider and model entry remain available, including when lookup fails or returns no models. When a provider is set, enter its exact model ID without adding the provider prefix. The Advanced model field preserves text literally, including IDs that themselves start with the provider name. After Browse, an unlisted ID carries a warning; manual IDs remain allowed and an available catalog is not inference validation. Clear both fields to keep Pi's own defaults. Choosing a provider requires a model before Start; Pi otherwise silently ignores a provider-only flag. Save restarts a running Pi agent whose effective settings changed.
Discovery launches the same locally resolved Pi used by the ACP adapter, in the
agent's workspace, with the same explicit environment and extension arguments.
It uses --mode rpc --no-session --no-themes and sends only
get_available_models, never a prompt or Buzz identity. Selection is omitted
from catalog startup so a stale model cannot prevent finding its replacement.
Cancel, changed workspace/configuration, and closing the editor retire the native
lookup; Unix cleanup kills the lookup process group. Errors require explicit retry.
Pi may return a cached extension catalog; Refresh reloads Pi’s available snapshot
and does not guarantee a fresh remote catalog. The catalog reflects Pi's available models and local credentials, not a guarantee
of inference permission. Authentication and extension caches remain Pi-owned;
configure sign-in in Pi. Extensions are executable local code and can perform
their own initialization/authentication during discovery.
Runtime forwards Provider and Model as --provider / --model to the adapter
and uses provider/exact-id for ACP model selection. There are no invented Pi
provider/model environment variables. The controller owns PI_ACP_PI_COMMAND;
it resolves Pi and Node beside the adapter first, then the usual local install
locations. Ambient provider credentials are not inherited. Use Pi's credential
store or explicit write-only per-agent environment patches.
Optional extension configuration uses Pi's existing facilities, with no provider package bundled into the OSS app:
- Install/configure packages in Pi normally; both discovery and runtime load them.
- Set
PI_CODING_AGENT_DIRin Advanced environment to use a specific local Pi configuration directory. It is saved locally, never projected in a snapshot. - To load a particular extension, set Advanced arguments to
["--", "--extension", "/absolute/path/to/extension.ts"]. Paths containing spaces are supported.--no-extensionsdisables automatic extension discovery while keeping explicitly supplied extensions. Advanced runtime arguments are preserved and forwarded to the adapter, including thinking, skills and tools. Browse supports standard Pi configuration options and strips provider/model flags for catalog startup. Unsupported extension flags or positional input block Browse with an explanation, while manual entry and runtime arguments remain available. Browse also rejects inline--flag=valuesyntax and--api-key, whose meaning depends on the selected startup provider; use Pi's local credential store or explicit provider environment instead. The adapter still owns its reserved session, prompt and mode flags. Explicit Provider/Model fields are appended last.
Internal distributions can provision a pinned extension package and Pi config, or supply an installed extension path through these same settings. Keep private package URLs, hosts, filters, authentication and model policy in the private packaging/configuration owner. Discovery and runtime must point at that same configuration. The current internal release repository builds the old desktop; its generic build environment injection is not a Pi resource-bundling contract for this app. Signed bundling, automatic employee provisioning and release pipeline migration require separate release work; no release is published here.
Local installation import validates the source configuration, owner authorization and private key. It does not require relay inventory or a community confirmation. The imported agent stays stopped.
For explicit setup in a community, the broker can sign the selected owner's intent for an identity/community pair. Native code verifies that signature against the retained source-owner authorization. This does not establish channel membership, key availability or exclusive community membership. It does not reserve a community before import. Setup recovery cannot add another community to an identity that already has a configured setup elsewhere; copying that agent requires Clone.
Joined-community discovery reads each joined community's scoped inventory without selecting it or opening a relay session. Exact keys appear once with all known associations. Each failed community read has its own warning and Refresh retry; successful reads remain visible. Discovery does not provide credentials, an import source, or permission to extend an existing local identity into another community.
Startup copies only identity names, public keys and source labels into a durable inventory. It does not read keys, configure a setup, or start an imported agent. Import copies the selected local key and settings, independent of relay inventory. New imports require a destination and are saved configured but stopped. Use here only recovers older incomplete imports. Start remains a separate action; a later deliberate mention can also start a configured agent. Existing saved setups without the configured flag keep their prior behavior.
The unified card's Import opens the existing installation form with its exact identity and known local source selected. The source is fixed during review; if the preview fails or the identity is unavailable there, you can choose another source. Clone from a local source or imported identity opens a review of only its name and instructions; creation generates a fresh key. Clone never imports the old key.
Community groups show known associations, not exclusive membership or admission. An inventory failure does not block local Import or setup confirmation. Every configured setup keeps Start, Stop and Edit, whichever community is selected. Cards for other communities also offer Clone to bring a new identity here, without changing the source. Archived discovery rows remain hidden after sources join, except where local controls must remain reachable. Linked profiles remain visible on identity cards.
Before starting an imported identity, stop the old agent and disable its automatic startup in the old application. Do not run duplicate copies of the same identity.