Skip to content

feat: first-run experience - guided wizard ending at the approval gate#216

Merged
nullxnothing merged 5 commits into
mainfrom
growth/loop4-firstrun
Jul 3, 2026
Merged

feat: first-run experience - guided wizard ending at the approval gate#216
nullxnothing merged 5 commits into
mainfrom
growth/loop4-firstrun

Conversation

@nullxnothing

Copy link
Copy Markdown
Owner

Rebuilds onboarding around the product's actual wedge: a fresh install reaches a real write approval card, and rejects it, inside five minutes (measured 3:31 on a fresh profile).

  • Five-step wizard: workspace -> Claude connect (resurrects StepClaude with OAuth polling) -> project with a one-click demo workspace -> approval-gate primer with a mock write card -> first mission: a scripted ARIA turn whose read chips run silently and whose remember_fact write raises a real approval card the user decides on.
  • Onboarding is chain-safe by construction: mission turns carry a devnet pin the IPC boundary enforces; pinned reads answer from local wallet inventory with zero RPC to any endpoint; sensitive tools are refused before any card can be raised; unpinned turns are byte-identical (regression-tested). Also fixes the demo card being falsely cluster-marked [MAINNET] from stored config.
  • First-session empty states across console, wallet, activity, swarms, memory; local-only firstrun funnel counters (app_settings + activity mirror); fixes set-onboarding-progress validation that silently dropped every save.

Suite 1073 passing (was 1027 at branch time; +46, none skipped). Typecheck, build, lint:styles green. Fresh-profile E2E driven over CDP twice, plus an adversarial run with cluster forced to mainnet-beta: pinned readout shown, card clean, zero console errors.

- firstrun_funnel app_settings blob, first-touch-wins, mirrored into the
  activity log (context first-run) so the trail reads in-app; mission-scoped
  marks gated in main so normal usage never logs
- settings:mark-funnel-step / settings:get-funnel IPC
- projects:createDemoWorkspace scaffolds ~/daemon-first-mission (3 files,
  git init, idempotent) and registers it for the mission read tools
- fix set-onboarding-progress validation: required keys were still the old
  step list, so every save failed silently
- new step order: workspace, claude connect, project, approval gate, first mission
- StepClaude back in the flow with OAuth polling (4s up to 5min) and honest
  disclosure copy while the browser flow runs
- StepProject gains the demo-workspace route; StepAiSafety is now a frozen
  preview of the real WRITE approval card plus the three risk rules
- StepFirstMission fires the scripted ARIA turn ending in a real remember_fact
  approval card; tour offer deferred until the mission turn settles so it
  never lands on top of the card
- funnel marks at each step boundary; approval_shown/decision marks in the
  aria store (gated main-side); wizard testids for the e2e run
… swarms, memory

- console empty state states the deal and offers starter prompt chips; the
  first-mission chip disappears after the first approval decision
- wallet empty route leads with the devnet context and a throwaway wallet
- activity true-empty introduces the flight recorder instead of a filter miss
- swarm and memory empties explain what will appear and what it needs
…urface

The no-wallet empty state moved to WalletWorkspace in the packs shell; the
old WalletTab route is dead code, so revert its copy edit and land the
devnet-context message and Create devnet wallet primary where users
actually see it. Also point the onboarding smoke at the toolbox host that
now owns Solana Start.
…'t leak in

The scripted mission ran its reads through the configured RPC, so a
re-entrant wizard run with mainnet stored in runtime config would silently
read mainnet wallet state and tag the demo's write card [MAINNET]. Pin the
mission turn instead: both launch surfaces send snapshot.pinnedCluster
'devnet' (restrict-only, normalized at the IPC boundary), pinned
read_wallet/read_project_status answer from the local wallet inventory with
zero RPC and report the cluster as devnet by construction, and pinned turns
refuse sensitive (money/key) tools before the card is ever raised - which
also makes the [MAINNET] label on the remaining local writes factually
wrong, so it is dropped for pinned turns only. Unpinned turns are untouched:
same gating, same marks.

Verified live against a mainnet-configured fresh profile: readout says
devnet (pinned), no [MAINNET] anywhere, card in 21s, reject narrated.
@nullxnothing nullxnothing enabled auto-merge (squash) July 3, 2026 22:26
@nullxnothing nullxnothing merged commit 51d2e24 into main Jul 3, 2026
5 checks passed
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.

1 participant