Skip to content

fix: preserve onboarding progress across the Screen Recording restart#214

Closed
quiet-node wants to merge 1 commit into
mainfrom
fix/onboarding-screen-recording-restart
Closed

fix: preserve onboarding progress across the Screen Recording restart#214
quiet-node wants to merge 1 commit into
mainfrom
fix/onboarding-screen-recording-restart

Conversation

@quiet-node

Copy link
Copy Markdown
Owner

Overview

Granting Screen Recording during onboarding requires a macOS restart. When the user accepted macOS's own "Quit & Reopen" prompt, the app relaunched onto the first onboarding screen (Grant Accessibility) instead of advancing, discarding the permissions they had just granted. After this change the restart continues onboarding to the model-check step as expected.

Cause

notify_frontend_ready chose which onboarding screen to show on every launch by calling the live macOS permission APIs (AXIsProcessTrusted, CGPreflightScreenCaptureAccess) and falling back to step 1 on a false. Those APIs return false negatives for a short settle window right after a process restart, so the post-restart launch wrongly concluded the permissions were missing. The macOS-initiated "Quit & Reopen" also never advanced the persisted onboarding stage (only the in-app "Quit & Reopen Thuki" button did), so there was no trusted progress to fall back on.

How it works

  • Startup trusts the persisted onboarding stage for every in-progress stage (permissions, model_check, intro) and consults the live permission grants only to detect a genuine revocation once onboarding is complete. The decision lives in a pure decide_startup_action helper.
  • PermissionsStep resumes the Screen Recording grant after the restart: if the permission is now active it advances straight to the model-check step via the new advance_past_permissions command, with no second restart and no re-granting.
  • The inline grant flow persists its resume marker even when it does not schedule the restart itself, so a macOS-initiated restart is recoverable.
  • Both restart routes (macOS's prompt and the in-app button) now land on the same model-check stage, so the model-check gate can no longer be skipped by choosing one button over the other.

Testing

  • bun run test:all:coverage: frontend and backend suites pass at 100% coverage, including new cases for the post-restart advance, the not-yet-granted fallback, and the unmount guard.
  • bun run validate-build: lint, format, typecheck, and the release build/bundle all clean.

Note: the end-to-end TCC restart flow cannot be exercised in CI because it requires real macOS permission grants; the fix is verified by unit tests and code trace.

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
@quiet-node quiet-node closed this Jun 10, 2026
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