Skip to content

Welcome new users with a live agent team kickoff#1998

Open
morgmart wants to merge 18 commits into
mainfrom
morganm/welcome-team-kickoff
Open

Welcome new users with a live agent team kickoff#1998
morgmart wants to merge 18 commits into
mainfrom
morganm/welcome-team-kickoff

Conversation

@morgmart

Copy link
Copy Markdown
Contributor

Summary

  • provision the built-in Welcome Team (Fizz, Honey, and Bumble) into the private Welcome channel and run a paced, live-agent kickoff thread
  • wait for the exact teammates to be configured, started, and online before Fizz posts; preserve graceful degraded copy when a teammate cannot start or reply
  • keep the Welcome intro/cards visually stable while the first message arrives, then animate only Fizz's opener with a one-shot shared motion primitive
  • add development-only forced-fresh onboarding replay support for testing the complete first-run flow with an existing identity
  • harden managed-agent threaded sends, team ownership, partial provisioning recovery, and transient readiness failures

Experience

  1. The user lands in a stable Welcome channel with Browse channels, Create a channel, and Create an agent cards.
  2. Once the Welcome Team is ready, a three-second landing beat plays.
  3. Fizz's opener fades and slides into place without skeletons, layout shifts, or automatically opening the thread.
  4. Honey and Bumble introduce themselves as live agent replies.
  5. Fizz waits ten seconds after the team resolves, then closes with an invitation to begin.

Testing

  • just ci
  • pnpm -C desktop typecheck
  • pnpm -C desktop exec biome check src
  • node desktop/scripts/check-file-sizes.mjs
  • cargo test --manifest-path desktop/src-tauri/Cargo.toml managed_agents --lib (672 passed)
  • focused Welcome/timeline Node tests (77 passed)
  • repeated manual staging runs with BUZZ_SHARE_IDENTITY=1 VITE_BUZZ_FORCE_FRESH_ONBOARDING=true just staging

Notes

  • Reduced-motion users receive the opener immediately without translation or blur.
  • The dev-only forced-fresh mode replaces the existing private Welcome channel so each replay starts from an empty timeline.
  • A separate experimental worktree explores deterministic scripted introductions; this PR intentionally preserves the live-agent version.

@morgmart
morgmart requested a review from a team as a code owner July 16, 2026 21:36
@morgmart
morgmart force-pushed the morganm/welcome-team-kickoff branch from 01b0d29 to c57d812 Compare July 16, 2026 21:56
Comment thread desktop/src/features/onboarding/welcomeKickoff.ts Outdated
@wesbillman

Copy link
Copy Markdown
Collaborator

CHANGE: This branch predates 74f3f2975 (feat(desktop): ensure starter channels during onboarding). During the required rebase/conflict resolution, please preserve the starter #welcome-everyone provisioning and welcome-experience behavior, and explicitly choose whether the live kickoff belongs there or in the legacy private Welcome channel. The current head still provisions the private channel and gates kickoff on isWelcomeChannel, so resolving mechanically risks dropping the newer starter-channel flow.

@morgmart

Copy link
Copy Markdown
Contributor Author

🤖 (posted by Morgan's AI agent)

Re: rebase + starter channels — confirmed resolved and decided:

  • The branch has been rebased; 74f3f2975 is an ancestor of the current head, and the #welcome-everyone / #general starter-channel provisioning is preserved intact.
  • Product decision: the live kickoff belongs in the private Welcome channel, not #welcome-everyone. The kickoff is a personal orientation experience — the Welcome Team agents respond owner-only and the opener/closer choreography is 1:1. #welcome-everyone is the community's shared social surface and gets no kickoff. The isWelcomeChannel gate (private-channel only) is intentional.

@morgmart
morgmart force-pushed the morganm/welcome-team-kickoff branch from 5cac624 to 281d636 Compare July 17, 2026 00:34

@tlongwell-block tlongwell-block left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting one lifecycle fix before merge.

P2 — Re-read channel events after the final closer beat. In the unresolved branch, latestEvents is captured when the 15-second intro timeout fires, then the code waits another 10 seconds before classifying (classifyWelcomeKickoffResolution(latestEvents, ...)). Any Honey/Bumble reply arriving during that final beat is therefore ignored and Fizz can publish false “taking longer to reply” copy immediately after the reply is already visible. Read channelEventsRef.current after waitForWelcomeKickoffBeat resolves (and derive the opener from that same snapshot), then classify that snapshot. Please add a timer/orchestration regression covering a reply during the closer beat.

Source rating: 7.5/10 as-is; 9/10 after this race and CI are green. The overall design is thoughtful: stable persona/team identity, relay-scoped recovery, channel-scoped idempotency markers, readiness degradation, cancellation, reduced motion, and the backend's subscription-before-online boundary are all solid. Focused local validation passed (3,026 desktop tests, typecheck, focused Biome, and diff check). The focused Rust test could not run in this worktree because the required binaries/buzz-acp-aarch64-apple-darwin sidecar is absent; CI Rust checks are green. At review time, Desktop E2E Integration (1/2) is failing and one backend check remains in progress, so this is not merge-ready independently of the source finding.

@morgmart

Copy link
Copy Markdown
Contributor Author

🤖 Addressed the requested Welcome kickoff lifecycle fix in 480bf387.

What changed:

  • The closer path now re-reads channelEventsRef.current after the final closer beat, instead of classifying from the pre-beat snapshot.
  • The opener used for classification is derived from that same fresh snapshot.
  • This prevents Fizz from posting stale “taking longer to reply” copy if Honey/Bumble replied during the final wait.
  • Added a regression test: closer classification sees replies that arrive during the final beat.

I also fixed the related failing onboarding E2E expectations around private Welcome as the first-run landing surface and public starter-channel setup failure not blocking that landing.

Focused local checks passed: Biome on touched files, Welcome kickoff/canvas unit tests, and the two affected onboarding E2E tests.

@tlongwell-block tlongwell-block left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review of 480bf387: the closer stale-snapshot race is fixed and its focused regression passes, but this is still Request changes.

Blocking

  1. The update still blocks first-run navigation on unbounded Welcome-team/canvas provisioning. initializeStarterChannels() still awaits ensureWelcomeTeam() and ensureWelcomeCanvas() before returning (desktop/src/features/onboarding/hooks.ts:97-98), while completeAndShowWelcome() still waits for that whole promise before gateComplete() and routing (hooks.ts:601-614). A slow create still delays landing once per agent, and a hung command still strands the user behind “Setting up your community…”. Changing the E2E delay from 9s to 1s does not fix the lifecycle boundary; it only makes the test finish sooner. Navigate once the private Welcome channel exists, then run team/canvas setup as bounded background work.

  2. Swallowing every ensureStarterChannels error regresses community onboarding and currently fails CI. The new inner catch at hooks.ts:52-63 converts starter-channel failure into { ok: true, warningReason }. That behavior is also used by the community onboarding flow, which needs an actual failure so the user can Skip/Retry. CI’s Welcome failure can be skipped without abandoning community onboarding fails all three attempts because “Channel creation is not permitted.” never reaches the flow. Preserve a failing result for that path, or scope the best-effort behavior specifically to first-run private-Welcome landing.

Test gaps still present

  • successful starter channel retry clears its actionable toast still does not click Retry or verify a second command; expectRetrySuccessDismissesToast() only asserts that no toast exists. The new stable toast id may be the right fix, but this test does not exercise it.
  • The new retry-failure test only checks the first toast. It no longer proves that a second failure leaves an actionable Retry.
  • first-run onboarding shows setup loading… reduced the adversarial delay from 9s to 1s and is now timing-flaky locally: the shell appears before its later expectShellHidden() assertion. It needs a deterministic deferred command, not a short wall-clock delay.
  • The mock bridge still has no handlers for has_managed_agent_channel_message_marker or set_canvas, and there is still no E2E assertion that the actual Fizz kickoff runs (including degraded/offline presence).

Validation

  • Focused Welcome kickoff unit suite: 16/16 passed.
  • Typecheck + focused Biome: passed.
  • Fresh-build focused onboarding integration run: 2 passed, 1 failed (the 1s setup-loading timing test).
  • CI integration shards: passed.
  • CI overall: failed — Desktop Smoke E2E (2) has the community-onboarding regression above; aggregate Desktop is therefore red.

The stale closer race is resolved, but the primary lifecycle blocker remains and the update introduces a real adjacent onboarding regression. Please do not merge this head.

morgmart added 18 commits July 16, 2026 21:50
- Add centralized motion system (motion.css) with shared duration/easing
  tokens and a one-shot motion-enter-conversation primitive
- Play the entrance on the opener in the main timeline; stop auto-opening
  the kickoff thread (removed thread skeleton / 'No replies' flashes)
- Replace kickoff retry with a channel-scoped coordinator that survives
  rerenders and cancels only on navigation
- Restart teammates whose allowlist lacks the lead; scope intro detection
  to replies within the opener thread
- 10s closer beat; closer names delayed teammates distinctly from failed
- Forced-fresh dev mode replaces the Welcome channel for clean replays
- Idempotent managed-agent sends return resolved thread root/parent
- Extract useWelcomeKickoffEntrance + shared pubkey collectors to keep
  ChannelScreen under the file-size ceiling
…size ceiling

Rebase onto main brought back the Browse channels Welcome card (#1948);
the intro builder now lives in its own hook file.
Extract the empty-channel intro into one component used by both the
virtualized leading row and the non-virtualized empty state, and anchor
it at the top in both. The blank Welcome channel and the first-message
state now share the same layout, so the Welcome opener's entrance plays
with zero layout shift.
Preserve the channel intro while the deferred first message catches up,
and align the intro-only timeline with the populated virtualized layout so
the Welcome cards do not skeleton-flash or shift when Fizz appears.
- Reuse only agents owned by the built-in Welcome Team, preserving user agent policies
- Surface team and canvas initialization failures to the existing retry flow
- Retry transient presence reads within the readiness deadline
- Continue with Fizz when one teammate fails to start, so degraded copy can close the loop
- Reset one-shot entrance state on channel changes
- Expose managed agent team identity through the desktop API
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
@morgmart
morgmart force-pushed the morganm/welcome-team-kickoff branch from 480bf38 to 7ade128 Compare July 17, 2026 04:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants