value delivered before the user is asked to configure something. That is settings-first onboarding. Completion rates collapse.
The user gets their first meaningful result before the onboarding screen closes. Not after. During. The onboarding IS the first audit.
Not first login. Not first finding. First fix merged. Every screen in the flow exists to remove friction toward that moment.
GitHub's native App install flow. Hydra does not control this screen.
On completion, GitHub redirects back with ?installation_id=...&code=... -- handled by the existing SetupWizard callback.
No new engineering needed here.
Headline: Connect your Anthropic API key
Body: You control the costs. We never mark them up.
sk-ant-"Headline: Which repo do you want to start with?
Standard GitHub repo selector. Name + last pushed date. Nothing else.
This is not a spinner. The user needs to see something real is happening.
Each line appears as the step completes. Animated ellipsis if a step exceeds 3 seconds.
"Typical audit: 8-12 minutes. $15-35 in Anthropic costs."
Sets expectations. Their API key -- their cost. No surprises.
Cannot interrupt a running audit. Timeout (>15 min)? Surface partial findings. None? Switch to demo repo.
Headline: Hydra found [N] issues in [repo name]
One finding shown. Not a list. One finding made concrete and solvable.
"Hydra can fix this automatically -- write the code change, run your tests, and open a PR."
[See the fix →]
The full findings list lives on the dashboard. This screen has one job: make the problem feel real and the fix feel obvious.
The user sees the finding, then watches Hydra fix it and open a real PR. Plan selection comes after the PR is created -- when the value is not a promise but a fact.
Same live-progress pattern as Step 4. Not a spinner.
Estimated time: 3-6 minutes.
PR opened on GitHub. Proceed to Step 7.
Do not dead-end. Offer to create a Linear ticket for the finding instead.
User leaves onboarding with something tangible -- a tracked issue, not a blank screen.
Hydra opened a PR in [repo name]. Review it and merge when ready.
[View PR on GitHub →] primary
[Go to dashboard →] secondary
The user has just watched Hydra write a fix, pass tests, and open a real PR on their code. The value is not hypothetical. This is the right moment to choose a plan.
| Plan | Trial | Credit card | Stripe |
|---|---|---|---|
| Free | None | Never | Not created |
| Team | 14 days | Not at signup | Day 14 |
| Business | 14 days | Not at signup | Day 14 |
| Enterprise | White-glove | Negotiated | Contract |
Onboarding continues immediately after plan selection. No interruption.
One finding card visible from onboarding. Full findings list accessible but not the lead. PR merge is still pending -- the checklist nudges toward it.
Checklist disappears when complete or dismissed. "First fix merged" closes via GitHub webhook.
Onboarding complete. The aha moment is one PR merge away. The checklist keeps the user moving toward it.
"Run Hydra on a second repo" surfaces naturally after the first repo is working. Not during onboarding. After.
Audit of user's repo returns zero findings. Surface the result honestly, then offer a real alternative -- not a pre-seeded fake.
Enter any public GitHub repo URL. Hydra runs a real audit -- live LLM, real findings, real fix. Not a demo. Not pre-loaded data.
| Scenario | Handling |
|---|---|
| GitHub OAuth fails | Error screen with retry + contact support link. |
| Anthropic key invalid | Inline error: "Check your key starts with sk-ant-." Do not advance. |
| Audit times out (>15 min) | Surface partial findings if any exist. If none, switch to demo repo. |
| No supported languages in repo | Explain supported languages. Prompt to pick a different repo. Do not switch to demo repo silently -- requires explicit re-selection. |
| Fix fails all gauntlet gates | Offer to create a Linear ticket instead. Never dead-end. |
| Browser closed mid-onboarding | Resume from last completed step on next login. State persisted server-side. |
| Enterprise clicks "Talk to us" | Route to contact form. Onboarding ends here -- separate white-glove path. |
| Trial user misses day 14 | Reverts to Free tier limits. Does not lose access. No punitive gate. |
| Event | What it measures |
|---|---|
onboarding_started | GitHub App install callback received |
api_key_connected | Anthropic key validated and saved |
repo_selected | User picked a repo and clicked Start |
audit_completed | Findings returned (real or demo) |
finding_viewed | Step 5 rendered |
plan_selected | free / team-trial / business-trial / enterprise |
fix_started | Fix workflow kicked off |
pr_created | PR opened on GitHub |
pr_merged | Aha moment. GitHub webhook on merge. |
demo_repo_fallback | Zero findings, demo used |
| Item | Owner | Notes |
|---|---|---|
| Trial terms -- 14-day, no CC | Tristan | Confirm before Stripe implementation begins |
| Demo repo contents | Tyler | 3-5 pre-seeded findings. Python or TypeScript. At least one fixable in onboarding time. |
| Resume-from-last-step | Tyler | Server-side state persistence -- browser close must not restart from zero |
| Enterprise contact path | Tristan | Contact form or Calendly? What happens after "Talk to us" is clicked? |
| Day 10 trial reminder email | Tyler | Stripe-triggered or in-house? Copy TBD. |
| Annual discount | Tristan | Show on plan selection screen? Standard PLG is 20% for annual. |
| Seat definition | Tyler | Who counts as a developer seat? Must be unambiguous before Stripe setup. |
| Brand identity | Neil | All visual implementation blocked until brand is delivered. |
First fix merged in under 24 hours.
That is the only metric that matters at launch.