mirror of
https://github.com/block/buzz.git
synced 2026-10-27 12:40:30 +00:00
🤖 ## Requested rebase published —ef40744bRebased onto fetched main **47d068e2109d077414cbf2f4f1c927f6d051037a**, published **ef40744b3aeb4baaf8c81416e1a644fb5b315f91** with the exact expected-old `df7fad6a` force-with-lease. No merge. Manual conflicts were additive: preserve main's exact-key identity documentation alongside the availability contract, and retain both Bestie props and the shared availability reader in `UnifiedAgentsSection`. Range-diff confirms unchanged lifecycle policy: exact-key action-time authority, Unknown versus Offline, rejected shutdown retains record/memberships, and separate local/provider/owner gates. Main's exact-key profile routing survives. Both test-only CI synchronization repairs (natural toast expiry and bounded stderr wait) are byte-identical to the prior head. All ten original authors/messages/DCO/material coauthor trailers are preserved; configured signing policy was not changed. Fresh checks on the rebased candidate: - TypeScript, Biome on 26 changed TypeScript files, differential file-size gate, and diff whitespace: pass. - Focused production-hook/card/profile units: **58/58**. - Fresh E2E build, availability/deletion browser: **11/11**, no retries. - Main exact-key profile cases plus failed-DM send/startup retries: **6/6**, no retries. Previously reviewed full Desktop/buzz-agent package and mutation evidence is reused for unchanged behavior; no ceremonial full suite, new native/provider test, or `just ci` pass is claimed. Local configs, dependency links, and historical artifacts are preserved. Hosted observation: **MERGEABLE**, **BLOCKED / REVIEW_REQUIRED**, no new-head formal review. [CI 33699735990](https://github.com/block/buzz/actions/runs/33699735990) is running (including Rust and Desktop lanes), not a completed success. DCO and required Security aggregate passed at the observation; the separate Codex advisory review was skipped. No completed failing check or new inline feedback observed. Historical approvals are not new-head approvals. No reviewer/security authorization or merge action was performed. --- ## Feature summary and retained pre-rebase evidence ## Summary In Buzz Desktop, an agent could look online just because it had been started or deployed, even when there was no current sign it was connected. Cards and profiles now show availability from the agent's relay presence rather than a saved launch record, so you can distinguish an online agent from one that was merely deployed. Agents cards and profiles use presence reported through the shared server (the relay). A successful presence read with no online agent shows Offline; failed/disconnected evidence shows unknown, rather than retaining a misleading cached Online state. Lifecycle actions remain separate. An offline agent may still have a Shutdown action because the deployment record exists. Shutdown reports a **request**, not proof the process stopped. Offline does not imply that starting a duplicate agent is safe, and Online does not promise a response. ### Related issue Independent base: `main`; no stack parent or child among the replacements. Extracted from [#7114](https://github.com/block/buzz/pull/7114), retained as historical source (`98fe33ec`). [Behavior contract](f4bb2ed44e/docs/agent-availability.md). Originating [Buzz discussion](buzz://message?channel=f7a9536a-1738-4bad-a888-b3ea25010ef1&id=7aa1f0ab23dce514bd8a0221441cf005bf428914621171472b79747c50820848) · channel `f7a9536a-1738-4bad-a888-b3ea25010ef1`. ### Testing The same saved provider-backed agent, with only authored presence changing. These are mock-browser states, not a before/after deployment or live relay transport test; production UI is unchanged by the later fixture repairs. **No online presence:** gray dot, existing Shutdown control retained.  **Online presence:** green dot, same lifecycle control.  [Capture details](https://github.com/block/buzz/pull/7127#issuecomment-5482264824). To check manually, compare runtime-only transitions with presence updates, then disconnect/fail the presence read and verify it does not stay Online. A Shutdown request should not immediately claim confirmed termination. #### Historical pre-rebase evidence and limitations (df7fad6a) Lifecycle production source remains **`f4bb2ed44e5a989d93c5f51e93c0bbd2dca941be`**. Current published head is **`df7fad6ae65dda78508317186a95522d1bb22ed9`**: the prior browser synchronization at `b78d093e` plus an additive two-file Rust test-harness synchronization described below. No production bytes, dependency/configuration files, or prior commits were changed; no rebase. Current live main `0dbd036f5bff33e7ade75e7639f3218d424a6e73` has identical failing-test/toaster/send-flow source; the causal browser comparison used latest successfully tested main `04babf02655440b4dfd37f2e2df605ead0a030d8`. **Lifecycle/deletion correction:** both Agents and actual profile deletion now pass the shared exact-key availability reader, not raw cached data. It reads the canonical query state and connection at action time, including after awaited channel discovery. Failed/disconnected/pending evidence and unqueried persona siblings are unknown; successful missing means Offline only for a requested key. Successful background refetch cache remains usable; settled failure revokes it. No second cache or per-row polling was added. Provider record + channel + Online/Away/**unknown** awaits shutdown submission before local removal; rejection preserves record/membership for retry. Established Offline preserves intentional no-request removal. No route preserves warned local removal. Local agents retain native stop-before-remove, independent of presence. Profile consent now describes a shutdown **request**, not remote deletion or guaranteed termination. Existing ownership and force gates are unchanged. **Verified, reused exact-candidate validation:** the independently approved eleven-file patch (SHA-256 `2f69fe12ef0420e62dea1fd8db28cfa22cde5eecaf8080e656310a3e60d0cf86`) was committed without byte changes. Desktop **5,921 passed, 0 failed/skipped**, including **26 new mounted production hook/IPC regressions**; rebuilt availability browser suite **11/11 passed, no retries**, including four actual profile Delete journeys. Desktop check (existing 4 warnings/5 infos), typecheck, production/protected-feature artifact matrix, differential file-size/policy and diff checks passed. No blanket rerun or new full-repository `just ci` is claimed for this frontend correction. Production regressions cover cached Online **and Offline** failure/disconnection, genuine missing/Offline, pending, successful inflight refetch versus settled error, retained reader, error during awaited channel discovery, unqueried persona sibling, shutdown rejection/order/cancel, no route and local authority. Browser fixtures use safe mock IPC and a retained provider receipt, not a real deployment. Three restored mutation controls fail: unknown → skip shutdown (**15** regressions), Agents raw-cache reader (**6**), actual profile raw-cache caller (**1 browser journey**, false removal on failed cached Offline). Independent review approved the exact frozen bytes and added **4/4 cached-empty failure/disconnection probes** across both callers. This is local independent approval, not formal GitHub/A Team clearance. The prior native propagation/poll-count defects remain closed ([earlier response](https://github.com/block/buzz/pull/7127#issuecomment-5512278755)). The prior hover-popover correction at `b55423f6` remains covered by the full 11-journey browser run: pending/failed/disconnected means no badge or accessible status, genuine missing/Offline retains an Offline badge. Its earlier fallback-restoration mutation failed as expected (badge count 1 rather than 0); that historical witness is reused, not rerun. **Reused unchanged native/system boundary:** local `just ci` at `c59067d8` passed workspace/Tauri fmt/clippy, static/policy checks, Rust unit recipe, native workspace **3,159 passed / 20 ignored**, Web build and **2,019 mobile tests**. No native implementation changed in this lifecycle correction. These are historical boundary results, not new-head native/live certification. [Parent CI](https://github.com/block/buzz/actions/runs/33650549130) passed with **14 retry-recovered browser flakes**, not retry-free. Old-head CI/reviews are not current-head clearance. **Hosted gates:** [CI33662151103](https://github.com/block/buzz/actions/runs/33662151103) on `f4bb2ed4` **FAILED**: smoke shard1 had 322 pass, one failure, one retry-recovered flaky, two skipped. The failed first-DM retry test timed out on all three attempts because the error toast intercepted Send. That failure is preserved, not waived; the scoped test repair below is published as `b78d093e`. [CI33668171165](https://github.com/block/buzz/actions/runs/33668171165) on `b78d093e` subsequently **FAILED** the Rust unit budget regression described below. Both original failures remain visible; neither was retried to green. Exact `f4bb2ed4` and `b78d093e` APPROVED reviews cover unchanged reviewed bytes, not formal approval of the new head. Fresh exact-head CI and the established automated technical rereview are the next gates for `df7fad6a`. Historical deletion responses remain ([5092381800](https://github.com/block/buzz/pull/7127#issuecomment-5513759316), [5092391193](https://github.com/block/buzz/pull/7127#issuecomment-5513763497)). No formal review dismissed. The [security notice](https://github.com/block/buzz/pull/7127#issuecomment-5482231278) and latest-push maintainer/codeowner policy remain separate actionable gates: eligible Block organization members own current-range authorization. No merge/security authority exercised. **CI causal repair (`b78d093e`, test only):** the error `Message failed to send: Mock first DM send failed.` is deliberately injected by the existing fixture. CI screenshot and retry trace show the bottom-right Sonner notification over the actual enabled Send button. `fill()` leaves the pointer parked there; Sonner pauses its 4-second lifetime while hovered. A fast run can click before animation settles (unchanged local test passed in 2.7s; two actual tested-main CI cases passed first attempt in 3.3s), which does not disprove the failure. Independent controlled browser runs on `f4bb2ed4` and tested main `04babf` both reproduced the same toast hit-test at Send `(1203,627,32,32)`, persistent hover beyond 4s, and intercepted ordinary click with no second send. Moving the real pointer to the editor allows natural expiry and successful ordinary retry, preserving all original DM-channel/recipient assertions. This same synchronization already exists in the neighboring agent-startup-failure test. The one-file correction keeps the visible error assertion, scopes its toast locator, moves the pointer back to the editor and observes normal toast removal (bounded 10s) before retry. No forced click, direct toast dismissal, mocked clock, CSS override, skipped test, production behavior change, or new backend mock. Six focused browser executions pass (first-send/startup-failure, three repeats each, no retries); the held-toast control fails on original bytes at the Send click while the exact repaired test passes. Biome and diff checks pass. Reuse unchanged 5,921 Desktop / 11 availability browser / four independent probes above; no semantic production change warrants repeating those suites. Original failed CI attempt/retries, local fast pass, deliberate failing control and all traces remain in `WORK_LOGS/AVAILABILITY_CI_B9210A40`. Browser evidence is mock-IPC Chromium, not native/live-relay certification. The UI still temporarily overlays Send while a notification is hovered; the test exercises its real move-away/expiry recovery, not immediate click-through. **Rust CI causal repair (`df7fad6a`, test only):** [original Rust / Unit Tests failure, job100375291370](https://github.com/block/buzz/actions/runs/33668171165/job/100375291370) tested GitHub merge `223dee91a396d8cb4ebf18b9b8559e5a54951235`. `context_recovery_budget_exhaustion_surfaces_the_error` failed at `regressions.rs:2756` in **0.091s** because its immediate stderr snapshot lacked `context recovery budget spent`. ACP context-error assertions had already passed. The captured prefix shows all three budgets **32768 → 16384 → 8192 bytes**, above the 4096-byte floor, and ends during the third attempt. This is **not evidence of floor exhaustion**. The collector is an independent Tokio task; a stdout response is not a stderr barrier. Recovery, harness and test blobs were identical across the compared base/head/merge parents; no production regression was implicated. The shared test Harness now provides a bounded event/condition wait, registering for collector notifications before reading the buffer to avoid lost wakeups. The budget and adjacent terminal floor assertions wait for their own diagnostic and retain the matching snapshot. The budget test still requires the provider's ACP context error and exactly three recovery rungs, now corroborated by **exactly four provider calls** and no floor diagnostic. Timeout remains a real failure with captured stderr. No fixed sleep, weaker assertion, skip, provider-limit/logging change, dependency/config edit, or production change. **Deterministic causal control:** the same real agent/HTTP-provider/ACP scenario holds only stderr collection behind a one-shot gate until after stdout responds. The old immediate snapshot fails the original budget assertion (intentional exit101); the repaired wait explicitly remains Pending while held, then passes after release. No scheduler-speed assumption or fixed sleep. This reproduces the observation race under controlled delay, **not the exact historical CI schedule**. A missing-diagnostic test proves the wait actually times out. Original failure and deliberate failing-control logs/patch remain in `WORK_LOGS/RUST_TRIAGE_06E32D2D` and `WORK_LOGS/RUST_SYNC_BC5758B9`. **Final candidate validation:** focused recovery **9/9**, floor **1/1**, absent-diagnostic timeout **1/1** pass. One full touched-package run, `cargo test --locked -p buzz-agent`: **695 passed, 0 failed, 1 existing ignored**, including all **54 regressions**. Local nextest was unavailable, so this uses the repository-supported cargo-test fallback, not a claim of nextest reproduction. `cargo fmt --check`, package-scoped Clippy all-targets with `-D warnings`, differential file-size/policy and diff checks pass. Previously reviewed availability production and the Desktop/browser evidence above are unchanged and reused; no all-native blanket rerun. The test-only delta was self-reviewed against collector ordering, timeout and falsification evidence. Existing production approval remains valid for those bytes; exact-new-head technical/CI clearance is not assumed. The required **Security aggregate** is distinct from optional Codex advisory feedback; no security authorization, human review contact, or merge was requested. **Remaining policy limits:** shutdown submission is not harness acceptance or process termination; confirmed Offline/no-route local removal may leave a remote process; route discovery is best effort, membership cleanup uses `Promise.allSettled`, and multi-instance deletion is sequential/non-atomic. No distributed singleton, provider-health, tenant-switch cancellation, live relay TTL or packaged WebView/VoiceOver certification is claimed. The pre-existing DM-header raw-presence fallback (`ChannelScreenHeader`/`useActiveChannelHeader`) remains outside this repair and uncertified. Screenshots above remain historical mock-browser illustrations, not new deletion or native transport evidence. --------- Signed-off-by: Logan Johnson <loganj@squareup.com> Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
123 lines
8.0 KiB
Markdown
123 lines
8.0 KiB
Markdown
# Agent availability and lifecycle
|
||
|
||
Availability means conversational presence on the relay, not process health.
|
||
A retained deployment receipt, PID, or `running` record cannot turn an agent's
|
||
availability dot green. A successful presence snapshot with no entry means
|
||
Offline **only for an identity included in that snapshot’s requested keys**.
|
||
An unqueried identity is unknown, never implicitly Offline. An initial pending
|
||
read, failed read, or disconnected relay means unknown, including
|
||
when the cache previously contained Online. Online and Away require presence.
|
||
|
||
Agents cards and profiles share the existing presence query and live subscription;
|
||
the Agents action owner queries its full managed set once and passes its reader
|
||
to persona/custom/unknown cards. Members owns one full-roster query shared by
|
||
rows, menus and bulk actions. The profile's actions use its existing snapshot,
|
||
and its popover also preserves failed/disconnected reads as unknown. Native
|
||
query errors reject the IPC call rather than fabricating an empty snapshot.
|
||
A live update or self heartbeat cannot heal a failed aggregate snapshot by
|
||
marking cached siblings successful; those reads remain unknown until a
|
||
successful snapshot retry. No per-row polling is needed, and
|
||
there is no second availability cache or substrate poller. Lifecycle controls
|
||
remain separate: a deployed provider agent still offers Shutdown while offline.
|
||
Shutdown sends a request, not a confirmed termination, and absence of presence
|
||
is not permission to deploy a duplicate body. Local Stop/Start routing is unchanged.
|
||
|
||
A locally stopped record with current exact-key Online or Away presence does
|
||
not establish local process ownership. Its card replaces Start (including a
|
||
stale restart/error badge) with the presence dot; its profile and member menu
|
||
retain the lifecycle-derived Start label but disable activation with an
|
||
explanation. No Stop is invented. Local/pair-owned running controls keep their
|
||
existing Stop/Restart routing, even when presence is Offline. The same positive
|
||
presence guard covers list/profile callbacks and member bulk respawn so the
|
||
visible affordance is not the only fence. This is a UI startup guard, **not** a
|
||
distributed singleton lock: missing, expired, failed or disconnected presence
|
||
cannot certify that starting another body is safe. Existing relay query/live
|
||
subscription freshness remains authoritative; no separate heartbeat or cache
|
||
is introduced. Runtime details remain accessible through the card/profile.
|
||
|
||
|
||
## Lifecycle decision authority
|
||
|
||
Presence does not grant management authority. Backend type, deployment receipt,
|
||
local/pair ownership and the existing owner gates still decide which operations
|
||
are offered and where they route. All presence-dependent decisions use the same
|
||
surface-owned reader, not raw query data. The reader checks the canonical query
|
||
cache and current relay connection at invocation, including after asynchronous
|
||
channel discovery and between persona siblings. Display observers refresh on
|
||
query data/status and connection changes (without the warning-banner debounce).
|
||
A successful cached snapshot remains usable during an in-flight background
|
||
refetch under the existing query policy; a settled error revokes it even though
|
||
TanStack retains the old data. A live single-author update cannot heal a failed
|
||
aggregate. This is not a new freshness cache or a distributed lock.
|
||
|
||
For deletion of a provider agent with a deployment receipt:
|
||
|
||
| Availability / route | Before local record deletion |
|
||
| --- | --- |
|
||
| Online or Away, channel available | Await a shutdown request; warn it does not confirm termination. |
|
||
| Unknown, channel available | Also await shutdown; explicitly identify unknown availability in the action confirmation, never claim Offline. |
|
||
| Established Offline | Preserve intentional offline removal without a shutdown request; warn the remote deployment may still exist. |
|
||
| No channel | No shutdown route; warn the remote deployment may still run, without claiming it will. |
|
||
|
||
A shutdown request failure propagates and leaves the management record and
|
||
channel memberships intact for retry; it is not silently converted into force
|
||
removal. A successful request still requires the existing orphan confirmation
|
||
(or the profile’s already-accepted equivalent) before forced **local record**
|
||
deletion. The profile confirmation describes this policy without asserting the
|
||
current availability or promising remote deletion. Cancelling after a request
|
||
retains the record; it cannot unsend the request. Channel removal follows record
|
||
deletion. Local deletion does not consult presence and still delegates to the
|
||
native stop-before-remove boundary. Custom-persona native cascade continues to
|
||
refuse provider-deployed targets; built-in persona instance removal uses these
|
||
same per-instance rules, treating unqueried siblings as unknown.
|
||
|
||
|
||
## Regression evidence
|
||
|
||
- `desktop/src-tauri/src/commands/profile_presence_tests.rs`: actual command
|
||
against loopback HTTP; empty success versus auth/rate-limit/storage/malformed
|
||
response and transport failure, with authenticated kind-20001 requests.
|
||
- `UnifiedAgentsSectionCardTarget.test.mjs`: three card types use one request
|
||
and one polling observer, reordered while the snapshot is in flight; exact-key
|
||
live updates, failed warm-cache poll, retry, changed author set and unmount.
|
||
- `agent-availability.spec.ts`: real Agents/Members surfaces request-count check;
|
||
failure uses the native string rejection shape, not a fabricated success.
|
||
|
||
- `desktop/src/features/agents/lib/useAgentAvailability.test.mjs`: successful,
|
||
missing, unavailable, and disconnected presence; lifecycle routing and badges.
|
||
- `desktop/tests/e2e/agent-availability.spec.ts`: deployed/offline profile and
|
||
card, stopped/Online and Away presence, disabled keyboard/click Start in
|
||
profile and member menu, restored Offline startup, running-but-Offline,
|
||
live updates and disconnected-state behavior. Its real hover-popover journey
|
||
holds the single-key IPC read pending, then distinguishes successful omission
|
||
and explicit Offline from failed cached Online and disconnection, checking
|
||
visible badges plus accessible names and screen-reader status text. Restoring
|
||
the popover's Offline fallback must fail this regression.
|
||
- `desktop/src/features/agents/ui/UnifiedAgentsSectionCardTarget.test.mjs`:
|
||
mounted persona/custom/unknown cards, exact-key versus other-key presence,
|
||
Online/Away/offline/missing transitions and actual Start callback activation.
|
||
- `desktop/tests/e2e/agents.spec.ts`: Start badge animation and avatar continuity,
|
||
runtime-only negative control, then authored Online presence.
|
||
- `desktop/tests/e2e/profile.spec.ts`: created-agent initial Online snapshot and
|
||
live Offline/Online transitions alongside independent Stop/Start controls.
|
||
- `desktop/tests/e2e/onboarding.spec.ts`: Welcome kickoff stays pending after
|
||
runtime start alone, then greets the owner and addresses Honey/Pollen only
|
||
after the scenario publishes their explicit presence. Healthy-team scenarios
|
||
use `tests/helpers/welcomeTeam.ts`, without changing the product readiness wait.
|
||
|
||
Mock create/start/stop only model runtime bookkeeping. Scenarios that require
|
||
availability use `__BUZZ_E2E_EMIT_MOCK_PRESENCE__` to seed the snapshot and emit
|
||
kind 20001 with the agent as author. Updating a directory row or posting a chat
|
||
message is not presence. Mock browser tests do not certify native relay TTL,
|
||
provider termination, or substrate health.
|
||
|
||
- `managedAgentDeletionAvailability.test.mjs`: mounted production Agents and
|
||
profile deletion hooks through safe mock IPC, including failed/disconnected
|
||
cached Online **and Offline**, pending, genuine missing/Offline, Online/Away,
|
||
channel-discovery suspension, unqueried persona siblings, successful in-flight
|
||
refetch, shutdown failure/ordering/cancel, no-channel and local delegation.
|
||
- `agent-availability.spec.ts`: real profile Delete dialog/action with failed or
|
||
disconnected cached Online and failed cached Offline. A rejected shutdown
|
||
retains the record; retry orders shutdown → deletion → membership removal.
|
||
Genuine Offline preserves no-request deletion. All destructive IPC is mocked.
|