mirror of
https://github.com/block/buzz.git
synced 2026-10-30 05:51:46 +00:00
938 lines
61 KiB
Markdown
938 lines
61 KiB
Markdown
Instruction editing: see [Private instruction profiles](PRIVATE_PROFILES.md) for offline durable drafts, owner-private relay publication/reload and selected-next versus actual-run application. Public kind0 metadata is not included.
|
||
|
||
# Beehive (experimental first slice)
|
||
|
||
Standalone TypeScript host + relay + terminal UI. **Not Desktop parity, not
|
||
production-ready; deployed relay/provider compatibility remains unverified.** No existing
|
||
client, relay policy, credential store, or native service is changed.
|
||
|
||
A locally created owner secp256k1 identity signs encrypted commands/receipts.
|
||
Hosts retain fixed agent authority and supervise external processes. The TUI
|
||
can close while the host/runner continues. No direct-host HTTP API or controller
|
||
service exists. This package intentionally lives alongside, not inside, the
|
||
native clients: it is a separately authorized product experiment.
|
||
|
||
Configure and start the default host with `beehive host`. Running `beehive`
|
||
opens the full-screen OpenTUI manager: **Local Host** works without an owner signer,
|
||
inspects/saves local configuration and supports provisioning from prepared binding/genesis
|
||
files; **Agents** signs into the relay-backed management view. See [prototype flows,
|
||
runtime boundary and explicit cuts](OPENTUI_WIP.md). Bare launch requires app-local
|
||
Bun 1.4.2 and Node 24.15.0; advanced Node CLI commands remain available. The owner key is entered once, verified against
|
||
the configured owner npub and retained only in this managing computer's Beehive OS
|
||
credential entry. Other hosts retain only the owner npub, host key and explicitly
|
||
registered agent keys.
|
||
|
||
## Command launcher (one-time, reversible)
|
||
|
||
For the packaged prototype, link `bin/beehive`, which explicitly uses app-local
|
||
`runtime/node` and `runtime/bun`. `bin/beehive.cjs` remains the Node bootstrap:
|
||
it checks Node (>= 22.18 for advanced CLI commands; the full-screen controller pins
|
||
24.15.0), routes bare launch to `src/manager-entry.ts`, and routes arguments to
|
||
`src/cli.ts`, resolving from its own real location. Install once into a user-owned bin
|
||
directory already on your PATH (matching no existing command):
|
||
|
||
```sh
|
||
ln -s "$(pwd)/bin/beehive.cjs" ~/.local/bin/beehive # adjust if your PATH differs
|
||
```
|
||
|
||
`beehive setup` (no directory) then uses the default host state folder
|
||
`~/.beehive/host`, resolved from your home and displayed once; an occupied
|
||
default is never reinitialized. Pass an explicit directory for additional
|
||
hosts. Normal configuration and private discovery need no approval files.
|
||
Undo the command with `rm ~/.local/bin/beehive` (or your equivalent link).
|
||
|
||
## Configure and join a private host
|
||
|
||
See [FIRST_DEMO.md](FIRST_DEMO.md) for the current short flow:
|
||
`beehive setup` → OWNER NPUB + RELAY → ordinary community check/join →
|
||
`beehive host --owner-present`. Setup merely configures; host start is an explicit
|
||
foreground lifecycle decision. Retained unapproved and approved identities resume
|
||
without key replacement, retargeting, file exchange or approval import.
|
||
|
||
The locally configured owner public key is the management trust root. Only that
|
||
owner's actual signed commands can manage the host. A host signs and privately
|
||
advertises its own availability, including with zero agents; this offer proves
|
||
neither owner consent nor agent placement. The owner uses
|
||
`beehive tui discover <relay> ~/.beehive/owner` without a catalog file.
|
||
|
||
Setup is configuration-only: no relay discovery, membership checks or invite prompts.
|
||
Retained setup does not open credentials. Host startup and owner management use
|
||
private NIP42/NIP59 transport directly; actual relay refusals fail as transport
|
||
errors. Host availability waits for accepted publication. Actual per-agent grants,
|
||
local genesis and retained assignment still gate Start. Owner secrets stay on the
|
||
owner computer.
|
||
|
||
Historical explicit registration tooling lives under `legacy-enrollment` and
|
||
`catalog`, not the normal setup menu. Legacy two-argument diagnostic setup below
|
||
stores a shared owner key; do not use it for normal private configuration.
|
||
|
||
## Run an isolated fixture
|
||
|
||
Requires Node >=22.18 (tested with Hermit 24.15.0), POSIX process groups and
|
||
pnpm 11.4.0 for the standalone lockfile. Activate Hermit from the repository root.
|
||
|
||
```sh
|
||
cd beehive
|
||
pnpm install --ignore-workspace --frozen-lockfile --ignore-scripts
|
||
npm test
|
||
npm run check
|
||
node src/cli.ts identity /tmp/my-beehive-owner
|
||
# Prints public key; never prints the private key.
|
||
node src/cli.ts setup /tmp/my-beehive-host /tmp/my-beehive-owner/identity.json
|
||
# Choose fixture, absolute Node executable, an allowed real workspace directory,
|
||
# and this package's absolute test/runner.ts path. Confirm NEW agent key creation.
|
||
node src/cli.ts relay 19481 <printed-owner-public-key> /tmp/my-beehive-relay.json
|
||
# Separate terminal:
|
||
node src/cli.ts host /tmp/my-beehive-host ws://127.0.0.1:19481
|
||
# Separate terminal:
|
||
node src/cli.ts tui /tmp/my-beehive-owner/identity.json ws://127.0.0.1:19481
|
||
```
|
||
|
||
On Block-managed machines, the public npm registry is policy-blocked. Append
|
||
`--registry https://global.block-artifacts.com/artifactory/api/npm/square-npm/`
|
||
to the install command to use the approved mirror. No credentials or persistent
|
||
registry config are needed. The committed lockfile is registry-agnostic.
|
||
|
||
TUI: `agents`, `operations`, `reconcile`, `retry <number>`, `hosts`, `select <number or unique host-name>`, `show`, `start`, `restart`, `save`, `stop`, `quit`.
|
||
Save asks for advertised model, workspace and independent behavior profile.
|
||
The fixture has one allowed model. Named behavior profiles are authored remotely
|
||
with `profile-new`, `profiles`, `profile-edit <number>`, and `apply <number|default>`.
|
||
Use `binding <local-id>` to save an advertised local binding into the selected
|
||
named candidate, then explicit `restart` to apply it. `show` lists binding IDs
|
||
and definition fingerprints. Private definitions are provisioned through `local-setup` (immutable add under
|
||
the installation lock); see the small local wizard section below. Destructive
|
||
edit/remove and full initial import unification remain deferred. Legacy configurations keep their original slot binding.
|
||
`show` separates selected-next and immutable actual-run snapshot. Save does not
|
||
restart. `quit` leaves the host running. Reopen TUI to inspect it; `stop` confirms
|
||
the owned process group is absent and leaves the agent assigned to this host.
|
||
Ctrl-C on **host** stops its owned fixture runner before exiting.
|
||
|
||
### Recover an UNKNOWN operation
|
||
|
||
`operations` lists numbered host/action/revision entries and historical results.
|
||
A terminal host rejection is **failed**; a matched accepted receipt is **completed**.
|
||
Neither a socket connection nor relay echo proves completion or current host state.
|
||
Use `hosts`/`show` for separately dated host inventory.
|
||
|
||
After a relay policy close (1008), unresolved work stays **UNKNOWN**, with automatic
|
||
retry disabled even after Quit/reopen. Repair policy outside the TUI, then:
|
||
|
||
1. `reconcile` reconnects and queries retained host receipts through the relay.
|
||
It does **not** resend policy-blocked operations or prove policy is repaired.
|
||
2. `operations` shows any recovered terminal result. If still UNKNOWN and retry
|
||
is appropriate, use `retry <number>` for the displayed operation, and confirm
|
||
`yes` after reading the warning. This attempts the original signed encrypted
|
||
event **once**, preserving its ID, fingerprint, body and revision preconditions.
|
||
3. A repeated denial stays blocked; another attempt requires another explicit
|
||
action. Even a successful socket send leaves UNKNOWN until a matched host receipt.
|
||
|
||
Retry does not clear the durable automatic-retry block, cancel remote work, mint a
|
||
replacement ID, update stale revisions, or re-sign an expired/invalid event. If the
|
||
original event can never be admitted, continue reconciliation; there is no honest
|
||
terminal result to invent. The development envelope has no built-in expiry, but
|
||
external policy may still reject it permanently. Keep the retained intent. Journal
|
||
retention (1,000 operations), pruning/log-full and host-crash recovery remain unfinished.
|
||
Ordinary transient loss still has bounded automatic unchanged replay. Quit changes
|
||
only UI transport lifetime, never the pending operation or host lifecycle.
|
||
|
||
**Do not point fixture mode at real agents.** This seam deliberately passes no
|
||
agent key, OAuth context, or model to the fixture. It passes only the selected
|
||
nonsecret behavior override for external-boundary acceptance. Executable trust
|
||
is a local operator decision; remote messages cannot supply executable/args/env.
|
||
The runner must remain within its process group. Escaping descendants require
|
||
stronger OS containment before arbitrary harness support.
|
||
|
||
## Relay boundary and trust
|
||
|
||
The loopback diagnostic protocol described below is separate from normal private
|
||
host setup. Normal host/owner management uses NIP42 plus NIP44/59 with independent
|
||
signers on the configured relay; see FIRST_DEMO.md. It neither shares the owner
|
||
secret with the host nor uses the diagnostic relay as a fallback.
|
||
|
||
Dedicated loopback-only WebSocket relay, not a Nostr relay, and no reserved kind
|
||
numbers. All application traffic is runtime-validated, Schnorr-signed and
|
||
AES-256-GCM-encrypted using a domain-separated owner-secret-derived key. The
|
||
relay is provisioned with only the owner public key, verifies publications and
|
||
stores ciphertext atomically before fanout. Local unauthenticated readers can
|
||
receive ciphertext and traffic metadata; this is NOT hosted private admission.
|
||
The protocol must receive independent cryptographic review before deployment.
|
||
Existing Buzz clients cannot consume these messages. Hosted compatibility needs
|
||
an independently validated private relay route/protocol decision; adding an
|
||
arbitrary Nostr kind is not an admission solution.
|
||
|
||
One dedicated owner shares signing/decryption authority with fully trusted host
|
||
installations. Host IDs route messages; they are NOT cryptographic host proof.
|
||
Agent identities are generated separately and only locally. Standby key import
|
||
attaches to an existing public genesis; only explicit experimental source-consumed Move can transfer assignment. Setup refuses an existing host directory; saved journal
|
||
bindings prevent owner/agent/host replacement from resetting admission.
|
||
An owner can still bypass software by cloning/recreating installations: safety
|
||
assumes non-cloned, non-rollback, exclusively supervised installations.
|
||
|
||
## Lifecycle claims and deliberate limits
|
||
|
||
- Exact operation ID/fingerprint and revision preconditions; durable admission
|
||
before effects, persistent replies/outbox, idempotent replay. No exactly-once
|
||
claim. Fixture Start means process spawned; ACP Start additionally requires probe evidence, **not Buzz conversation readiness**.
|
||
- Immutable captured selection/executable digest; executable and workspace
|
||
prerequisites checked immediately before fixture launch. Executable replacement
|
||
between check and spawn is outside this trusted-operator preview; full prepared
|
||
launch must pin all setup/credential/script generations and close that gap.
|
||
- Stop uses a live TypeScript group anchor and private in-lifetime IPC channel.
|
||
The anchor outlives the external runner, preserving group identity if its leader
|
||
exits. Stop asks that anchor to signal its own group, retaining the living anchor
|
||
through a 500 ms TERM grace period before ownership-safe KILL escalation, then confirms group absence;
|
||
it never sends a kill to a recovered or possibly reused numeric ID. Quarantine
|
||
preserves this teardown route. A lost anchor fails closed and retains the lock.
|
||
This is POSIX in-group supervision, not containment of escaping descendants.
|
||
- Interrupted operation replies report reconciliation required. Abrupt host death
|
||
leaves an exclusive lock: restart is blocked, not an automatic PID-based
|
||
takeover. Local recovery tooling and crash-injection coverage remain pending.
|
||
**Do not remove locks just because a PID seems absent.**
|
||
- Local journals are necessary admission/safety/outbox records, not a second
|
||
remote authoring authority. Commands, configurations, receipts and inventory
|
||
cross the relay. Journal schema validation/migration and transactional scaling
|
||
remain pending; current journal is operator-trusted local state.
|
||
- Relay history max 10,000 envelopes, per-envelope limit, slow-reader disconnect.
|
||
Log full closes publisher; no compaction. Outbox retained without ACK pruning;
|
||
host auto-reconnect replays saved receipts and relay history with operation-ID
|
||
deduplication (eight attempts/lifetime, bounded backoff). Per-event relay ACKs remain absent. Durable
|
||
TUI pending intents/reconnect are implemented with a local encrypted journal. Lost connection means
|
||
unknown, not stopped or success; exhausted recovery needs operator attention.
|
||
- Inventory has freshness, not liveness proof. Host starts no action based on peer
|
||
agent presence. Only its locally bound slots are manageable; each has independent authority,
|
||
revisions, receipts, admission and process ownership under one installation.
|
||
|
||
## Explicit initial assignment (Move prerequisite, not Move)
|
||
|
||
New local setup writes both setup and authority journal before a host can launch.
|
||
The journal pins a public genesis (owner, agent, initial host, random enrollment
|
||
ID) and a separate assigned-host field. Start/Save/Stop are denied at a standby
|
||
host even with the identical local private key. Stop and service restart retain
|
||
assignment. Startup refuses a missing journal rather than recreating authority
|
||
from a cached key. Lifecycle checks current local key/setup availability before
|
||
Start and never writes keys back; Stop does not need provider auth or a key file.
|
||
|
||
For a second, independently provisioned installation, export only the public root:
|
||
|
||
```sh
|
||
node src/cli.ts assignment-export /absolute/source-host /new/public-genesis.json
|
||
node src/cli.ts setup /new/target-host /local/owner-identity.json /local/agent-key.json /local/public-genesis.json
|
||
```
|
||
|
||
The key file is an owner-only local JSON `{ "secret": "<hex-private-key>" }`,
|
||
provisioned by the local administrator, not sent over the management relay. The
|
||
public root file is also read/written owner-only by these commands. The key must
|
||
match that root; import cannot create a second initial-authority installation.
|
||
No credential, workspace, session or provider configuration is exported. This is
|
||
not existing unmanaged-agent enrollment, nsec parsing or a key-export feature.
|
||
New-key setup remains the ordinary guided command without those optional files.
|
||
|
||
Existing pre-assignment **stopped journals** require explicit local migration:
|
||
`node src/cli.ts migrate-assignment /absolute/host-directory`. Verify there is
|
||
exactly one installation and no unmanaged execution of that identity, then confirm.
|
||
Migration preserves revision, receipts and configuration, uses the host exclusion
|
||
lock and refuses missing journals, unknown execution or an already pinned assignment.
|
||
It cannot recover journal loss, clone/rollback or retire an old installation.
|
||
A partial setup remains inert and requires local investigation, not automatic repair.
|
||
|
||
`agents` groups observations by persistent public key; `hosts` numbers host/agent
|
||
rows, shows reported assignment, and `select` routes to the exact row. A unique host
|
||
name remains a backward-compatible shortcut. Observations are not consensus; an
|
||
unreachable source never makes its standby eligible. The original assignment test uses three distinct installations. The newer
|
||
`slots.test.ts` separately proves two identities in ONE host process/connection;
|
||
these are independent agent slots, not cloned daemons.
|
||
|
||
**Experimental Move path implemented below:** destination local preflight, source
|
||
reservation/Stop, consumed grant/outbox lineage and target acceptance/fresh launch.
|
||
Preflight prerequisites and post-grant actual conversation readiness are separate gates. The root ID
|
||
is an identity binding, not a lock service or partition/rollback solution.
|
||
|
||
## Several agents, one installation
|
||
|
||
Upgrade an existing **stopped**, assignment-pinned installation explicitly, then
|
||
add an independent identity using the same locally trusted harness setup:
|
||
|
||
```sh
|
||
node src/cli.ts migrate-slots /absolute/host-directory
|
||
node src/cli.ts add-agent /absolute/host-directory
|
||
node src/cli.ts host /absolute/host-directory ws://127.0.0.1:19481
|
||
```
|
||
|
||
Both commands ask for confirmation and refuse a live installation lock. Migration
|
||
replaces only setup inventory atomically; the original journal stays byte-identical
|
||
with its assignment, revision, operation receipts and outbox. It never generates or
|
||
copies the existing key. Legacy single-slot hosts still run without silent upgrade.
|
||
Pre-assignment installations must use `migrate-assignment` first. Missing journals
|
||
and partial additions fail closed, not an invitation to re-enroll an identity.
|
||
|
||
`add-agent` creates a NEW key, or accepts local key/root files for a standby import
|
||
using the same optional-file convention as `setup`. Host-owned `default` harness,
|
||
executable/auth context and conversation setup are shared; agent keys are not part
|
||
of that reusable harness. A version-2 owner-only `setup.json` holds one installation
|
||
identity, setup inventory and per-agent key/setup references. New authority journals
|
||
live under `agents/<public-key>/journal.json`; these directories cannot run daemons.
|
||
The original slot keeps its journal in place. Maximum 32 slots per installation.
|
||
Changing local conversation setup requires every slot stopped and updates the shared
|
||
harness; `auth-info` prints the shared service-user context without signing in.
|
||
|
||
Use remote TUI `hosts` then `select <row-number>` to configure/start/stop each agent.
|
||
A host-name shortcut is rejected when ambiguous. `agents` groups persistent public
|
||
identities and labels reported assignment separately from the observing host. Each
|
||
slot retains independent selected-next/actual-run, revision, operation IDs/outbox and
|
||
admission queue. Stop X does not stop Y or change Y's receipt/revision. One host
|
||
process holds ONE installation lock, heartbeat and management connection. Reconnect
|
||
replays each slot's receipts; client reconciliation queries every unresolved
|
||
host/agent pair. Host shutdown attempts every slot even if one is uncertain, reports
|
||
failure and retains the installation lock rather than falsely declaring all stopped.
|
||
|
||
Setup/key enrollment remains local and offline; ordinary selections and lifecycle
|
||
remain remote. Multiple selectable harness inventory entries, profile CRUD, key
|
||
revocation UX and live-provider/production acceptance are still future work. Standby
|
||
X elsewhere cannot Start without a grant, even while source X is stopped/unreachable. This is trusted-installation
|
||
coordination, not physical host attestation, partition safety or exactly-once execution.
|
||
|
||
## Real target: Buzz Agent + Databricks v2
|
||
|
||
Local setup option 2 now takes **buzz-agent**, not buzz-acp. It creates fresh
|
||
owner-only `service-home` and `agent-config` directories beneath the new host
|
||
directory. Existing option-2 setups need deliberate local reprovisioning of the
|
||
runner and these paths; there is no automatic migration or credential import.
|
||
Never substitute an old Desktop configuration/cache.
|
||
|
||
```sh
|
||
node src/cli.ts auth-info /absolute/host-directory
|
||
```
|
||
|
||
This prints the exact shell-quoted executable, HOME, BUZZ_AGENT_CONFIG_DIR and
|
||
DATABRICKS_HOST context, with the host name and current OS uid. **The operator
|
||
must run that command as the same OS user that runs the host service.** It does
|
||
not perform login. Buzz Agent owns normal browser OAuth, cache, client/scopes and
|
||
headless refresh; Beehive does not broker tokens or inherit DATABRICKS_TOKEN.
|
||
No actual account/workspace is preconfigured here. Save and Stop never log in.
|
||
|
||
Start in this preview launches a bounded TypeScript ACP boundary directly to the
|
||
locally selected external executable. It negotiates ACP v1, creates one session,
|
||
reads the catalog, requires `session/set_model` to acknowledge the exact selected
|
||
`databricks-claude-haiku-4-5` **and session ID**, then requests a short greeting on
|
||
that same session/process. Only a completed `end_turn` with same-session text
|
||
produces evidence: session ID, exact model, executable SHA-256 and response hash.
|
||
Text, raw diagnostics, names/descriptions and credentials are not published.
|
||
Selected-next is independent of the running session; the process remains owned
|
||
until Stop. Auth/protocol failures do not become accepted Start.
|
||
|
||
**This is an ACP integration probe, NOT yet a conversational Buzz relay agent.**
|
||
The persistent Beehive agent key binds host authority but is not supplied to this
|
||
stdio-only probe, and this unconfigured path does not use the conversation broker. Model
|
||
acknowledgement is the trusted external executable's claim, not cryptographic
|
||
provider/model attestation. Only deterministic external ACP fixtures have passed;
|
||
no credentialed Databricks response, live account or installed binary ACP
|
||
capability negotiation was observed. Installed `/Applications/Buzz.app/Contents/
|
||
MacOS/buzz-agent --help` with a fresh isolated HOME/config returned provider-required
|
||
(exit 2); that is executable discovery, not an ACP capability test.
|
||
|
||
The narrow protocol seam is grounded in pinned main `051c3a2`:
|
||
`crates/buzz-agent/src/lib.rs` initialize (349), session/new (500–610),
|
||
session/set_model (633–682); `config.rs` BUZZ_AGENT_MODEL (642), Databricks token
|
||
optional (676), `databricks_v2` selector (939); `llm.rs` effective-model request
|
||
routing (85–147). No unmerged `BUZZ_ACP_REQUIRED_MODEL` flag is used.
|
||
|
||
**Catalog uncertainty is explicit.** `not-probed`, `reported`, `empty`, `filtered`
|
||
and `failed` are distinct, but all currently carry authentication `unverified`:
|
||
main's session/new can return a configured-model fallback after an OAuth or
|
||
network discovery failure. A reported/empty catalog cannot establish authenticated
|
||
availability or distinguish refresh-expired/denied/no-credential. That diagnostic
|
||
seam remains missing in the external protocol; do not relabel it authenticated.
|
||
An empty/filtered catalog does not prevent trying an explicitly saved exact model;
|
||
only same-session acknowledgement plus completed response establishes probe evidence.
|
||
|
||
## External conversation setup (ordinary Buzz CLI tools)
|
||
|
||
`node src/cli.ts conversation-setup /absolute/existing-host-directory` attaches
|
||
an installed **buzz-acp** and separate conversation relay to the SAME existing
|
||
agent key. Close the host first; setup uses its exclusion lock. It never reads
|
||
owner profiles, performs sign-in or regenerates an identity.
|
||
|
||
Start now uses a private per-run TypeScript ACP broker. External buzz-acp owns
|
||
Buzz authentication, membership, mentions and dispatch; its detached childless
|
||
stdio shim cannot choose executables/env/keys. The host separately owns the actual
|
||
harness process group. The proxy enforces exact-model acknowledgement at each
|
||
conversation session boundary and hashes the actual completed response, never a
|
||
separate greeting. Start waits up to 30 seconds for a real inbound conversation;
|
||
missing relay admission or local sign-in fails Start. Stop tears down all retained
|
||
runtime/harness groups and confirms shim exit. No raw text or credentials enter
|
||
management observations. This is not provider attestation or delivery proof.
|
||
|
||
Both external process-contract fixtures and the installed buzz-acp have exercised
|
||
this broker. The installed-binary test uses fresh fixture identities and an
|
||
isolated NIP-42/NIP-29 relay fixture, not a real community or provider. That binary
|
||
subscribes to legacy kind 9; this is not current Buzz relay compatibility evidence.
|
||
**An actual signed threaded reply is now observed** through the installed Buzz CLI
|
||
in that isolated test, with a deterministic ACP harness (not a live model). Local
|
||
`conversation-setup` can optionally provision a canonical Buzz CLI executable.
|
||
The fixed stdio MCP `buzz({argv, stdin})` tool passes native arguments to that CLI
|
||
under the provisioned agent identity. Use its `--help` to discover operations.
|
||
The existing CLI owns member/mention/thread semantics; no local channel, parent,
|
||
or recipient setup is required when another owner conversation arrives.
|
||
Explicit hex `--mention` supports authorized non-owner channel members too.
|
||
Implicit display-name mention behavior remains the installed CLI's contract and
|
||
has not been validated here.
|
||
|
||
The host rejects caller executable/env/MCP provisioning and relay/signer/attestation
|
||
flag overrides. There is no shell parser or HTTP/SSE MCP support. Native CLI
|
||
operations (including file operations) have local service-process authority, not
|
||
an OS sandbox. Old single-thread tool configurations require explicit rerunning of
|
||
`conversation-setup`; they are not silently broadened. MCP shims remain childless
|
||
and every actual CLI group retains its own host anchor through cleanup. Bounded
|
||
stdout reaches the model for reads; stderr stays withheld. Ordinary CLI errors are
|
||
tool errors, not a reason to destroy a healthy conversation.
|
||
|
||
Installed isolated validation covers two channels/threads and a later prompt in
|
||
the first thread, three signed replies under one agent identity, native channel
|
||
reads, non-member mention rejection and owner-only incoming dispatch. No local
|
||
reconfiguration or key generation occurs between prompts. This new surface still
|
||
has received independent tool/reconnect review; its R1 and later journal U1
|
||
recovery corrections are recorded in CHECKPOINT.md with exact evidence and limits.
|
||
|
||
Community admission/attestation and normal OAuth in the named host-service context
|
||
remain explicit local/operator actions. No live Databricks request has occurred.
|
||
|
||
## Supported / remaining parity
|
||
|
||
| Surface | This slice | Required next work |
|
||
|---|---|---|
|
||
| Local owner/key setup | New owner + separately generated agent key; deliberate local agent-key removal keeps a retained public-only slot | nsec import, saved-owner verification, remote revocation/key-removal UX |
|
||
| Host inventory | Real relay, multiple independent slots, shared host harness, freshness | multiple selectable setups, service install, richer reconciliation |
|
||
| Remote configuration | CAS model/workspace + reusable immutable profile publication/application; captured actual-run history | named launch configurations, metadata, setup revision pinning, retention UI |
|
||
| Lifecycle | Start/Stop/Restart and experimental source-consumed conversation Move, UI-independent host | production admission/live-provider acceptance, installed-conversation Restart acceptance |
|
||
| Buzz Agent Databricks v2 | Local setup + TypeScript ACP probe boundary | live OAuth/model proof, production protocol compatibility and catalog provenance |
|
||
| Other Buzz Agent providers | Not implemented | Anthropic, OpenAI-compatible, Databricks legacy, OpenRouter |
|
||
| Goose / Claude Code / Codex | Not implemented | harness-specific local auth and adapters/catalog/launch |
|
||
| Ten presets / custom ACP | Not implemented | explicit executable/env trust, preset-specific capability grounding |
|
||
| OpenClaw Gateway | Not implemented | external containment/environment boundary |
|
||
| Relay mesh LLM mode | Not implemented | separate transport integration, not generic provider alias |
|
||
| Compute deployment providers | Not implemented | assess `buzz-backend-*` separately from LLM providers |
|
||
|
||
None of the remaining rows is an owner-approved exclusion from the requested
|
||
full parity. Review actual executable UX/security/lifecycle before expanding.
|
||
|
||
## Experimental identity-bearing conversation Move
|
||
|
||
On two separately provisioned, trusted installations with the SAME agent key and
|
||
pinned public genesis, use `hosts`, select the source agent row, then `move` and
|
||
confirm the destination. Hosts exchange preparation/grants over the existing relay;
|
||
the TUI sends intent only. Target selection uses its locally configured allowed
|
||
model/workspace/profile. No key, workspace, credential or conversation session moves.
|
||
The source receipt means **source consumed + grant durably queued**, NOT destination
|
||
process exit/start evidence. Observe target inventory separately.
|
||
|
||
The source retains an irreversible grant chain/outbox after Stop. A destination
|
||
accepts an exact successor once before fresh Start; missing/changed prepared inputs
|
||
leave it assigned but stopped. Retry/inspect replays the grant without restoring the
|
||
source. A stopped or unreachable source does not authorize a standby by itself.
|
||
Preflight validates local key/setup, allowed selection, canonical executable hashes,
|
||
script inputs and workspace identity. Identity-free bounded `--help` runs check the
|
||
installed runtime and CLI contracts. An independently owned ACP greeting probe checks
|
||
usable local harness/model/auth prerequisites without any signer, relay or tools.
|
||
It is completely stopped before publishing preparation. Catalogs can be fallback
|
||
metadata; neither catalog nor this probe proves a **future** conversation will work.
|
||
Inventory labels preparation separately; it never becomes actual-run evidence.
|
||
|
||
After irrevocable grant the fresh target conversation must independently satisfy the
|
||
existing broker's exact requested model/session acknowledgement and completed response.
|
||
Failure leaves target assigned/stopped (or quarantined if teardown is uncertain), never
|
||
source resurrection. Restart/replayed preparation preserves the original immutable
|
||
grant binding; lost live readiness forbids automatic launch but not target acceptance.
|
||
A new Move operation is required to retry a preflight whose target lifetime ended.
|
||
|
||
`installed-move.test.ts` proves two real host processes, installed buzz-acp + Buzz CLI,
|
||
same locally provisioned signer, source exit before grant delivery/target actual spawn,
|
||
then signed target replies with correct channel/parent/recipient and same-run model
|
||
completion. It also injects actual model rejection only after grant: target stays
|
||
assigned/stopped, source cannot Start. Model/provider remain deterministic fixtures;
|
||
no actual Databricks/login/community calls or production kind-40002 proof.
|
||
|
||
**Scoped exit barrier supported:** independent `MOVE_REVIEW_97A9050A.md` source review
|
||
and grant-time runner/TERM-resistant-descendant ESRCH evidence establish the current
|
||
exclusively supervised POSIX in-group barrier. Broker-owned harness/tool groups and
|
||
childless shims retain their separate teardown checks. This is not arbitrary escaped
|
||
process containment. The historical unrecorded PID failure remains unclassified; a
|
||
new reviewer observation was empty bytes converted to PID 0, not a live descendant.
|
||
Fixture spawn now validates a positive PID and publishes it atomically. ESRCH and
|
||
bounded failure diagnostics remain, without added teardown delays or weaker assertions.
|
||
Trust requires dedicated non-cloned/non-rollback installations, exclusive supervision
|
||
and local provisioning; shared owner signatures do not attest physical hosts. No
|
||
exactly-once/partition-safe transfer, workspace/session transfer or full parity claim.
|
||
|
||
## Explicit remote Restart (incremental)
|
||
|
||
Select the assigned agent row, then enter `restart`. No operation ID or config JSON
|
||
is needed. Restart uses the existing durable relay intent/receipt journal and the
|
||
same per-slot assignment, revision and Stop-cancellation authority as Start/Move.
|
||
It captures selected-next, validates local inputs before stopping, and (for ACP)
|
||
performs a bounded identity-free model/auth prerequisite probe while the old run
|
||
remains owned. Probe teardown completes before old-run teardown and fresh launch.
|
||
This does not claim future conversation readiness or provider attestation.
|
||
|
||
Missing local setup/key or failed prerequisite preserves the existing actual run.
|
||
After old-run exit, failures leave assigned/stopped (or quarantined for uncertain
|
||
ownership), never a fallback run. An admitted Stop cancels pending Restart; queued
|
||
Save cannot mix inputs and receives a revision conflict after successful Restart.
|
||
Retry of the same operation replays its result, not another launch. Setup/credential
|
||
stores remain local, and Restart never recreates a key. Trusted local executable
|
||
replacement between final validation and spawn remains outside this preview.
|
||
|
||
Current tests exercise actual two-agent TUI Restart X with Y's journal unchanged,
|
||
fixture replay, missing setup and delayed ACP prerequisite cancellation. Named
|
||
behavior profile authoring/revisions and actual applied-instruction evidence are
|
||
now implemented by the continuation below. Installed
|
||
conversation Restart-specific acceptance remains to add; installed Move/Start tests
|
||
remain separate reusable evidence, not a claim that this whole journey is complete.
|
||
|
||
## Named behavior profiles (0aa71)
|
||
|
||
Everyday workflow in the TUI:
|
||
|
||
1. `profile-new`: enter a name and **nonsecret** behavior instructions; review and
|
||
confirm publication. The form is a draft until confirmed. No provider/model,
|
||
executable, workspace, key, credential or OAuth fields exist in a profile.
|
||
2. `profiles`: numbered immutable versions, parents and instructions. `profile-edit
|
||
<number>` publishes a new child of that exact version. Concurrent edits remain
|
||
explicit branches; neither timestamps nor arrival order choose a latest version.
|
||
3. `hosts` → `select <number>` → `apply <profile number>` selects that exact revision
|
||
for that agent at its advertised expected revision. `save` also accepts a profile
|
||
number (first run `profiles`) alongside allowed model/workspace. Host acceptance
|
||
is distinct from publication. `show` names agent, host, current and selected-next.
|
||
4. `start` or explicit `restart` captures the selected snapshot. Editing/publishing
|
||
or applying while running never restarts anything, changes actual instructions,
|
||
touches another agent's journal, or creates/restores credentials.
|
||
5. `apply default` explicitly clears the override for selected-next only. No delete
|
||
operation exists: historical revisions and running snapshots cannot be stranded
|
||
or silently switched. Retention/archiving is future work, not destructive CRUD.
|
||
|
||
**Authority:** `src/profiles.ts` is the sole profile codec/lineage projection. The
|
||
existing authenticated encrypted relay publications are definition truth, scoped by
|
||
relay/owner; hosts and UI replay that same read-only projection. Content addresses
|
||
cover canonical name, explicit parent and instruction bytes. There is no mutable
|
||
host/CLI/broker profile database or new controller. The assigned host alone accepts
|
||
per-agent association changes using existing Save/CAS/receipt durability. Missing
|
||
or conflicting lineage remains incomplete, never executable. Publication completion
|
||
means the relay observed the immutable event, NOT any agent applied it. Unsent
|
||
publications use the existing encrypted client intent journal and unchanged replay.
|
||
|
||
A selection contains the validated complete profile revision, not a floating name.
|
||
The existing Start/Restart/Move preparation token covers those effective instructions.
|
||
Move preserves the source's selected public behavior while choosing target-local
|
||
launch settings; target keys/workspace/session are never copied. Later catalog
|
||
publications cannot change an asynchronous preflight or accepted historical selection.
|
||
Successful runs retain immutable full snapshots in the existing per-agent journal;
|
||
Stop/Restart cannot overwrite them. Inventory exposes the last eight run IDs/revision/
|
||
instruction hashes; actual-run carries full selected instructions plus prepared-input
|
||
hash. Legacy journals/default selections need no migration and gain no invented old
|
||
run evidence. `upstream-default` deliberately records no fabricated default-text hash.
|
||
|
||
The host passes exact captured instructions through upstream `BUZZ_AGENT_SYSTEM_PROMPT`
|
||
and installed `BUZZ_ACP_SYSTEM_PROMPT`. These are behavior inputs, never authorization
|
||
for lifecycle, membership, tools or destinations. Existing owner-only dispatch,
|
||
model-before-prompt and fixed CLI authority remain unchanged. Applied-instruction
|
||
hash covers the explicit override, **not** all upstream orientation/memory/history.
|
||
External fixture logs prove received bytes; installed conversation acceptance also
|
||
observes the marker in the actual runtime-generated ACP prompt. No live-model
|
||
obedience or production kind-40002/admission/OAuth claim follows from that evidence.
|
||
|
||
Bounds: 2 KiB UTF-8 instructions, 1,000 catalog versions, 100 parent edges, 1,000
|
||
retained successful runs per agent. Start/Restart refuse when run retention is full;
|
||
Stop remains available. Wire payload checks and a conservative Move lineage budget
|
||
refuse oversized new work before consuming source authority. No automatic pruning.
|
||
The TUI currently uses a one-line instruction form; protocol supports line breaks.
|
||
Named launch configurations, local key/setup CRUD and a small harness-specific wizard,
|
||
Desktop harness/provider/preset/custom/mesh/compute parity, final real-TUI UX/live
|
||
acceptance and independent review remain broader work, not completed by profiles.
|
||
|
||
## Named launch configurations and shorter first setup
|
||
|
||
`setup <new-host-directory> <identity-file>` now directly produces the shared-slot
|
||
installation. Choose the fixture or Buzz Agent Databricks v2 harness, provision its
|
||
local executable and one or two allowed workspaces, then create independent agent
|
||
identities reusing **one harness setup**. The wizard shows the intended service uid,
|
||
HOME/config directory and provider login mechanism before confirmation (no login is
|
||
performed). Each extra identity is a deliberate yes/no choice, not another provider
|
||
setup. Optional owner-only key/root file import remains standby-only. Existing hosts
|
||
still use explicit stopped `migrate-slots`/`add-agent`; this does not reset them.
|
||
No extra migration command is needed for a newly created host.
|
||
|
||
In the remote TUI, select the exact host/agent row, then:
|
||
|
||
- `config-new`: name a copy of selected-next, using the **same key and harness setup**.
|
||
The new configuration becomes selected-next after host acceptance.
|
||
- `save`: edit the selected configuration's advertised model/workspace and profile.
|
||
- `configurations`: list the bounded, host-owned named candidates and their revisions.
|
||
- `config-select <name>`: select an existing candidate without editing it.
|
||
- `config-rename`: rename a candidate; old actual snapshots keep their old names.
|
||
- `config-remove <name>`: remove an inactive candidate. Select another first if it
|
||
is selected. Removal never removes run history, assignment or keys.
|
||
- `show`: inspect selected-next, immutable actual run and recent historical
|
||
configuration/model/workspace/instruction/prepared-input fingerprints.
|
||
- Explicit `restart` applies the captured selected candidate; Save/select never
|
||
restarts. Creating/selecting a configuration never creates/imports a key.
|
||
|
||
All mutations are existing durable Save operations with agent/host/revision CAS,
|
||
receipts and unchanged-envelope retries. Configuration revisions come from the
|
||
agent journal revision, so removing/recreating a name cannot reuse an applied
|
||
revision. Maximum 32 candidates / 8 KiB combined public candidate data. Unsupported
|
||
model/workspace/profile is rejected by the owning host. One local harness setup per
|
||
slot is selectable in this increment; multiple configurations may differ in allowed
|
||
workspace or behavior. Multiple selectable harness setups and richer models/settings
|
||
remain work, not generic-provider parity.
|
||
|
||
Legacy selected-next is projected as `default` without rewriting its actual run or
|
||
inventing historical names/revisions. First accepted Save materializes the registry
|
||
in the same atomic journal persist as selected-next and the receipt. Historical
|
||
runs without a configuration tag remain explicitly legacy/unversioned data.
|
||
|
||
Standby public configuration is now remotely editable, **not execution permission**.
|
||
Start/Restart/Stop/Move remain assignment-fenced. Move requires the exact target
|
||
candidate revision and local settings while retaining source-selected public behavior.
|
||
If a target Save is accepted after preparation but before the consumed grant arrives,
|
||
the target accepts the assignment **stopped**, keeps that later selected-next, and
|
||
requires a fresh explicit Start. It never launches mixed inputs, discards the accepted
|
||
Save, strands the grant, or resurrects the source. Old prepared/grant evidence remains
|
||
immutable. Normal successful Move still captures the exact prepared candidate.
|
||
|
||
**Still unfinished:** full import/reuse wizard UX,
|
||
local setup CRUD/multiple selectable setup bindings, Goose/Claude Code/Codex/vendor
|
||
login/ACP adapters, other Buzz Agent providers, ten presets/custom ACP, mesh/compute,
|
||
production admission and normal service-user OAuth/live exact-model proof. The wizard
|
||
has working fixture and existing Buzz Agent Databricks paths; the fixture is **not**
|
||
a second Desktop harness. No new provider path or live login has been verified here.
|
||
|
||
## Deliberate local key removal (public-only slots)
|
||
|
||
`remove-agent-key <host-directory> [agent-public-key]` deliberately deletes ONE
|
||
installation's local copy of an agent key while the host is stopped (it refuses a
|
||
present installation lock — no PID or stale-lock removal — and requires a stopped
|
||
slot with no actual run). The public identity, genesis/assignment, configurations
|
||
and the complete journal/receipt/run history stay in place as a **public-only
|
||
slot**; siblings and the owner identity are untouched. Only the `agentSecret` in
|
||
the 0600 manifest becomes `null`; shared harness inventory is validated to never
|
||
carry key material (a migrated manifest that did would silently re-arm a removed
|
||
key and now fails closed).
|
||
|
||
After reopen, inventory advertises the missing-key slot (`localKey` removed) with
|
||
its retained identity and history. `start`/`restart` reject **before any spawn**
|
||
until an explicit local repair — the execution credential is an optional loader,
|
||
never regenerated or inferred. `stop`/`save`/inspect/reconnect stay
|
||
credential-neutral and truthful; ordinary save/lifecycle/recovery never recreate
|
||
the key. `add-agent` refuses to recreate the public-only identity; `remove-agent-key`
|
||
again is an explicit no-op error. `assignment-export` still exports the public
|
||
genesis for a public-only slot. `conversation-setup` and legacy key-less
|
||
installations fail closed.
|
||
|
||
Move honors the removal on both sides: a Move **to** a missing-key destination
|
||
fails its destination preflight before the source Stop, preserving the running
|
||
source; a Move **from** a public-only source still consumes its retained
|
||
management authority — the destination launches with its own local key, no
|
||
secret transfer or recreation. This is a local copy removal, not a global
|
||
cryptographic revocation: no nsec is transferred, and no remote key CRUD exists.
|
||
Local re-provisioning requires explicit local reconciliation.
|
||
|
||
### Named Move identity contract
|
||
|
||
Profiles are independent behavior revisions; a named launch configuration identifies
|
||
an exact per-agent effective snapshot. Move takes source-selected public behavior and
|
||
target-local launch settings. A `named-v1` grant binds the derived new named revision
|
||
and the exact prepared snapshot, not merely the destination's previous display label.
|
||
Preparation durably reserves `max(target revision + 1, old named revision + 1)` before
|
||
replying; cancelled preparations can leave gaps. The legacy implicit default@1 is
|
||
materialized by this same rule, rather than leaving an unnamed selection divergent
|
||
from its projected named inventory. The previous target definition stays
|
||
in immutable preparation evidence. Acceptance atomically materializes inventory and
|
||
selected-next, and actual/history retain full snapshots. A later Save gets a later
|
||
revision, is never overwritten, and forces consumed-grant acceptance to remain stopped.
|
||
Reservations alone never confer Start authority. Legacy saved grant/event identity hashes
|
||
are not changed or re-signed; new materialization requires compatible host versions.
|
||
|
||
### Explicit local key reuse for a retained public-only slot
|
||
|
||
`node src/cli.ts import-agent-key <host-directory> <agent-public-key>` is a small
|
||
local repair wizard: confirm the public identity, then paste the exact 64-hex
|
||
private key at a **hidden** prompt. Never put the private key in argv, environment,
|
||
a remote message or terminal transcript. Protected piped stdin is supported;
|
||
the key is never printed. It restores only a previously removed local copy, not
|
||
an unknown identity or an assignment. The host must be stopped and its lock free.
|
||
A valid retained journal is mandatory; wrong keys, missing/malformed authority,
|
||
non-stopped slots and already-present keys refuse without modifying state.
|
||
Standby or consumed-source import does **not** grant Start. All retained history,
|
||
public configuration, sibling keys and journals remain unchanged. Ordinary remote
|
||
Save/Start/Restart still never recreate removed keys. This is deliberate local
|
||
provisioning, not global revocation/rotation or restoration of compromised authority.
|
||
|
||
This increment does not yet integrate import/new/reuse into the initial setup
|
||
wizard, manage multiple local harness bindings, or add Goose. Those, remote A/B
|
||
selection with immutable applied inputs, and remaining Claude/Codex/preset/custom/
|
||
mesh/compute parity remain unfinished. Existing file-based standby enrollment is
|
||
unchanged; no provider login/cache access or live-provider acceptance is claimed.
|
||
|
||
## Small local binding / identity wizard
|
||
|
||
After initial `setup`, run `node src/cli.ts local-setup <host-directory>` offline.
|
||
It lists existing binding IDs/fingerprints and public identities (never keys), then
|
||
performs **one** chosen action:
|
||
|
||
- `reuse`: choose an existing identity without any mutation or key recreation;
|
||
use the remote TUI for normal public selection/configuration/lifecycle.
|
||
- `new-agent`: choose an existing binding and confirm an independent NEW identity.
|
||
- `restore-key`: select a retained public-only identity and enter its exact key at
|
||
the existing hidden prompt. Assignment/history stay unchanged; no standby Start
|
||
authority is created. Unknown-identity enrollment still uses the explicit public
|
||
genesis/file-based standby path, not this restoration action.
|
||
- `add-binding`: select a compatible existing harness definition, enter a NEW ID,
|
||
local executable and allowed workspace (fixture additionally asks for its script).
|
||
The existing harness mode, service-user auth context and conversation authority
|
||
are retained. This does not add another provider/harness or authenticate anything.
|
||
Confirming saves only the binding; reopen the wizard to create an agent using it,
|
||
or select it remotely for an existing identity. Cancel leaves no draft writes.
|
||
|
||
Edits deliberately create NEW binding IDs/revisions; no in-place edit or removal
|
||
is advertised. Historical/current references remain valid. Each mutation takes
|
||
atomic `host.lock`, including exclusion against a competing host start; changed
|
||
source definitions reject under that lock rather than saving a stale draft.
|
||
No long-held lock during prompts. New agent journal staging remains inert until
|
||
its atomic manifest activation; interrupted staging requires local reconciliation.
|
||
|
||
Actual CLI acceptance now follows initial setup → local binding B wizard → remote
|
||
TUI A/B selection → explicit Restart B with the same identity/profile, stable A
|
||
history and unchanged sibling journal. A separate CLI journey covers new/reuse and
|
||
hidden exact-key restoration. This is a small existing-installation wizard, not a
|
||
universal provider form or complete initial-setup/import unification. Goose, Claude,
|
||
Codex, other providers, presets/custom/mesh/compute and live auth remain unfinished.
|
||
|
||
## Goose and one local entry (768f increment)
|
||
|
||
`setup <new-directory> <owner-identity-file>` now offers **3 Goose**. Configure the
|
||
installed Goose executable locally (launched as `goose acp`), its provider ID and
|
||
operator-approved compatible exact model IDs. The wizard creates a dedicated
|
||
0700 `service-home`; Goose owns its provider configuration and credentials under
|
||
that HOME, independently of Buzz Agent OAuth. `auth-info <host> [binding-id]`
|
||
prints the corresponding service-user context without login or credential reads.
|
||
No executable-found/authenticated equivalence or provider-catalog claim is made.
|
||
|
||
At initial identity confirmation choose `yes` for a NEW independent identity,
|
||
`no` to cancel, or `import-standby` for a local public genesis + hidden exact key.
|
||
Standby possession never grants Start. An existing retained public-only identity
|
||
must instead use explicit `restore-key`, not ordinary Save or re-enrollment.
|
||
`setup <existing-host>` is the same entry as `local-setup <existing-host>` and
|
||
rejects replacement owner arguments. It lists identities and immutable bindings;
|
||
choose reuse/new-agent/import-standby/restore-key/add-binding/add-goose/cancel.
|
||
Every mutation is a separate explicit confirmation. Add a compatible Goose binding
|
||
with a dedicated pre-existing service HOME; new binding IDs replace old definitions
|
||
without destructive edits or rewriting actual/history. Then remotely `binding <id>`,
|
||
choose an advertised compatible model, Save and explicitly Restart. No remote
|
||
credential/env/executable fields or new provider registry have been added.
|
||
|
||
This narrow Goose path is grounded in pinned Buzz 051c3a2's Desktop catalog and ACP
|
||
client, not a promise about every Goose version. It does **not** send Goose the Buzz
|
||
Agent-only `session/set_model` acknowledgement contract. Fresh session native model
|
||
configOptions must report the exact selected model and advertise it. Stable model
|
||
configuration responses must confirm it again; unknown/mismatch/missing evidence
|
||
fails closed. Goose profile delivery uses `_goose/unstable/session/system-prompt/set`.
|
||
Compatible models are locally approved, not discovered/authenticated automatically.
|
||
Preflight response is not a guarantee of future provider or conversation readiness.
|
||
|
||
Validation uses a **Goose-shaped TypeScript ACP fixture**, not live Goose. Actual
|
||
CLI/wizard -> remote TUI -> selected-setup ACP Restart is exercised. Separately,
|
||
actual installed buzz-acp and Buzz CLI execute through the same conversation broker
|
||
against that fixture, producing three signed replies with native model/profile
|
||
mechanics. The uninterrupted wizard-to-installed-conversation journey remains a
|
||
validation gap. Kind-9 isolated relay acceptance is not current production kind-40002.
|
||
Full Claude Code/Codex/provider/preset/custom/mesh/compute parity remains incomplete.
|
||
|
||
## Normal local conversation wizard (A661)
|
||
|
||
Initial `setup` for Goose/Buzz Agent now asks **normal (default)** versus explicit
|
||
**diagnostic ACP probe**. Normal collects canonical installed buzz-acp and Buzz CLI
|
||
paths and a trusted conversation relay, validates local launch prerequisites under
|
||
`host.lock`, and provisions conversation mode in the initial definition. There is
|
||
no separate conversion command between initial setup and remote Start. Missing
|
||
runtime/tools fail with local-install/cancel/diagnostic guidance; executable presence
|
||
is not provider authentication or relay admission. Hidden standby import retains its
|
||
original assignment and does not gain Start authority.
|
||
|
||
For an existing diagnostic agent, remotely select the desired ACP binding (including
|
||
non-default B), stop execution and shut down the host service, then run
|
||
`local-setup <installation>` and choose `normal`. It captures that agent's selected
|
||
binding, asks for a **new immutable binding ID**, and commits under the same atomic
|
||
installation lock after revalidating every stopped slot, retained authority/key and
|
||
source fingerprint. Reopen the host/TUI, select the exact host/agent and use
|
||
`binding <new-id>` (ordinary public revision CAS), then explicit Start/Restart.
|
||
Local conversion never changes any agent's selection, actual run or journal.
|
||
|
||
One fsynced manifest replacement pins installation-owned conversation runtime,
|
||
relay/tool/trust and activates the new binding together. Existing binding snapshots
|
||
and fingerprints retain their meaning; diagnostic references still opt out. Normal
|
||
binding snapshots must equal the pinned common authority, not an independently
|
||
editable per-binding authority. Existing authority is reused, never silently retargeted
|
||
or widened. Legacy `conversation-setup` refuses in-place definition rewriting and
|
||
points to explicit migration and this wizard. New/import/reuse remain key-independent
|
||
of model definitions; no key/session/credential transfer or provider login is added.
|
||
|
||
Installed acceptance uses the retained TypeScript Goose-shaped harness, actual
|
||
installed buzz-acp/Buzz CLI and isolated legacy-kind9 relay: initial normal and
|
||
selected-B conversion, TUI Start/Restart, exact profile/model, same-agent signed
|
||
cross-channel/later replies, old definition/history/Y preservation and wrong-model
|
||
preflight/replay/Stop controls. Production `host()` is in-process, not a service
|
||
subprocess deployment proof. Real Goose/provider, current-kind40002 admission,
|
||
Claude/Codex/other providers/presets/custom/mesh/compute and startup-signal cleanup
|
||
remain unfinished; see CHECKPOINT for the exact full gate, not a full-product claim.
|
||
|
||
## Claude Code: bounded API-key local binding
|
||
|
||
Initial `setup` offers **4 Claude Code** with normal conversation as default;
|
||
existing installations use `local-setup` → `add-claude`. Supply canonical installed
|
||
`claude-agent-acp`, canonical `claude` vendor CLI, dedicated service HOME, an
|
||
owner-only API-key file belonging to the host OS user, and approved exact model IDs.
|
||
The wizard never prints/relays the file contents or runs install/login. Missing
|
||
credentials must be provisioned locally. Subscription login, Bedrock/Vertex and
|
||
other Claude auth/provider modes are **not implemented** by this binding.
|
||
|
||
Bindings/keys/profiles are independent: reuse/new/import-standby and existing
|
||
normal conversion operate unchanged; selecting a new binding remotely is
|
||
selected-next only until explicit Restart. Standby still cannot Start. Remote
|
||
configuration cannot provide env/executables/credentials. Fixed installation
|
||
conversation/owner/trust/relay authority does not change with the binding.
|
||
|
||
This preview requires ACP protocol 1 and exact initialize identity
|
||
`@agentclientprotocol/claude-agent-acp` (native `_meta.systemPrompt.append` support).
|
||
`session/new.models.currentModelId` must equal the requested startup model and the
|
||
model must appear in availableModels **in that actual session**, before prompts.
|
||
Missing/mismatched reports fail closed: no native config or unstable set_model is
|
||
invented, no fallback model. Claude load/resume/optional native config are refused;
|
||
model/profile changes need a fresh session via Restart. Drift fails the run.
|
||
Catalog/key/executable presence is not authentication or provider attestation.
|
||
|
||
Source and evidence: `CLAUDE_SOURCE_6F8D.md`. Real installed buzz-acp/Buzz CLI with
|
||
source-shaped TS Claude fixtures passed normal wizard/host CLI/TUI conversations;
|
||
no real Claude/provider login or inference has been tested. Codex remains unfinished,
|
||
as do other providers/presets/custom/mesh/compute and production current-kind40002
|
||
admission/full-product acceptance. This is a coherent Claude subset, not both-harness
|
||
or full provider parity.
|
||
|
||
## Codex: conditional protocol-2 API-key subset
|
||
|
||
`setup` option **5 Codex** supports normal/default or explicit diagnostic purpose;
|
||
`local-setup` → `add-codex` adds a new immutable binding, and `normal` converts the
|
||
selected diagnostic binding to a NEW normal reference. Neither selects nor starts
|
||
it: select the binding/model/workspace remotely and explicitly Start/Restart.
|
||
Supply separately installed codex-acp and codex, an owner-only OPENAI_API_KEY file,
|
||
and dedicated service HOME/CODEX_HOME. CODEX_HOME/config.toml is TOML;
|
||
CODEX_CONFIG is the host's closed JSON model override, not a path. No installation,
|
||
login, owner-cache reading or ChatGPT subscription parity. Missing credentials,
|
||
protocol-2 native profile capability or fresh exact session model evidence fails
|
||
closed before prompting. Save/Stop are credential-neutral. See
|
||
`CODEX_SOURCE_29C7.md` for exact source, fixture/installed evidence and support limits;
|
||
older statements above about entirely unimplemented Codex are historical.
|
||
|
||
### Local preset/custom ACP setup
|
||
|
||
See [PRESET_CUSTOM_SOURCE_8D6D.md](PRESET_CUSTOM_SOURCE_8D6D.md) for the ten
|
||
source-pinned diagnostic presets, owner-only structured custom JSON and wizard
|
||
journey. Preset discovery is not authentication/readiness; arbitrary ACP adapters
|
||
are not assumed to support native model/profile contracts. Only the explicitly
|
||
opted-in Goose-native custom contract has fixture conversation acceptance here.
|
||
|
||
### Buzz Agent API-key providers (local bindings)
|
||
|
||
Normal `setup` option **8** offers Anthropic, OpenAI-compatible and OpenRouter.
|
||
Existing installations use `local-setup` → `add-buzz-provider`, reusing pinned
|
||
conversation authority without selecting or restarting any agent. Supply the
|
||
installed Buzz Agent executable, dedicated service HOME/config directory, allowed
|
||
workspace, owner-only key file, HTTPS provider base URL and operator-approved exact
|
||
models. OpenAI-compatible additionally requires explicit `auto`, `chat` or
|
||
`responses`; OpenRouter is Chat Completions only, Anthropic has no wire override.
|
||
The key variables are respectively `ANTHROPIC_API_KEY`, `OPENAI_COMPAT_API_KEY`
|
||
(**not** `OPENAI_API_KEY`), and `OPENROUTER_API_KEY`.
|
||
|
||
Endpoint, key path/value and service context remain local in immutable bindings.
|
||
Remote users choose a compatible binding/model/workspace and independent profile,
|
||
Save selected-next, then explicitly Start/Restart. No automatic install/login,
|
||
credential probe, key generation or Restart during ordinary management. Operator
|
||
model lists and keyfile presence are not authentication or actual-model proof.
|
||
Source-shaped fixture acceptance does not establish real vendor inference.
|
||
Databricks static-token setup and expanded OAuth diagnostics remain future work;
|
||
existing v2 native service-user OAuth setup remains separate (never copy owner,
|
||
Goose or Claude caches). Preset diagnostics are not provider parity.
|
||
|
||
Model/profile correction: native Buzz Agent's pinned protocol-2 contract carries
|
||
selected instructions in fresh `session/new.systemPrompt`, not just an environment
|
||
fallback. Diagnostic ACP model evidence remains guarded against same-session drift;
|
||
Restart/Move prerequisite evidence is sealed after probe teardown before old actual
|
||
teardown. Installed acceptance uses real Buzz transport/CLI with source-shaped
|
||
TypeScript provider fixtures, not live vendor authentication or inference. See
|
||
CHECKPOINT's MODEL_PROVIDER_CORRECTION entry for validation and observation limits.
|
||
|
||
Public identity editing/publication is separate from private instructions: see
|
||
[PUBLIC_METADATA.md](PUBLIC_METADATA.md) for offline metadata drafts, deliberate
|
||
agent-signed kind0 publication while stopped, and pending/error recovery.
|
||
|
||
### Standalone harness inventory
|
||
|
||
Beehive ships its built-in runtime catalog in `src/harness-contract.json`.
|
||
Desktop is not required. Additional local detection definitions live in
|
||
`~/.beehive/custom_harnesses/*.json` on every platform (under `BEEHIVE_HOME`
|
||
when set). A definition has `id`, `label`, and `command` fields; `command` is
|
||
an absolute executable path or a command name resolved through local discovery.
|
||
Built-in IDs cannot be overridden. Malformed definitions are ignored.
|
||
|
||
Beehive does not read or automatically import Desktop's `custom_harnesses`.
|
||
To reuse a local definition, explicitly copy its JSON into the Beehive directory
|
||
and choose **Refresh harnesses**. Only detection fields are read: launch arguments,
|
||
environment variables, credentials, and Desktop agent state are not imported.
|
||
Refresh replaces the saved inventory; saved runtime configurations are unchanged.
|
||
|
||
### Providers in the OpenTUI manager
|
||
|
||
Providers is available while signed out. Configuration supports OpenAI, Anthropic,
|
||
OpenAI-compatible (endpoint and wire mode), OpenRouter, and Databricks v2.
|
||
Select a saved row, then use Tab or `a` to focus its actions. Arrows select an
|
||
action; Enter runs it. PgUp/PgDn scroll details and the full result.
|
||
Forms use Tab/Shift-Tab, Left/Right choices, Enter to advance/submit, Ctrl-U to
|
||
clear a field, and Esc to cancel. Saved API-key fields open with a fixed mask;
|
||
typing replaces the key, while an untouched field retains it. The mask does not
|
||
read or expose the saved key. API-key input is masked; its value stays in the
|
||
Node controller and credential helper, not renderer state or settings.
|
||
|
||
Edit preserves provider identity and affects future launches. A replacement API
|
||
key gets a fresh exact OS entry; old entries remain for active launch snapshots.
|
||
Blank key input keeps the saved key. Opening Providers checks every saved
|
||
account's model catalog automatically. Saving credentials and completing
|
||
Databricks sign-in recheck the selected account. Each account shows Checking,
|
||
Connected with a model count (including zero), or Failed with recovery steps.
|
||
Connected means catalog access, not model execution. Model IDs are not listed.
|
||
Refresh models is the single manual retry action. Harness and model setup belong
|
||
in agent configuration, not Providers; existing saved runtime records are retained.
|
||
|
||
The Databricks workspace is editable. Its saved HTTPS origin takes precedence
|
||
over `DATABRICKS_HOST`; the variable only prefills new configuration when available.
|
||
Without either, the field starts empty. Changing workspace clears connection
|
||
status and assigns a fresh credential reference; old credentials are not reused.
|
||
Restart and reload preserve the saved choice even if the environment differs.
|
||
Browser sign-in is explicit and uses the packaged native helper. Catalog checks
|
||
may refresh stored credentials but never launch browser authorization.
|
||
Esc stops waiting, not committed storage: inspect/reload before retrying. Quit
|
||
closes the provider controller and cancels its bounded helpers.
|
||
|
||
For safe real-terminal acceptance without vendor or OS access, the explicit
|
||
`test/provider-tui-fixture.ts` entrypoint uses the real renderer, IPC, controller,
|
||
and settings with synthetic external adapters. It requires a temporary
|
||
`BEEHIVE_HOME` whose name contains `provider-tui-fixture-`. It is not reachable
|
||
from the production launcher. API key `deny` exercises provider denial. The
|
||
fixture is not proof of live vendor authentication.
|
||
|
||
The Providers list always includes every supported provider type, even before
|
||
any account is saved. Missing accounts show NOT SET. Saving configuration alone
|
||
does not establish connection. Select an unconfigured type and use Configure,
|
||
or select a saved account and use Edit configuration. The global Add provider
|
||
command is removed; all existing saved accounts remain accessible.
|
||
|
||
In the prototype shell, Left/Right in the header changes the visible destination
|
||
immediately and keeps focus in the header. Enter/Down moves into that pane.
|