Commit Graph

2679 Commits

Author SHA1 Message Date
Logan Johnson
2ea103d74f feat(beehive): provision Databricks token and native OAuth contexts
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 05:10:17 -04:00
Logan Johnson
e00fe8f28c docs(beehive): reconcile captured admission critical path
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 05:03:09 -04:00
Logan Johnson
6697ad8043 docs(beehive): retain provider gate failure owner evidence
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 04:56:51 -04:00
Logan Johnson
36e2eaca00 test(beehive): prove provider journeys and retain event timing
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 04:51:53 -04:00
Logan Johnson
575254ac95 feat(beehive): bind Buzz Agent API providers locally
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 04:45:05 -04:00
Logan Johnson
83ea233a04 docs(beehive): bound admission latency evidence and unresolved gate
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 04:39:06 -04:00
Logan Johnson
f8556d157c docs(beehive): record recovered acceptance and open timing gate
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 04:30:22 -04:00
Logan Johnson
dd97d91405 fix(beehive): recover custom ACP journeys and coherent binding previews
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 04:27:03 -04:00
Logan Johnson
811ba471d2 feat(beehive): add local preset diagnostics and explicit custom ACP contracts
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 04:11:16 -04:00
Logan Johnson
8bf1c7d946 Fence binding confirmations and cover replacement retirement journeys
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 04:02:52 -04:00
Logan Johnson
9f6d885697 Add immutable local binding replacement and retirement eligibility
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 03:57:24 -04:00
Logan Johnson
b75b2e63ac test(beehive): prove Codex normal journeys and fail-closed prerequisites
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 03:48:54 -04:00
Logan Johnson
7174579342 feat(beehive): checkpoint closed Codex binding and protocol-two model fences
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 03:44:02 -04:00
Logan Johnson
3c31eabd12 feat(beehive): add source-grounded Claude local harness binding
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 03:37:32 -04:00
Logan Johnson
256cdf319e fix(beehive): own CLI shutdown across startup and persistence failures
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 03:26:36 -04:00
Logan Johnson
425feb343e feat(beehive): provision normal conversation wizard and immutable conversion
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 03:15:26 -04:00
Logan Johnson
58c566bbce beehive: retain disconnect fixture evidence and disclose Goose probe setup
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 03:03:45 -04:00
Logan Johnson
e8f9543ce4 fix(beehive): commit relay snapshots asynchronously before publication
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 02:58:25 -04:00
Logan Johnson
d22ce81ea5 feat(beehive): add native Goose binding and guided identity entry
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 02:46:39 -04:00
Logan Johnson
3b3ba27aa1 feat(beehive): add local binding wizard and bounded startup probes
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 02:33:25 -04:00
Logan Johnson
6a28b390db feat(beehive): resolve named selections to immutable local harness bindings
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 02:26:57 -04:00
Logan Johnson
1e6ead550e test(beehive): retain bounded host startup failure diagnostics
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 02:15:58 -04:00
Logan Johnson
6a5a459246 feat(beehive): restore retained local keys through a hidden import wizard
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 02:11:47 -04:00
Logan Johnson
08be5d6eb4 fix(beehive): validate retained public authority before key removal
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 02:07:58 -04:00
Logan Johnson
2151ea3a5d fix(beehive): bind Move to semantic selections and reserved named revisions
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 02:03:52 -04:00
Logan Johnson
7ad542080d feat(beehive): remove local agent keys into retained public-only slots
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 01:39:44 -04:00
Logan Johnson
4d26c2e192 feat(beehive): add named launch candidates and reusable setup wizard
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 01:13:53 -04:00
Logan Johnson
e70f90f9ae feat(beehive): publish revisioned behavior profiles and capture applied instructions
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 01:01:33 -04:00
Logan Johnson
e6717541d4 feat(beehive): add fenced per-agent remote Restart
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 00:49:37 -04:00
Logan Johnson
a235638e0a feat(beehive): complete preflight-gated identity conversation Move
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 00:43:00 -04:00
Logan Johnson
97a9050adb feat(beehive): recover source-consumed fixture Move transaction
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 00:25:47 -04:00
Logan Johnson
8ba5fa9cd4 feat(beehive): isolate agent slots under one host installation
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 00:10:11 -04:00
Logan Johnson
ebc8b3cb24 feat(beehive): fence initial assignment independently of key possession
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-09 23:59:40 -04:00
Logan Johnson
8a67b96786 docs(beehive): record verified recovery publication heads
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-09 23:52:29 -04:00
Logan Johnson
4fa4fd1469 feat(beehive): reconcile policy-blocked intents with informed unchanged retry
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-09 23:52:15 -04:00
Logan Johnson
64305a7a00 fix(beehive): fence queued Start cancellation by admitted Stop identity
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-09 23:49:20 -04:00
Logan Johnson
d12ed7b4e0 feat(beehive): persist client intents and replay across TUI reconnect
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-09 23:29:39 -04:00
Logan Johnson
6f893f51d2 docs(beehive): record recovered source and branch publication
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-09 23:22:51 -04:00
Logan Johnson
998e919a9b feat(beehive): recover host relay transport with durable replay
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-09 23:22:32 -04:00
Logan Johnson
f8f161ffc1 feat(beehive): expose owned Buzz CLI across agent conversations
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-09 23:17:26 -04:00
Logan Johnson
023c927476 feat(beehive): provision owned fixed-scope Buzz reply tool
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-09 23:08:42 -04:00
Logan Johnson
c4f3017676 feat(beehive): broker identity-bearing ACP conversations under host ownership
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-09 23:00:03 -04:00
Logan Johnson
9ff9c6cf16 fix(beehive): preserve teardown ownership and cancel ACP startup
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>
2026-09-09 22:47:45 -04:00
Logan Johnson
6bd8594795 feat(beehive): add external ACP probe and anchored host teardown
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-09 22:35:53 -04:00
Logan Johnson
94d1da0e81 feat(beehive): checkpoint isolated TypeScript relay host and terminal slice
Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-09 22:26:24 -04:00
Diem Nguyen
051c3a270b fix(buzz-acp): report missing models without retrying (#7538)
## Summary

When an agent reports model-not-found, Buzz retries the unavailable
model and delays the failure reply until retries are exhausted. Stop
retrying this error and immediately post a threaded recovery notice. The
notice tells users to select a different model in agent settings, save,
restart the agent to apply the configuration, and re-send their request.

This adds one error-handling branch and regression coverage in
`buzz-acp`. It matches `-32002` errors containing `model not found`.
Other resource-not-found errors, such as stale sessions, retain the
existing retry behavior. Detailed error events remain available for
diagnosis. The existing restart policy is unchanged.

### Related issue

None found in existing issue/PR searches for model-not-found recovery.

### Testing

Playwright captured and visually checked the thread UI with seeded
conversation data and the exact recovery text. The check opens the
request's thread, confirms no reply before the failure, injects the
notice, and verifies the full text is visible. [Before/after
screenshots](https://github.com/block/buzz/pull/7538#issuecomment-5608196506)
show the corrected save-and-restart instructions. These are local test
captures, not a deployed provider recovery flow.

Generated with Codex

---------

Signed-off-by: Diem Nguyen <diem@squareup.com>
2026-09-09 16:52:35 -07:00
Stephen DeLorme
12023a3cba fix(desktop): require a Codex adapter with Astra support (#7427)
## Summary

Buzz considers codex-acp 1.6.2 current because the supported adapter
floor is still 1.1.7. That adapter bundles Codex 0.148.0, so updating a
separate Codex CLI to 0.153.4 leaves managed agents on the older runtime
and unable to use GPT-6 Astra.

Raise the supported adapter floor to the published 1.10.0 release, which
depends on `@openai/codex ^0.153.3`. Existing discovery and installation
code then classifies older adapters as outdated and offers the managed
reinstall path. Update the availability and install-plan regressions to
cover the observed 1.6.2 installation and the new minimum.

This follows the existing version-floor policy. It does not
automatically update a running installation: the user must complete
Buzz’s offered adapter upgrade. Future upstream compatibility changes
may require another floor update.

### Related issue

No exact duplicate found in searches for Astra, CODEX_PATH, bundled
Codex, outdated runtime, and codex-acp 1.10. Related: #3097 raised the
older floor to 1.1.7 (already present on main); #2422 covers lost error
details for runtime mismatches. Neither resolves this version gap.

Originating conversation:
buzz://message?channel=3286cd76-f83e-4c7d-8317-10a16580744d&id=8b79a73078217222b870fff144c27e7d27bcd5a67c966869c18fe726db716898

### Testing

- Isolated npm install of codex-acp 1.10.0 resolved bundled Codex
0.153.4, with no CODEX_PATH override.
- Live macOS ACP probe: initialize protocol v1 → session/new → select
gpt-6-astra[medium] → prompt. Received `OK` and `stopReason: end_turn`;
usage metadata confirms gpt-6-astra.
- Existing adapter 1.6.2 initialized but advertised no Astra model in
the same probe.
- Desktop Rust formatting and `git diff --check` pass.
- `just desktop-tauri-test`: 3,266 passed, 20 ignored, zero failures
across the Desktop workspace and integration tests.
- Workspace and Desktop Clippy, frontend static checks, and `just
file-size-check` pass.
- Repository `just ci`: still running the remaining
mobile/build/workspace-test stages.

The installed Buzz app and managed adapter were not replaced or
restarted. The live check validates the new adapter/runtime path; a
complete packaged Desktop upgrade workflow remains untested.

Signed-off-by: Stephen DeLorme <stephen@d.elor.me>
2026-09-09 16:32:37 -06:00
Logan Johnson
ad9591c43b fix(desktop): order unnamed roster members by full canonical npub (#7503)
🤖

## Summary

- Channel members appear in the Members sidebar. A member who has never
set a display name is listed under an abbreviated form of their public
key (npub), and the sidebar previously sorted those unnamed members by
that short label. Short labels are not unique — different keys can share
one — so the order of unnamed members could look arbitrary or unstable.
Unnamed members now sort by their full public key, so the order is
deterministic.
- When two members display the same name, the previous tiebreak was
membership order (who joined first), which is not visible to a reader
and can shift as roster data loads in. The tiebreak is now the full
public key, so identical display names always land in the same order.
- Nothing gets noisier on screen: the full key is used only for sorting,
and the sidebar still shows the compact abbreviated form. Priorities are
unchanged — authored (custom) names still outrank fallback labels, and
role/current-user grouping still applies.
- Scope is the desktop app's Members sidebar and member management: the
two existing sort comparators. Mobile and other lists in the app are
untouched.

### Related issue

Based on #7495 (introduced the abbreviated npub labels this follows up
on). The original five presentation PRs remain independently reviewable.
No closer duplicate found.

### Testing

- 6469 desktop unit tests, typecheck, and check pass.
- The 3 existing consumer-seam E2E tests still pass; a new E2E test
asserts the sidebar lists unnamed members in full-key order, with
fixture members deliberately inserted in the opposite order so incoming
membership order cannot mask the sort.
- Negative check: reverting only this change makes the new ordering
assertion fail, so it genuinely binds the new sort.
- CI has not run on this PR yet.

Buzz provenance: channel 1f0e4a3d-7e01-4efe-bb16-843b357f85c9 / task
340c3de9b27dbedb8453c0c7652220f9080d30fcc70a7c4f6e27fdd4fa378056

---------

Signed-off-by: Logan Johnson <loganj@squareup.com>
Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
2026-09-09 13:32:10 -07:00
Logan Johnson
82656ffea0 fix(mobile): standardize public-key identity display on npub (#7493)
🤖

## Summary

In the mobile app, anyone who hasn't set a display name shows up as a
raw 64-character hex key (e.g. `3a5d4f9c…`) — unreadable, and
unrecognizable as the same identity across screens. Profile and Settings
also let you copy that raw hex. Nostr public keys have a standard
readable form — `npub1…`, the same encoding other Nostr apps and our
desktop app already display. This PR makes every mobile identity surface
render npub instead:

- **Unnamed people everywhere** — message and thread authors, reactions,
typing indicators, member lists, channel details, DM headers and tiles,
inbox, search, forum cards, Pulse notes and reply context, mention
suggestions, and invite rows — now show a compact npub label: first 8 +
last 4 characters of the full npub joined by an ellipsis
(`npub1abcd…wxyz`), the same truncation desktop uses. Previously these
showed truncated raw hex.
- **DM fallback avatars and blank names** — 1:1 DM tiles and headers key
their fallback avatar to the same non-self counterpart the label names,
including self-first participant order; a self-DM keeps its
hex-key-derived initial. Blank or whitespace-only display names fall
back to the compact npub instead of rendering empty, while nonblank
authored names render verbatim (padding included).
- **Profile sheet → "Copy public key"** now copies the full canonical
npub — never raw hex. When the identity string isn't a valid public key,
the copy tile is disabled, so a malformed key never reaches the
clipboard.
- **Settings → Identity (pubkey)** displays and copies the full npub; an
invalid identity reads "Identity unavailable" with copy disabled.
- **Invalid identities never leak truncated raw hex** into the UI
anywhere — they render a neutral "Unknown identity" label.
- **Unchanged on purpose:** display names and verified handles (NIP-05 —
the `name@domain` badge) still render as before. Unnamed avatars keep
distinct per-key initials, derived from the underlying hex key rather
than the npub — otherwise every unnamed key would render the same "N"
initial. Event IDs are not public keys, so they keep their hex
truncation (in Pulse's "Replying to", the parent author shows npub while
an event-id fallback still shows hex). The nevent share link, private
keys, and internal hex storage are untouched. Inputs that accept a key
(invite/member entry) accept both hex and npub and keep working in hex
internally.

### Related issue

N/A. Searched open issues/PRs for npub identity display on mobile —
closest related: none found. Desktop's parallel npub standardization
lives in the stacked desktop PRs (#7488 foundation, #7489 controls,
#7495 display surfaces); this is the independent mobile slice (based
directly on `main`, not on those branches).

### Testing

At exact head `5a620e420a1fd57d9d8011ac26434eed32fcf765` (base: `main`
`44316ff72`; 40 files, +1,345/−154):

- Full mobile suite: 2,098 tests passing (`cd mobile && flutter test`);
`flutter analyze` clean; `dart format --set-exit-if-changed .` clean —
the same checks CI runs.
- Widget/unit coverage at production seams: compact labels and hex-keyed
avatar initials for DM headers/tiles, member rows, mention suggestions,
and Pulse reply context; DM fallback avatars keyed to the labeled
counterpart (self-first order and self-DMs); blank/whitespace
display-name npub fallback with nonblank authored labels verbatim,
including the Activity inbox sender and profile-sheet heading (each with
its own empty/whitespace production-seam regression); full-npub copy and
disabled-copy semantics in profile and settings; invalid-key
suppression; and hex↔npub input round-trips.

Verified via unit and widget tests — no device/simulator validation is
claimed.

### Task provenance

Buzz channel: `1f0e4a3d-7e01-4efe-bb16-843b357f85c9`

Task:
buzz://message?channel=1f0e4a3d-7e01-4efe-bb16-843b357f85c9&id=86b34eb4bd84a1472419e9af22636c011c0fe273e3c196f967d7a36996e149b6

---------

Signed-off-by: Logan Johnson <loganj@squareup.com>
Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
2026-09-09 14:08:24 -04:00
Logan Johnson
2226b6f95b fix(desktop): npub identity controls across profile, agents, and workflows (#7489)
🤖
## Summary

Building on #7488's npub foundation, this PR finishes the identity
display change for the controls where you actually manage people and
keys: profile, settings, agent access, and workflows. Everywhere in
these surfaces, an identity key shows — and copies — as its canonical
npub (npub is the human-readable encoding of a Nostr public key: the
compact `npub1j57...fjmv` form where space is tight, the full npub where
the whole key matters), and accepts npub as input.

After this change:

- Profile panel: the public-key row and the managed-by / declared-owner
copies show the full npub. If a key can't be encoded, you see
"Unavailable" with no copy button — never a raw or partial key.
- Settings: the identity card shows and copies the npub. The
hosted-communities account identity derives from the bound key
(`pubkey_hex`) — the same authority as the mismatch gate and hosted
operations — so the display can never disagree with what the app acts
on; an unusable hex falls back to a neutral label instead of rendering
the unverified server npub. The connected claim and a community's
Connect action require that same usable bound key to match the local one
— with no usable binding the card cannot claim connected or start
Connect, while the community list, linking, and delete/rebind recovery
stay available.
- Hosted create/onboarding: the account and device identity rows in the
create flow and owner onboarding derive from the same authoritative
fields (bound key / local key), with the same neutral fallback;
readiness requires a usable bound key that matches the local one.
- Respond-to allowlist (controls who may respond to an agent): entries
can be typed or pasted as hex or npub; both spellings of the same key
are recognized as one entry and dedupe. Search results, chips, and
remove buttons use the compact npub.
- Workflow key fields: to/from keys display as npubs in the form and
save back as canonical hex. Templates like `{{trigger.author}}`, roles,
and free text pass through untouched; placeholders accept both
spellings.
- Recipient and agent dialogs: the verify popover is npub-only (the
raw-hex line is gone); denied-membership screens never show a raw key.
- The Rust-side truncated display name (used for native surfaces) shows
the same compact npub, so those surfaces match the web UI.

Internal representation is unchanged: keys are still stored, sent, and
matched as canonical 64-character hex — npub is a display and input
spelling, normalized to hex at the boundary, so existing data and
integrations keep working. Bound-key usability and comparison use one
normalized form (trimmed, lowercased, 64 hex characters; npub rejected),
so padded or mixed-case spellings of the same key match. Display names,
private keys, and event IDs are untouched.

## Details

- `respondToAllowlist` / `RespondToField`: npub entries normalize to
canonical hex; cross-form dedupe; compact npub in rows and chips;
direct-add accepts npub and stores canonical hex.
- `workflowFormTypes` / `WorkflowStepCard`: hex → npub for display, npub
→ canonical hex on save; templates, roles, and free text pass through in
both directions (roundtrip-tested).
- `UserProfilePanelFields`, `ProfileSettingsCard`,
`HostedCommunitiesSettingsCard`, `MembershipDenied`,
`SelectedRecipientChip`, `AddAgentToChannelDialog`: npub display and
copy; invalid keys → "Unavailable" with no copy; hosted identity rows
derive from the bound `pubkey_hex` (create/onboarding rows from the
bound and local keys), never the unverified server npub;
connected/readiness/Connect gates use the same usable-bound-key
predicate, and the settings Connect invocation callback re-checks it
before starting.
- `src-tauri/src/commands/identity.rs`: `truncated_display_name`
compacts to the first 8 + last 4 characters of the npub (above a 12-char
threshold), mirroring `truncateNpub`.
- e2e: profile key rows and clipboard polls assert npub forms and
raw-hex suppression; the display-screenshots spec pins the npub-only
popover; hosted specs drive the real settings card, create flow, and
onboarding rows through their real providers, and the unlinked/npub-only
identity cases assert no connected claim and no Connect action.

### Related issue

- Fixes: N/A. No separate issue; the related work is the stack below.
- Stack: builds on #7488 (shared npub foundation), now merged; this PR
is rebased onto main and stands on its own.

### Testing

At head `303c90ffa` (base: main `bfc38485`; 24 files, +1125/−146):

- Focused unit suites (respondToAllowlist, workflowFormTypes,
hostedCommunityApi bound-key helpers) green; mutation-checked — dropping
allowlist canonicalization fails the dedupe case, and dropping bound-key
normalization fails the npub-in-hex and padded same-key cases.
- Full desktop unit suite 6,477/6,477, `desktop-typecheck`,
`desktop-check` (formatting fixed narrowly with `biome check --write` on
the touched files only), and a fresh E2E build at the current head; the
add-community + hosted-communities-settings specs 18/18 and onboarding
integration 69/69 on a fresh dedicated port, with focused new-case runs
4+4 covering padded same-key (ready, Connect kept — no false rebind) and
npub-in-hex (neutral label, recovery, no Connect) across the settings
card, create flow, and first-community onboarding, plus the
unlinked-account settings regression asserting Connect cannot occur.
- `cargo fmt`/clippy (both feature sets) and `cargo test identity` (71
pass) passed at the earlier full-change head; since then, the only
production changes in this PR's delta are the hosted identity display
authority and its fail-closed bound-key gating/normalization above
(base-side fixes carry #7488's receipts) — every other change is
test-only.

### Task provenance

Buzz channel: `1f0e4a3d-7e01-4efe-bb16-843b357f85c9`

Task:
buzz://message?channel=1f0e4a3d-7e01-4efe-bb16-843b357f85c9&id=86b34eb4bd84a1472419e9af22636c011c0fe273e3c196f967d7a36996e149b6

---------

Signed-off-by: Logan Johnson <loganj@squareup.com>
Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
2026-09-09 14:08:01 -04:00