Add reproducible standalone dependencies and a source-grounded external conversation launch plan, gated until ACP subtree containment is implemented. Signed-off-by: Logan Johnson <loganj@squareup.com>
Beehive (experimental first slice)
Standalone TypeScript host + relay + terminal UI. Not Desktop parity, not production-ready, not compatible with the current Buzz relay. 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.
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.
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: hosts, select <host-name>, show, start, save, stop, quit.
Save asks for advertised model, workspace and independent behavior profile.
Only one fixture model and the default profile are currently supported;
profile authoring/versioning and useful multi-setup selection remain to build.
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.
Do not point fixture mode at real agents. This seam deliberately passes no agent key, OAuth context, model, or instructions to the fixture. 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
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. Key import and Move are disabled. 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, relay ACKs and durable TUI pending intents are not yet implemented. Lost connection means unknown, not stopped or success.
- Inventory has freshness, not liveness proof. Host starts no action based on peer agent presence. Only its locally bound agent is manageable.
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.
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 there is no relay prompt/conversation bridge yet. 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 (launch blocked)
node src/cli.ts conversation-setup /absolute/existing-host-directory attaches
an installed buzz-acp executable and separate Buzz conversation relay URL to
an existing Buzz Agent setup. It never generates/replaces the provisioned agent
identity, reads OAuth or initiates a connection. Close the host first; setup uses
the same atomic exclusion lock and leaves the key/auth context unchanged.
This does not enable a conversation yet. A configured conversation Start is
rejected before spawn; inventory explains why. Upstream AcpClient::spawn calls
process_group(0), so putting buzz-acp inside the existing outer supervisor would
let its ACP adapter escape owned Stop. apply_model_switch can also proceed on
a default model after rejection. A host-owned TS ACP stdio broker must retain
adapter ownership and observe exact-model/session completions in actual Buzz
conversations before this gate can be removed. Buzz-acp—not Beehive—will continue
to own Nostr auth, membership, author gates, mentions, replies and delivery.
The launch plan supplies the existing agent key, explicit owner, optional local NIP-OA attestation and authoritative relay/model env. None has been exercised against a real conversation relay. Community admission and host-service-user OAuth remain explicit operator actions; this package has not performed them.
Supported / remaining parity
| Surface | This slice | Required next work |
|---|---|---|
| Local owner/key setup | New owner + separately generated agent key | nsec import, saved-owner verification, revocation/key removal UX |
| Host inventory | Real relay, fixed authority, freshness | multiple setups/agents, service install, reconnect/reconciliation |
| Remote configuration | CAS model/workspace/default profile selection | reusable profiles, metadata, config history, setup revision pinning |
| Lifecycle | fixture Start/Stop, UI-independent host | strict real launch, Restart, host-owned irreversible Move |
| Buzz Agent Databricks v2 | Local setup + TypeScript ACP probe boundary | live OAuth/model proof, full conversation bridge and diagnostic 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.