diff --git a/src/Expensify.tsx b/src/Expensify.tsx
index 2b5a5d892640..be371c56f0cc 100644
--- a/src/Expensify.tsx
+++ b/src/Expensify.tsx
@@ -117,6 +117,9 @@ function Expensify() {
     const [isSidebarLoaded] = useOnyx(ONYXKEYS.IS_SIDEBAR_LOADED, {canBeMissing: true});
     const [screenShareRequest] = useOnyx(ONYXKEYS.SCREEN_SHARE_REQUEST, {canBeMissing: true});
     const [lastVisitedPath] = useOnyx(ONYXKEYS.LAST_VISITED_PATH, {canBeMissing: true});
+    const [currentOnboardingPurposeSelected] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED, {canBeMissing: true});
+    const [currentOnboardingCompanySize] = useOnyx(ONYXKEYS.ONBOARDING_COMPANY_SIZE, {canBeMissing: true});
+    const [onboardingInitialPath] = useOnyx(ONYXKEYS.ONBOARDING_LAST_VISITED_PATH, {canBeMissing: true});
     const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {canBeMissing: false});
     const [hasLoadedApp] = useOnyx(ONYXKEYS.HAS_LOADED_APP, {canBeMissing: true});
     const [isLoadingApp] = useOnyx(ONYXKEYS.IS_LOADING_APP, {canBeMissing: true});
@@ -345,7 +348,16 @@ function Expensify() {
                 if (introSelected === undefined) {
                     Log.info('[Deep link] introSelected is undefined when processing initial URL', false, {url});
                 }
-                openReportFromDeepLink(url, allReports, isAuthenticated, conciergeReportID, introSelected);
+                openReportFromDeepLink(
+                    url,
+                    currentOnboardingPurposeSelected,
+                    currentOnboardingCompanySize,
+                    onboardingInitialPath,
+                    allReports,
+                    isAuthenticated,
+                    introSelected,
+                    conciergeReportID,
+                );
             } else {
                 Report.doneCheckingPublicRoom();
             }
@@ -362,7 +374,16 @@ function Expensify() {
                 Log.info('[Deep link] introSelected is undefined when processing URL change', false, {url: state.url});
             }
             const isCurrentlyAuthenticated = hasAuthToken();
-            openReportFromDeepLink(state.url, allReports, isCurrentlyAuthenticated, conciergeReportID, introSelected);
+            openReportFromDeepLink(
+                state.url,
+                currentOnboardingPurposeSelected,
+                currentOnboardingCompanySize,
+                onboardingInitialPath,
+                allReports,
+                isCurrentlyAuthenticated,
+                introSelected,
+                conciergeReportID,
+            );
         });
 
         return () => {
diff --git a/src/hooks/useOnboardingFlow.ts b/src/hooks/useOnboardingFlow.ts
index 7d32c505a164..5b3009214593 100644
--- a/src/hooks/useOnboardingFlow.ts
+++ b/src/hooks/useOnboardingFlow.ts
@@ -1,8 +1,10 @@
 import {isSingleNewDotEntrySelector} from '@selectors/HybridApp';
 import {hasCompletedGuidedSetupFlowSelector, tryNewDotOnyxSelector} from '@selectors/Onboarding';
 import {emailSelector} from '@selectors/Session';
-import {useEffect, useMemo} from 'react';
+import {useEffect, useMemo, useRef} from 'react';
 import {InteractionManager} from 'react-native';
+import {startOnboardingFlow} from '@libs/actions/Welcome/OnboardingFlow';
+import Log from '@libs/Log';
 import getCurrentUrl from '@libs/Navigation/currentUrl';
 import Navigation, {navigationRef} from '@libs/Navigation/Navigation';
 import {buildCannedSearchQuery} from '@libs/SearchQueryUtils';
@@ -27,16 +29,20 @@ function useOnboardingFlowRouter() {
     const [onboardingValues, isOnboardingCompletedMetadata] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {
         canBeMissing: true,
     });
-    const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true});
+    const [currentOnboardingPurposeSelected] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED, {canBeMissing: true});
+    const [currentOnboardingCompanySize] = useOnyx(ONYXKEYS.ONBOARDING_COMPANY_SIZE, {canBeMissing: true});
+    const [onboardingInitialPath, onboardingInitialPathMetadata] = useOnyx(ONYXKEYS.ONBOARDING_LAST_VISITED_PATH, {canBeMissing: true});
+    const [account, accountMetadata] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true});
+    const isOnboardingLoading = isLoadingOnyxValue(onboardingInitialPathMetadata, accountMetadata);
 
     const [sessionEmail] = useOnyx(ONYXKEYS.SESSION, {canBeMissing: true, selector: emailSelector});
     const isLoggingInAsNewSessionUser = isLoggingInAsNewUser(currentUrl, sessionEmail);
+    const startedOnboardingFlowRef = useRef(false);
     const [tryNewDot, tryNewDotMetadata] = useOnyx(ONYXKEYS.NVP_TRY_NEW_DOT, {
         selector: tryNewDotOnyxSelector,
         canBeMissing: true,
     });
     const {isHybridAppOnboardingCompleted, hasBeenAddedToNudgeMigration} = tryNewDot ?? {};
-    const isOnboardingLoading = isLoadingOnyxValue(isOnboardingCompletedMetadata, tryNewDotMetadata);
 
     const [dismissedProductTraining, dismissedProductTrainingMetadata] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING, {canBeMissing: true});
 
@@ -50,7 +56,7 @@ function useOnboardingFlowRouter() {
         // This should delay opening the onboarding modal so it does not interfere with the ongoing ReportScreen params changes
         // eslint-disable-next-line @typescript-eslint/no-deprecated
         const handle = InteractionManager.runAfterInteractions(() => {
-            // Prevent showing onboarding if we are logging in as a new user with short lived token
+            // Prevent starting the onboarding flow if we are logging in as a new user with short lived token
             if (currentUrl?.includes(ROUTES.TRANSITION_BETWEEN_APPS) && isLoggingInAsNewSessionUser) {
                 return;
             }
@@ -83,6 +89,12 @@ function useOnboardingFlowRouter() {
                 return;
             }
 
+            if (hasBeenAddedToNudgeMigration) {
+                return;
+            }
+
+            const isOnboardingCompleted = hasCompletedGuidedSetupFlowSelector(onboardingValues) && onboardingValues?.testDriveModalDismissed !== false;
+
             if (CONFIG.IS_HYBRID_APP) {
                 // For single entries, such as using the Travel feature from OldDot, we don't want to show onboarding
                 if (isSingleNewDotEntry) {
@@ -93,6 +105,37 @@ function useOnboardingFlowRouter() {
                 if (isHybridAppOnboardingCompleted === false) {
                     Navigation.navigate(ROUTES.EXPLANATION_MODAL_ROOT);
                 }
+
+                // But if the hybrid app onboarding is completed, but NewDot onboarding is not completed, we start NewDot onboarding flow
+                // This is a special case when user created an account from NewDot without finishing the onboarding flow and then logged in from OldDot
+                if (isHybridAppOnboardingCompleted === true && isOnboardingCompleted === false && !startedOnboardingFlowRef.current) {
+                    startedOnboardingFlowRef.current = true;
+                    Log.info('[Onboarding] Hybrid app onboarding is completed, but NewDot onboarding is not completed, starting NewDot onboarding flow');
+                    startOnboardingFlow({
+                        onboardingValuesParam: onboardingValues,
+                        isUserFromPublicDomain: !!account?.isFromPublicDomain,
+                        hasAccessiblePolicies: !!account?.hasAccessibleDomainPolicies,
+                        currentOnboardingCompanySize,
+                        currentOnboardingPurposeSelected,
+                        onboardingInitialPath,
+                        onboardingValues,
+                    });
+                }
+            }
+
+            // If the user is not transitioning from OldDot to NewDot, we should start NewDot onboarding flow if it's not completed yet
+            if (!CONFIG.IS_HYBRID_APP && isOnboardingCompleted === false && !startedOnboardingFlowRef.current) {
+                startedOnboardingFlowRef.current = true;
+                Log.info('[Onboarding] Not a hybrid app, NewDot onboarding is not completed, starting NewDot onboarding flow');
+                startOnboardingFlow({
+                    onboardingValuesParam: onboardingValues,
+                    isUserFromPublicDomain: !!account?.isFromPublicDomain,
+                    hasAccessiblePolicies: !!account?.hasAccessibleDomainPolicies,
+                    currentOnboardingCompanySize,
+                    currentOnboardingPurposeSelected,
+                    onboardingInitialPath,
+                    onboardingValues,
+                });
             }
         });
 
@@ -109,11 +152,16 @@ function useOnboardingFlowRouter() {
         hasBeenAddedToNudgeMigration,
         dismissedProductTrainingMetadata,
         dismissedProductTraining?.migratedUserWelcomeModal,
+        onboardingValues,
         dismissedProductTraining,
+        account?.isFromPublicDomain,
+        account?.hasAccessibleDomainPolicies,
         currentUrl,
         isLoggingInAsNewSessionUser,
+        currentOnboardingCompanySize,
+        currentOnboardingPurposeSelected,
+        onboardingInitialPath,
         isOnboardingLoading,
-        onboardingValues,
     ]);
 
     return {
diff --git a/src/libs/Navigation/AppNavigator/createRootStackNavigator/RootStackRouter.ts b/src/libs/Navigation/AppNavigator/createRootStackNavigator/RootStackRouter.ts
index 8eceff88a361..651bc15f14b1 100644
--- a/src/libs/Navigation/AppNavigator/createRootStackNavigator/RootStackRouter.ts
+++ b/src/libs/Navigation/AppNavigator/createRootStackNavigator/RootStackRouter.ts
@@ -1,11 +1,9 @@
-import {CommonActions, StackRouter} from '@react-navigation/native';
-import type {RouterConfigOptions, StackActionType, StackNavigationState} from '@react-navigation/native';
+import type {CommonActions, RouterConfigOptions, StackActionType, StackNavigationState} from '@react-navigation/native';
+import {findFocusedRoute, StackRouter} from '@react-navigation/native';
 import type {ParamListBase} from '@react-navigation/routers';
-import {createGuardContext, evaluateGuards} from '@libs/Navigation/guards';
-import getAdaptedStateFromPath from '@libs/Navigation/helpers/getAdaptedStateFromPath';
-import {isFullScreenName} from '@libs/Navigation/helpers/isNavigatorName';
+import {isFullScreenName, isOnboardingFlowName} from '@libs/Navigation/helpers/isNavigatorName';
 import isSideModalNavigator from '@libs/Navigation/helpers/isSideModalNavigator';
-import {linkingConfig} from '@libs/Navigation/linkingConfig';
+import * as Welcome from '@userActions/Welcome';
 import CONST from '@src/CONST';
 import NAVIGATORS from '@src/NAVIGATORS';
 import {
@@ -58,45 +56,20 @@ function isPreloadAction(action: RootStackNavigatorAction): action is PreloadAct
     return action.type === CONST.NAVIGATION.ACTION_TYPE.PRELOAD;
 }
 
-/**
- * Evaluates navigation guards and handles BLOCK/REDIRECT results
- *
- * @param state - Current navigation state
- * @param action - Navigation action being attempted
- * @param configOptions - Router configuration options
- * @param stackRouter - Stack router instance
- * @returns Modified state if guard blocks/redirects, null if navigation should proceed
- */
-function handleNavigationGuards(
-    state: StackNavigationState<ParamListBase>,
-    action: RootStackNavigatorAction,
-    configOptions: RouterConfigOptions,
-    stackRouter: ReturnType<typeof StackRouter>,
-): ReturnType<ReturnType<typeof StackRouter>['getStateForAction']> | null {
-    const guardContext = createGuardContext();
-    const guardResult = evaluateGuards(state, action, guardContext);
-
-    if (guardResult.type === 'BLOCK') {
-        syncBrowserHistory(state);
-        return state;
+function shouldPreventReset(state: StackNavigationState<ParamListBase>, action: CommonActions.Action | StackActionType) {
+    if (action.type !== CONST.NAVIGATION_ACTIONS.RESET || !action?.payload) {
+        return false;
     }
+    const currentFocusedRoute = findFocusedRoute(state);
+    const targetFocusedRoute = findFocusedRoute(action?.payload);
 
-    if (guardResult.type === 'REDIRECT') {
-        const redirectState = getAdaptedStateFromPath(guardResult.route, linkingConfig.config);
-
-        if (!redirectState || !redirectState.routes) {
-            return null;
-        }
-
-        const resetAction = CommonActions.reset({
-            index: redirectState.index ?? redirectState.routes.length - 1,
-            routes: redirectState.routes,
-        });
-
-        return stackRouter.getStateForAction(state, resetAction, configOptions);
+    // We want to prevent the user from navigating back to a non-onboarding screen if they are currently on an onboarding screen
+    if (isOnboardingFlowName(currentFocusedRoute?.name) && !isOnboardingFlowName(targetFocusedRoute?.name)) {
+        Welcome.setOnboardingErrorMessage('onboarding.purpose.errorBackButton');
+        return true;
     }
 
-    return null;
+    return false;
 }
 
 function isNavigatingToModalFromModal(state: StackNavigationState<ParamListBase>, action: CommonActions.Action | StackActionType): action is PushActionType {
@@ -117,14 +90,6 @@ function RootStackRouter(options: RootStackNavigatorRouterOptions) {
     return {
         ...stackRouter,
         getStateForAction(state: StackNavigationState<ParamListBase>, action: RootStackNavigatorAction, configOptions: RouterConfigOptions) {
-            // Evaluate navigation guards FIRST
-            const guardState = handleNavigationGuards(state, action, configOptions, stackRouter);
-            if (guardState) {
-                return guardState;
-            }
-
-            // Guards allowed navigation - continue with routing logic
-
             if (isPreloadAction(action) && action.payload.name === state.routes.at(-1)?.name) {
                 return state;
             }
@@ -156,6 +121,12 @@ function RootStackRouter(options: RootStackNavigatorRouterOptions) {
                 return handlePushFullscreenAction(state, action, configOptions, stackRouter);
             }
 
+            // Don't let the user navigate back to a non-onboarding screen if they are currently on an onboarding screen and it's not finished.
+            if (shouldPreventReset(state, action)) {
+                syncBrowserHistory(state);
+                return state;
+            }
+
             if (isNavigatingToModalFromModal(state, action)) {
                 return handleNavigatingToModalFromModal(state, action, configOptions, stackRouter);
             }
diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx
index 1e2d153be3d8..25bbc0d01666 100644
--- a/src/libs/Navigation/NavigationRoot.tsx
+++ b/src/libs/Navigation/NavigationRoot.tsx
@@ -1,7 +1,8 @@
 import type {NavigationState} from '@react-navigation/native';
 import {DarkTheme, DefaultTheme, findFocusedRoute, getPathFromState, NavigationContainer} from '@react-navigation/native';
-import {hasCompletedGuidedSetupFlowSelector} from '@selectors/Onboarding';
+import {hasCompletedGuidedSetupFlowSelector, wasInvitedToNewDotSelector} from '@selectors/Onboarding';
 import React, {useCallback, useContext, useEffect, useMemo, useRef} from 'react';
+import {useOnboardingValues} from '@components/OnyxListItemProvider';
 import {ScrollOffsetContext} from '@components/ScrollOffsetContextProvider';
 import {useCurrentReportIDActions} from '@hooks/useCurrentReportID';
 import useOnyx from '@hooks/useOnyx';
@@ -16,6 +17,8 @@ import shouldOpenLastVisitedPath from '@libs/shouldOpenLastVisitedPath';
 import {getPathFromURL} from '@libs/Url';
 import {updateLastVisitedPath} from '@userActions/App';
 import {updateOnboardingLastVisitedPath} from '@userActions/Welcome';
+import {getOnboardingInitialPath} from '@userActions/Welcome/OnboardingFlow';
+import CONFIG from '@src/CONFIG';
 import CONST from '@src/CONST';
 import {endSpan, getSpan, startSpan} from '@src/libs/telemetry/activeSpans';
 import {navigationIntegration} from '@src/libs/telemetry/integrations';
@@ -99,11 +102,20 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady}: N
         selector: hasCompletedGuidedSetupFlowSelector,
         canBeMissing: true,
     });
-
+    const [wasInvitedToNewDot = false] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, {
+        selector: wasInvitedToNewDotSelector,
+        canBeMissing: true,
+    });
+    const [hasNonPersonalPolicy] = useOnyx(ONYXKEYS.HAS_NON_PERSONAL_POLICY, {canBeMissing: true});
+    const [currentOnboardingPurposeSelected] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED, {canBeMissing: true});
+    const [currentOnboardingCompanySize] = useOnyx(ONYXKEYS.ONBOARDING_COMPANY_SIZE, {canBeMissing: true});
+    const [onboardingInitialPath] = useOnyx(ONYXKEYS.ONBOARDING_LAST_VISITED_PATH, {canBeMissing: true});
+    const onboardingValues = useOnboardingValues();
     const previousAuthenticated = usePrevious(authenticated);
 
     const initialState = useMemo(() => {
         const path = initialUrl ? getPathFromURL(initialUrl) : null;
+
         if (path?.includes(ROUTES.MIGRATED_USER_WELCOME_MODAL.route) && shouldOpenLastVisitedPath(lastVisitedPath) && isOnboardingCompleted && authenticated) {
             Navigation.isNavigationReady().then(() => {
                 Navigation.navigate(ROUTES.MIGRATED_USER_WELCOME_MODAL.getRoute());
@@ -124,6 +136,22 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady}: N
             return undefined;
         }
 
+        // If the user haven't completed the flow, we want to always redirect them to the onboarding flow.
+        // We also make sure that the user is authenticated, isn't part of a group workspace, isn't in the transition flow & wasn't invited to NewDot.
+        if (!CONFIG.IS_HYBRID_APP && !hasNonPersonalPolicy && !isOnboardingCompleted && !wasInvitedToNewDot && authenticated) {
+            return getAdaptedStateFromPath(
+                getOnboardingInitialPath({
+                    isUserFromPublicDomain: !!account.isFromPublicDomain,
+                    hasAccessiblePolicies: !!account.hasAccessibleDomainPolicies,
+                    currentOnboardingPurposeSelected,
+                    currentOnboardingCompanySize,
+                    onboardingInitialPath,
+                    onboardingValues,
+                }),
+                linkingConfig.config,
+            );
+        }
+
         if (shouldOpenLastVisitedPath(lastVisitedPath) && authenticated) {
             // Only skip restoration if there's a specific deep link that's not the root
             // This allows restoration when app is killed and reopened without a deep link
diff --git a/src/libs/Navigation/guards/OnboardingGuard.ts b/src/libs/Navigation/guards/OnboardingGuard.ts
deleted file mode 100644
index e9ffc469b20a..000000000000
--- a/src/libs/Navigation/guards/OnboardingGuard.ts
+++ /dev/null
@@ -1,169 +0,0 @@
-import type {NavigationAction, NavigationState} from '@react-navigation/native';
-import {findFocusedRoute} from '@react-navigation/native';
-import {isSingleNewDotEntrySelector} from '@selectors/HybridApp';
-import {hasCompletedGuidedSetupFlowSelector, tryNewDotOnyxSelector, wasInvitedToNewDotSelector} from '@selectors/Onboarding';
-import Onyx from 'react-native-onyx';
-import type {OnyxEntry} from 'react-native-onyx';
-import type {ValueOf} from 'type-fest';
-import {setOnboardingErrorMessage} from '@libs/actions/Welcome';
-import Log from '@libs/Log';
-import {isOnboardingFlowName} from '@libs/Navigation/helpers/isNavigatorName';
-import {getOnboardingInitialPath} from '@userActions/Welcome/OnboardingFlow';
-import CONFIG from '@src/CONFIG';
-import CONST from '@src/CONST';
-import ONYXKEYS from '@src/ONYXKEYS';
-import type {Route} from '@src/ROUTES';
-import ROUTES from '@src/ROUTES';
-import type {Account, Onboarding} from '@src/types/onyx';
-import type {GuardResult, NavigationGuard} from './types';
-
-type OnboardingCompanySize = ValueOf<typeof CONST.ONBOARDING_COMPANY_SIZE>;
-type OnboardingPurpose = ValueOf<typeof CONST.ONBOARDING_CHOICES>;
-
-/**
- * Module-level Onyx subscriptions for OnboardingGuard
- * These provide synchronous access to onboarding-related data
- */
-let onboarding: OnyxEntry<Onboarding>;
-let account: OnyxEntry<Account>;
-let tryNewDot: {isHybridAppOnboardingCompleted: boolean | undefined; hasBeenAddedToNudgeMigration: boolean} | undefined;
-let hybridApp: {isSingleNewDotEntry?: boolean} | undefined;
-let onboardingPurposeSelected: OnyxEntry<OnboardingPurpose>;
-let onboardingCompanySize: OnyxEntry<OnboardingCompanySize>;
-let onboardingInitialPath: OnyxEntry<string>;
-let hasNonPersonalPolicy: OnyxEntry<boolean>;
-let wasInvitedToNewDot: boolean | undefined;
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.NVP_ONBOARDING,
-    callback: (value) => {
-        onboarding = value;
-    },
-});
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.ACCOUNT,
-    callback: (value) => {
-        account = value;
-    },
-});
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.NVP_TRY_NEW_DOT,
-    callback: (value) => {
-        tryNewDot = value ? tryNewDotOnyxSelector(value) : undefined;
-    },
-});
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.HYBRID_APP,
-    callback: (value) => {
-        hybridApp = {isSingleNewDotEntry: value ? isSingleNewDotEntrySelector(value) : undefined};
-    },
-});
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.ONBOARDING_PURPOSE_SELECTED,
-    callback: (value) => {
-        onboardingPurposeSelected = value;
-    },
-});
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.ONBOARDING_COMPANY_SIZE,
-    callback: (value) => {
-        onboardingCompanySize = value;
-    },
-});
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.ONBOARDING_LAST_VISITED_PATH,
-    callback: (value) => {
-        onboardingInitialPath = value;
-    },
-});
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.HAS_NON_PERSONAL_POLICY,
-    callback: (value) => {
-        hasNonPersonalPolicy = value;
-    },
-});
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.NVP_INTRO_SELECTED,
-    callback: (value) => {
-        wasInvitedToNewDot = value ? wasInvitedToNewDotSelector(value) : undefined;
-    },
-});
-
-/**
- * Helper to get the correct onboarding route based on current progress
- */
-function getOnboardingRoute(): Route {
-    return getOnboardingInitialPath({
-        onboardingValuesParam: onboarding,
-        isUserFromPublicDomain: !!account?.isFromPublicDomain,
-        hasAccessiblePolicies: !!account?.hasAccessibleDomainPolicies,
-        currentOnboardingCompanySize: onboardingCompanySize,
-        currentOnboardingPurposeSelected: onboardingPurposeSelected,
-        onboardingInitialPath,
-        onboardingValues: onboarding,
-    }) as Route;
-}
-
-function shouldPreventReset(state: NavigationState, action: NavigationAction) {
-    if (action.type !== CONST.NAVIGATION_ACTIONS.RESET || !action?.payload) {
-        return false;
-    }
-
-    const currentFocusedRoute = findFocusedRoute(state);
-    const targetFocusedRoute = findFocusedRoute(action?.payload as NavigationState);
-
-    // We want to prevent the user from navigating back to a non-onboarding screen if they are currently on an onboarding screen
-    if (isOnboardingFlowName(currentFocusedRoute?.name) && !isOnboardingFlowName(targetFocusedRoute?.name)) {
-        setOnboardingErrorMessage('onboarding.purpose.errorBackButton');
-        return true;
-    }
-
-    return false;
-}
-
-/**
- * OnboardingGuard handles ONLY the core NewDot onboarding flow
- */
-const OnboardingGuard: NavigationGuard = {
-    name: 'OnboardingGuard',
-
-    evaluate: (state, action, context): GuardResult => {
-        if (shouldPreventReset(state, action)) {
-            return {type: 'BLOCK', reason: 'Cannot reset to non-onboarding screen while on onboarding'};
-        }
-
-        const isTransitioning = context.currentUrl?.includes(ROUTES.TRANSITION_BETWEEN_APPS);
-        const isOnboardingCompleted = hasCompletedGuidedSetupFlowSelector(onboarding) ?? false;
-        const isMigratedUser = tryNewDot?.hasBeenAddedToNudgeMigration ?? false;
-        const isSingleEntry = hybridApp?.isSingleNewDotEntry ?? false;
-        const needsExplanationModal = (CONFIG.IS_HYBRID_APP && tryNewDot?.isHybridAppOnboardingCompleted !== true) ?? false;
-        // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
-        const isInvitedOrGroupMember = (!CONFIG.IS_HYBRID_APP && (hasNonPersonalPolicy || wasInvitedToNewDot)) ?? false;
-
-        const shouldSkipOnboarding = context.isLoading || isTransitioning || isOnboardingCompleted || isMigratedUser || isSingleEntry || needsExplanationModal || isInvitedOrGroupMember;
-
-        if (shouldSkipOnboarding) {
-            return {type: 'ALLOW'};
-        }
-
-        // User needs onboarding - calculate the correct step and redirect
-        const onboardingRoute = getOnboardingRoute();
-
-        Log.info('[OnboardingGuard] Redirecting to onboarding route', false, {onboardingRoute});
-
-        return {
-            type: 'REDIRECT',
-            route: onboardingRoute,
-        };
-    },
-};
-
-export default OnboardingGuard;
diff --git a/src/libs/Navigation/guards/TestDriveModalGuard.ts b/src/libs/Navigation/guards/TestDriveModalGuard.ts
deleted file mode 100644
index 5adb7146824b..000000000000
--- a/src/libs/Navigation/guards/TestDriveModalGuard.ts
+++ /dev/null
@@ -1,163 +0,0 @@
-import type {NavigationAction, NavigationState} from '@react-navigation/native';
-import {findFocusedRoute} from '@react-navigation/native';
-import {hasCompletedGuidedSetupFlowSelector} from '@selectors/Onboarding';
-import Onyx from 'react-native-onyx';
-import type {OnyxEntry} from 'react-native-onyx';
-import Log from '@libs/Log';
-import CONST from '@src/CONST';
-import NAVIGATORS from '@src/NAVIGATORS';
-import ONYXKEYS from '@src/ONYXKEYS';
-import ROUTES from '@src/ROUTES';
-import SCREENS from '@src/SCREENS';
-import type Onboarding from '@src/types/onyx/Onboarding';
-import type {GuardResult, NavigationGuard} from './types';
-
-/**
- * Module-level Onyx subscriptions for TestDriveModalGuard
- */
-let onboarding: OnyxEntry<Onboarding>;
-let onboardingPolicyID: OnyxEntry<string>;
-let hasNonPersonalPolicy: OnyxEntry<boolean>;
-
-let hasRedirectedToTestDriveModal = false;
-
-/**
- * Reset the session flag (for testing purposes)
- */
-function resetSessionFlag() {
-    hasRedirectedToTestDriveModal = false;
-}
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.NVP_ONBOARDING,
-    callback: (value) => {
-        onboarding = value;
-
-        // Reset the session flag when modal is dismissed
-        if (value?.testDriveModalDismissed === true) {
-            hasRedirectedToTestDriveModal = false;
-        }
-    },
-});
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.ONBOARDING_POLICY_ID,
-    callback: (value) => {
-        onboardingPolicyID = value;
-    },
-});
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.HAS_NON_PERSONAL_POLICY,
-    callback: (value) => {
-        hasNonPersonalPolicy = value;
-    },
-});
-
-/**
- * Check if navigation should be blocked while the test drive modal is active.
- * After the guard redirects to the modal, there's a delay before the native Modal overlay becomes visible
- * During this window, tab switches can push screens on top of the modal navigator,
- * causing DISMISS_MODAL to fail since it only checks the last route.
- */
-function shouldBlockWhileModalActive(state: NavigationState, action: NavigationAction): boolean {
-    const isModalDismissed = onboarding?.testDriveModalDismissed === true;
-    if (!hasRedirectedToTestDriveModal || isModalDismissed) {
-        return false;
-    }
-
-    // Only block when the test drive modal is the LAST route (on top of the stack).
-    // If something was already pushed on top (broken state), don't block — the user
-    // needs to be able to navigate to recover from the error.
-    const lastRoute = state.routes.at(-1);
-    if (lastRoute?.name !== NAVIGATORS.TEST_DRIVE_MODAL_NAVIGATOR) {
-        return false;
-    }
-
-    // Allow DISMISS_MODAL (Skip button) and GO_BACK (close/X button, confirm flow)
-    if (action.type === CONST.NAVIGATION.ACTION_TYPE.DISMISS_MODAL || action.type === CONST.NAVIGATION.ACTION_TYPE.GO_BACK) {
-        return false;
-    }
-
-    return true;
-}
-
-/**
- * Check if we're already on or navigating to the test drive modal
- * This prevents redirect loops where our redirect creates new navigation actions
- */
-function isNavigatingToTestDriveModal(state: NavigationState, action: NavigationAction): boolean {
-    const currentRoute = findFocusedRoute(state);
-    if (currentRoute?.name === SCREENS.TEST_DRIVE_MODAL.ROOT) {
-        return true;
-    }
-
-    if (action.type === 'RESET' && action.payload) {
-        const targetRoute = findFocusedRoute(action.payload as NavigationState);
-        if (targetRoute?.name === SCREENS.TEST_DRIVE_MODAL.ROOT) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-/**
- * TestDriveModalGuard handles the test drive modal flow
- * This modal appears after a user completes the guided setup flow but hasn't dismissed the test drive modal yet
- */
-const TestDriveModalGuard: NavigationGuard = {
-    name: 'TestDriveModalGuard',
-
-    evaluate: (state: NavigationState, action: NavigationAction, context): GuardResult => {
-        if (context.isLoading) {
-            return {type: 'ALLOW'};
-        }
-
-        if (shouldBlockWhileModalActive(state, action)) {
-            return {type: 'BLOCK', reason: '[TestDriveModalGuard] Blocking navigation while test drive modal is active'};
-        }
-
-        const isModalDismissed = onboarding?.testDriveModalDismissed === true;
-        const isNavigatingToModal = isNavigatingToTestDriveModal(state, action);
-
-        // Redirect to home if trying to access dismissed test drive modal (prevent URL navigation)
-        if (isNavigatingToModal && isModalDismissed) {
-            Log.info('[TestDriveModalGuard] Redirecting to home - test drive modal has been dismissed');
-            return {type: 'REDIRECT', route: ROUTES.HOME};
-        }
-
-        // Allow if we're already navigating to the modal (prevents redirect loops)
-        if (isNavigatingToModal) {
-            return {type: 'ALLOW'};
-        }
-
-        // Skip if already redirected or user has accessible policy
-        if (hasRedirectedToTestDriveModal || (onboardingPolicyID && hasNonPersonalPolicy)) {
-            Log.info('[TestDriveModalGuard] Already redirected or user has accessible policy, allowing');
-            return {type: 'ALLOW'};
-        }
-
-        // Check if user has completed the guided setup flow
-        const hasCompletedGuidedSetup = hasCompletedGuidedSetupFlowSelector(onboarding) ?? false;
-
-        // Check if test drive modal should be shown
-        const shouldShowTestDriveModal = onboarding?.testDriveModalDismissed === false;
-
-        // If user completed setup and modal should be shown, redirect to it once
-        if (hasCompletedGuidedSetup && shouldShowTestDriveModal) {
-            Log.info('[TestDriveModalGuard] Redirecting to test drive modal');
-            hasRedirectedToTestDriveModal = true;
-
-            return {
-                type: 'REDIRECT',
-                route: ROUTES.TEST_DRIVE_MODAL_ROOT.route,
-            };
-        }
-
-        return {type: 'ALLOW'};
-    },
-};
-
-export default TestDriveModalGuard;
-export {resetSessionFlag};
diff --git a/src/libs/Navigation/guards/index.ts b/src/libs/Navigation/guards/index.ts
deleted file mode 100644
index ef8e8c37b2ab..000000000000
--- a/src/libs/Navigation/guards/index.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import type {NavigationAction, NavigationState} from '@react-navigation/native';
-import Onyx from 'react-native-onyx';
-import type {OnyxEntry} from 'react-native-onyx';
-import getCurrentUrl from '@libs/Navigation/currentUrl';
-import ONYXKEYS from '@src/ONYXKEYS';
-import type {Session} from '@src/types/onyx';
-import OnboardingGuard from './OnboardingGuard';
-import TestDriveModalGuard from './TestDriveModalGuard';
-import type {GuardContext, GuardResult, NavigationGuard} from './types';
-
-/**
- * Module-level Onyx subscriptions for common guard context values
- * These provide synchronous access to shared data used by multiple guards
- */
-let session: OnyxEntry<Session>;
-let isLoadingApp = true;
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.SESSION,
-    callback: (value) => {
-        session = value;
-    },
-});
-
-Onyx.connectWithoutView({
-    key: ONYXKEYS.IS_LOADING_APP,
-    callback: (value) => {
-        isLoadingApp = value ?? true;
-    },
-});
-
-/**
- * Registry of all navigation guards
- * Guards are evaluated in the order they are registered
- */
-const guards: NavigationGuard[] = [];
-
-/**
- * Registers a navigation guard
- */
-function registerGuard(guard: NavigationGuard): void {
-    guards.push(guard);
-}
-
-/**
- * Creates a guard context with common computed values
- * Guards access specific Onyx data directly via their own subscriptions for runtime checks,
- *
- * @param overrides - Optional context overrides (e.g., account, onboarding data from hooks)
- * @returns Guard context with common helper flags and optional Onyx data
- */
-function createGuardContext(overrides?: Partial<GuardContext>): GuardContext {
-    const isAuthenticated = !!session?.authToken;
-    const currentUrl = getCurrentUrl();
-    const isLoading = isLoadingApp;
-
-    return {
-        isAuthenticated,
-        isLoading,
-        currentUrl,
-        ...overrides,
-    };
-}
-
-/**
- * Evaluates all registered guards for the given navigation action
- * Evaluation short-circuits on the first BLOCK or REDIRECT result.
- *
- * - BLOCK: block navigation, return unchanged state
- * - REDIRECT: create redirect action and process it
- * - ALLOW: continue with normal navigation
- */
-function evaluateGuards(state: NavigationState, action: NavigationAction, context: GuardContext): GuardResult {
-    for (const guard of guards) {
-        const result = guard.evaluate(state, action, context);
-
-        if (result.type === 'BLOCK' || result.type === 'REDIRECT') {
-            return result;
-        }
-    }
-
-    return {type: 'ALLOW'};
-}
-
-/**
- * Gets all registered guards (useful for testing)
- */
-function getRegisteredGuards(): readonly NavigationGuard[] {
-    return guards;
-}
-
-/**
- * Clears all registered guards (useful for testing)
- */
-function clearGuards(): void {
-    guards.length = 0;
-}
-
-// Register guards in order of evaluation
-// IMPORTANT: Order matters! Guards evaluate in sequence and short-circuit on BLOCK/REDIRECT
-
-registerGuard(OnboardingGuard);
-registerGuard(TestDriveModalGuard);
-
-export {registerGuard, createGuardContext, evaluateGuards, getRegisteredGuards, clearGuards};
-export type {NavigationGuard, GuardResult, GuardContext};
diff --git a/src/libs/Navigation/guards/types.ts b/src/libs/Navigation/guards/types.ts
deleted file mode 100644
index 914dc1493c69..000000000000
--- a/src/libs/Navigation/guards/types.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import type {NavigationAction, NavigationState} from '@react-navigation/native';
-import type {Route} from '@src/ROUTES';
-
-/**
- * Result returned by a navigation guard after evaluation
- */
-type GuardResult = {type: 'ALLOW'} | {type: 'BLOCK'; reason?: string} | {type: 'REDIRECT'; route: Route};
-
-/**
- * Context provided to guards during evaluation
- */
-type GuardContext = {
-    /** Whether the user is authenticated */
-    isAuthenticated: boolean;
-
-    /** Whether the app is still loading initial data */
-    isLoading: boolean;
-
-    /** Current URL (for HybridApp and deep link checks) */
-    currentUrl: string;
-};
-
-/**
- * Navigation guard interface
- * Guards can intercept navigation actions and allow, block, or redirect them
- */
-type NavigationGuard = {
-    /** Guard name for debugging and logging */
-    name: string;
-
-    /**
-     * Evaluates the navigation action and returns a decision
-     * - ALLOW: Let navigation proceed normally
-     * - BLOCK: Prevent navigation and keep current state
-     * - REDIRECT: Replace the navigation with a redirect to a different route
-     */
-    evaluate(state: NavigationState, action: NavigationAction, context: GuardContext): GuardResult;
-};
-
-export type {GuardResult, GuardContext, NavigationGuard};
diff --git a/src/libs/actions/Link.ts b/src/libs/actions/Link.ts
index 8e951001b893..c09d9aa257c8 100644
--- a/src/libs/actions/Link.ts
+++ b/src/libs/actions/Link.ts
@@ -9,6 +9,7 @@ import asyncOpenURL from '@libs/asyncOpenURL';
 import * as Environment from '@libs/Environment/Environment';
 import getIsNarrowLayout from '@libs/getIsNarrowLayout';
 import isPublicScreenRoute from '@libs/isPublicScreenRoute';
+import Log from '@libs/Log';
 import {isOnboardingFlowName} from '@libs/Navigation/helpers/isNavigatorName';
 import normalizePath from '@libs/Navigation/helpers/normalizePath';
 import shouldOpenOnAdminRoom from '@libs/Navigation/helpers/shouldOpenOnAdminRoom';
@@ -28,10 +29,12 @@ import ONYXKEYS from '@src/ONYXKEYS';
 import type {Route} from '@src/ROUTES';
 import ROUTES from '@src/ROUTES';
 import SCREENS from '@src/SCREENS';
-import type {IntroSelected, Report} from '@src/types/onyx';
+import type {Account, IntroSelected, Report} from '@src/types/onyx';
 import {doneCheckingPublicRoom, navigateToConciergeChat, openReport} from './Report';
 import {canAnonymousUserAccessRoute, isAnonymousUser, signOutAndRedirectToSignIn, waitForUserSignIn} from './Session';
-import {setOnboardingErrorMessage} from './Welcome';
+import {isOnboardingFlowCompleted, setOnboardingErrorMessage} from './Welcome';
+import {startOnboardingFlow} from './Welcome/OnboardingFlow';
+import type {OnboardingCompanySize, OnboardingPurpose} from './Welcome/OnboardingFlow';
 
 let isNetworkOffline = false;
 let networkStatus: NetworkStatus;
@@ -53,6 +56,15 @@ Onyx.connectWithoutView({
     },
 });
 
+let account: OnyxEntry<Account>;
+// Use connectWithoutView to subscribe to account data without affecting UI
+Onyx.connectWithoutView({
+    key: ONYXKEYS.ACCOUNT,
+    callback: (value) => {
+        account = value;
+    },
+});
+
 function buildOldDotURL(url: string, shortLivedAuthToken?: string): Promise<string> {
     const hashIndex = url.lastIndexOf('#');
     const hasHashParams = hashIndex !== -1;
@@ -230,7 +242,16 @@ function openLink(href: string, environmentURL: string, isAttachment = false) {
     openExternalLink(href);
 }
 
-function openReportFromDeepLink(url: string, reports: OnyxCollection<Report>, isAuthenticated: boolean, conciergeReportID: string | undefined, introSelected: OnyxEntry<IntroSelected>) {
+function openReportFromDeepLink(
+    url: string,
+    currentOnboardingPurposeSelected: OnyxEntry<OnboardingPurpose>,
+    currentOnboardingCompanySize: OnyxEntry<OnboardingCompanySize>,
+    onboardingInitialPath: OnyxEntry<string>,
+    reports: OnyxCollection<Report>,
+    isAuthenticated: boolean,
+    introSelected: OnyxEntry<IntroSelected>,
+    conciergeReportID: string | undefined,
+) {
     const reportID = getReportIDFromLink(url);
 
     if (reportID && !isAuthenticated) {
@@ -366,7 +387,25 @@ function openReportFromDeepLink(url: string, reports: OnyxCollection<Report>, is
 
                         if (isAnonymousUser()) {
                             handleDeeplinkNavigation();
+                            return;
                         }
+                        // We need skip deeplinking if the user hasn't completed the guided setup flow.
+                        isOnboardingFlowCompleted({
+                            onNotCompleted: () => {
+                                Log.info('[Onboarding] User has not completed the guided setup flow, starting onboarding flow from deep link');
+                                startOnboardingFlow({
+                                    onboardingValuesParam: val,
+                                    hasAccessiblePolicies: !!account?.hasAccessibleDomainPolicies,
+                                    isUserFromPublicDomain: !!account?.isFromPublicDomain,
+                                    currentOnboardingPurposeSelected,
+                                    currentOnboardingCompanySize,
+                                    onboardingInitialPath,
+                                    onboardingValues: val,
+                                });
+                            },
+                            onCompleted: handleDeeplinkNavigation,
+                            onCanceled: handleDeeplinkNavigation,
+                        });
                     });
                 },
             });
diff --git a/src/libs/actions/Welcome/index.ts b/src/libs/actions/Welcome/index.ts
index a10f96e62a8e..9c69f9ed7a68 100644
--- a/src/libs/actions/Welcome/index.ts
+++ b/src/libs/actions/Welcome/index.ts
@@ -11,21 +11,84 @@ import type {OnboardingAccounting} from '@src/CONST';
 import type {TranslationPaths} from '@src/languages/types';
 import ONYXKEYS from '@src/ONYXKEYS';
 import ROUTES from '@src/ROUTES';
-import type {OnboardingPurpose} from '@src/types/onyx';
+import type {Account, OnboardingPurpose} from '@src/types/onyx';
 import type Onboarding from '@src/types/onyx/Onboarding';
+import {isEmptyObject} from '@src/types/utils/EmptyObject';
 import type {OnboardingCompanySize} from './OnboardingFlow';
+import {startOnboardingFlow} from './OnboardingFlow';
 
 let isLoadingReportData = true;
+let onboarding: Onboarding | undefined;
+let account: Account | undefined;
+
+type HasCompletedOnboardingFlowProps = {
+    onCompleted?: () => void;
+    onNotCompleted?: () => void;
+    onCanceled?: () => void;
+};
 
 let resolveIsReadyPromise: (value?: Promise<void>) => void | undefined;
 let isServerDataReadyPromise = new Promise<void>((resolve) => {
     resolveIsReadyPromise = resolve;
 });
 
+let resolveOnboardingFlowStatus: () => void;
+let isOnboardingFlowStatusKnownPromise = new Promise<void>((resolve) => {
+    resolveOnboardingFlowStatus = resolve;
+});
+
 function onServerDataReady(): Promise<void> {
     return isServerDataReadyPromise;
 }
 
+let isOnboardingInProgress = false;
+function isOnboardingFlowCompleted({onCompleted, onNotCompleted, onCanceled}: HasCompletedOnboardingFlowProps) {
+    isOnboardingFlowStatusKnownPromise.then(() => {
+        // Don't trigger onboarding if we are showing the require 2FA page
+        const shouldShowRequire2FAPage = account && !!account.needsTwoFactorAuthSetup && (!account.requiresTwoFactorAuth || !!account.twoFactorAuthSetupInProgress);
+        if (shouldShowRequire2FAPage) {
+            return;
+        }
+
+        if (isEmptyObject(onboarding) || onboarding?.hasCompletedGuidedSetupFlow === undefined) {
+            onCanceled?.();
+            return;
+        }
+
+        // The value `undefined` should not be used here because `testDriveModalDismissed` may not always exist in `onboarding`.
+        // So we only compare it to `false` to avoid unintentionally opening the test drive modal.
+        if (onboarding?.testDriveModalDismissed === false) {
+            Navigation.setNavigationActionToMicrotaskQueue(() => {
+                // Check if we're already on the test drive modal route or if navigation is in progress to prevent duplicate navigation
+                const currentRoute = Navigation.getActiveRoute();
+                if (currentRoute?.includes(ROUTES.TEST_DRIVE_MODAL_ROOT.route)) {
+                    return;
+                }
+
+                Log.info('[Onboarding] User has not completed the guided setup flow, starting onboarding flow from test drive modal');
+                startOnboardingFlow({
+                    onboardingInitialPath: ROUTES.TEST_DRIVE_MODAL_ROOT.route,
+                    isUserFromPublicDomain: false,
+                    hasAccessiblePolicies: false,
+                    currentOnboardingCompanySize: undefined,
+                    currentOnboardingPurposeSelected: undefined,
+                    onboardingValues: onboarding,
+                });
+            });
+
+            return;
+        }
+
+        if (onboarding?.hasCompletedGuidedSetupFlow) {
+            isOnboardingInProgress = false;
+            onCompleted?.();
+        } else if (!isOnboardingInProgress) {
+            isOnboardingInProgress = true;
+            onNotCompleted?.();
+        }
+    });
+}
+
 /**
  * Check if report data are loaded
  */
@@ -37,6 +100,17 @@ function checkServerDataReady() {
     resolveIsReadyPromise?.();
 }
 
+/**
+ * Check if the onboarding data is loaded
+ */
+function checkOnboardingDataReady() {
+    if (onboarding === undefined || account === undefined) {
+        return;
+    }
+
+    resolveOnboardingFlowStatus();
+}
+
 function setOnboardingPurposeSelected(value: OnboardingPurpose) {
     Onyx.set(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED, value ?? null);
 }
@@ -112,6 +186,26 @@ function completeHybridAppOnboarding() {
     });
 }
 
+// We use `connectWithoutView` here since this connection only updates a module-level variable
+// and doesn't need to trigger component re-renders.
+Onyx.connectWithoutView({
+    key: ONYXKEYS.ACCOUNT,
+    callback: (value) => {
+        account = value;
+        checkOnboardingDataReady();
+    },
+});
+
+// We use `connectWithoutView` here since this connection only updates a module-level variable
+// and doesn't need to trigger component re-renders.
+Onyx.connectWithoutView({
+    key: ONYXKEYS.NVP_ONBOARDING,
+    callback: (value) => {
+        onboarding = value;
+        checkOnboardingDataReady();
+    },
+});
+
 // We use `connectWithoutView` here since this connection only to get loading flag
 // and doesn't need to trigger component re-renders.
 Onyx.connectWithoutView({
@@ -127,7 +221,11 @@ function resetAllChecks() {
     isServerDataReadyPromise = new Promise((resolve) => {
         resolveIsReadyPromise = resolve;
     });
+    isOnboardingFlowStatusKnownPromise = new Promise<void>((resolve) => {
+        resolveOnboardingFlowStatus = resolve;
+    });
     isLoadingReportData = true;
+    isOnboardingInProgress = false;
 }
 
 function setSelfTourViewed(shouldUpdateOnyxDataOnlyLocally = false) {
@@ -169,6 +267,7 @@ function dismissProductTraining(elementName: string, isDismissedUsingCloseButton
 
 export {
     onServerDataReady,
+    isOnboardingFlowCompleted,
     dismissProductTraining,
     setOnboardingPurposeSelected,
     updateOnboardingLastVisitedPath,
diff --git a/src/libs/navigateAfterOnboarding.ts b/src/libs/navigateAfterOnboarding.ts
index cfb8de469374..11ac99e4aedf 100644
--- a/src/libs/navigateAfterOnboarding.ts
+++ b/src/libs/navigateAfterOnboarding.ts
@@ -69,10 +69,20 @@ function navigateAfterOnboarding(
     );
     if (reportID) {
         Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportID));
-    } else {
-        // Navigate to home to trigger guard evaluation
-        Navigation.navigate(ROUTES.HOME);
     }
+
+    // In this case, we have joined an accessible policy. We would have an onboarding policy, but not an admins chat report.
+    // We should skip the Test Drive modal in this case since we already have a policy to join.
+    if (onboardingPolicyID && !onboardingAdminsChatReportID) {
+        return;
+    }
+
+    // We're using Navigation.isNavigationReady here because without it, on iOS,
+    // Navigation.dismissModal runs after Navigation.navigate(ROUTES.TEST_DRIVE_MODAL_ROOT.route)
+    // And dismisses the modal before it even shows
+    Navigation.isNavigationReady().then(() => {
+        Navigation.navigate(ROUTES.TEST_DRIVE_MODAL_ROOT.route);
+    });
 }
 
 function navigateAfterOnboardingWithMicrotaskQueue(
diff --git a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx
index cb27b82684cd..18fcb3f9f670 100644
--- a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx
+++ b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx
@@ -1,6 +1,6 @@
 import {useIsFocused} from '@react-navigation/native';
 import React, {useCallback, useImperativeHandle, useMemo, useRef} from 'react';
-import {View} from 'react-native';
+import {InteractionManager, View} from 'react-native';
 import {ScrollView} from 'react-native-gesture-handler';
 import FormHelpMessage from '@components/FormHelpMessage';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
@@ -107,6 +107,11 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, ro
                         companySize: onboardingCompanySize,
                     });
 
+                    // eslint-disable-next-line @typescript-eslint/no-deprecated
+                    InteractionManager.runAfterInteractions(() => {
+                        Navigation.navigate(ROUTES.TEST_DRIVE_MODAL_ROOT.route);
+                    });
+
                     return;
                 }
 
diff --git a/tests/unit/Navigation/guards/NavigationGuards.test.ts b/tests/unit/Navigation/guards/NavigationGuards.test.ts
deleted file mode 100644
index 6cd41fdb8216..000000000000
--- a/tests/unit/Navigation/guards/NavigationGuards.test.ts
+++ /dev/null
@@ -1,210 +0,0 @@
-import type {NavigationState} from '@react-navigation/native';
-import {clearGuards, createGuardContext, evaluateGuards, getRegisteredGuards, registerGuard} from '@libs/Navigation/guards';
-import type {GuardContext, NavigationGuard} from '@libs/Navigation/guards/types';
-import ROUTES from '@src/ROUTES';
-
-describe('Navigation Guard System', () => {
-    beforeEach(() => {
-        // Clear all guards before each test
-        clearGuards();
-    });
-
-    describe('registerGuard', () => {
-        it('should register a guard', () => {
-            const mockGuard: NavigationGuard = {
-                name: 'TestGuard',
-                evaluate: () => ({type: 'ALLOW'}),
-            };
-
-            registerGuard(mockGuard);
-
-            expect(getRegisteredGuards()).toHaveLength(1);
-            expect(getRegisteredGuards().at(0)).toBe(mockGuard);
-        });
-
-        it('should register multiple guards in order', () => {
-            const guard1: NavigationGuard = {
-                name: 'Guard1',
-                evaluate: () => ({type: 'ALLOW'}),
-            };
-            const guard2: NavigationGuard = {
-                name: 'Guard2',
-                evaluate: () => ({type: 'ALLOW'}),
-            };
-
-            registerGuard(guard1);
-            registerGuard(guard2);
-
-            const guards = getRegisteredGuards();
-            expect(guards).toHaveLength(2);
-            expect(guards.at(0)?.name).toBe('Guard1');
-            expect(guards.at(1)?.name).toBe('Guard2');
-        });
-    });
-
-    describe('clearGuards', () => {
-        it('should remove all registered guards', () => {
-            const mockGuard: NavigationGuard = {
-                name: 'TestGuard',
-                evaluate: () => ({type: 'ALLOW'}),
-            };
-
-            registerGuard(mockGuard);
-            expect(getRegisteredGuards()).toHaveLength(1);
-
-            clearGuards();
-            expect(getRegisteredGuards()).toHaveLength(0);
-        });
-    });
-
-    describe('createGuardContext', () => {
-        it('should create a guard context with expected properties', () => {
-            const context = createGuardContext();
-
-            expect(context).toHaveProperty('isAuthenticated');
-            expect(context).toHaveProperty('isLoading');
-            expect(context).toHaveProperty('currentUrl');
-            expect(typeof context.isAuthenticated).toBe('boolean');
-            expect(typeof context.isLoading).toBe('boolean');
-            expect(typeof context.currentUrl).toBe('string');
-        });
-    });
-
-    describe('evaluateGuards', () => {
-        const mockState = {
-            key: 'test-key',
-            index: 0,
-            routeNames: [],
-            routes: [],
-            type: 'test',
-            stale: false,
-        } as NavigationState;
-        const mockAction = {type: 'NAVIGATE', payload: {name: 'TestScreen'}} as const;
-        const mockContext: GuardContext = {
-            isAuthenticated: true,
-            isLoading: false,
-            currentUrl: '',
-        };
-
-        it('should return ALLOW when no guards are registered', () => {
-            const result = evaluateGuards(mockState, mockAction, mockContext);
-            expect(result).toEqual({type: 'ALLOW'});
-        });
-
-        it('should evaluate guards', () => {
-            const evaluateFn = jest.fn(() => ({type: 'ALLOW' as const}));
-            const mockGuard: NavigationGuard = {
-                name: 'TestGuard',
-                evaluate: evaluateFn,
-            };
-
-            registerGuard(mockGuard);
-            evaluateGuards(mockState, mockAction, mockContext);
-
-            expect(evaluateFn).toHaveBeenCalledWith(mockState, mockAction, mockContext);
-        });
-
-        it('should short-circuit on BLOCK result', () => {
-            const guard1Evaluate = jest.fn(() => ({type: 'BLOCK' as const, reason: 'Blocked'}));
-            const guard2Evaluate = jest.fn(() => ({type: 'ALLOW' as const}));
-
-            const guard1: NavigationGuard = {
-                name: 'BlockingGuard',
-                evaluate: guard1Evaluate,
-            };
-            const guard2: NavigationGuard = {
-                name: 'AllowGuard',
-                evaluate: guard2Evaluate,
-            };
-
-            registerGuard(guard1);
-            registerGuard(guard2);
-
-            const result = evaluateGuards(mockState, mockAction, mockContext);
-
-            expect(result).toEqual({type: 'BLOCK', reason: 'Blocked'});
-            expect(guard1Evaluate).toHaveBeenCalled();
-            expect(guard2Evaluate).not.toHaveBeenCalled();
-        });
-
-        it('should short-circuit on REDIRECT result', () => {
-            const guard1Evaluate = jest.fn(() => ({type: 'REDIRECT' as const, route: ROUTES.HOME}));
-            const guard2Evaluate = jest.fn(() => ({type: 'ALLOW' as const}));
-
-            const guard1: NavigationGuard = {
-                name: 'RedirectGuard',
-                evaluate: guard1Evaluate,
-            };
-            const guard2: NavigationGuard = {
-                name: 'AllowGuard',
-                evaluate: guard2Evaluate,
-            };
-
-            registerGuard(guard1);
-            registerGuard(guard2);
-
-            const result = evaluateGuards(mockState, mockAction, mockContext);
-
-            expect(result).toEqual({type: 'REDIRECT', route: ROUTES.HOME});
-            expect(guard1Evaluate).toHaveBeenCalled();
-            expect(guard2Evaluate).not.toHaveBeenCalled();
-        });
-
-        it('should continue evaluation when guard returns ALLOW', () => {
-            const guard1Evaluate = jest.fn(() => ({type: 'ALLOW' as const}));
-            const guard2Evaluate = jest.fn(() => ({type: 'ALLOW' as const}));
-
-            const guard1: NavigationGuard = {
-                name: 'AllowGuard1',
-                evaluate: guard1Evaluate,
-            };
-            const guard2: NavigationGuard = {
-                name: 'AllowGuard2',
-                evaluate: guard2Evaluate,
-            };
-
-            registerGuard(guard1);
-            registerGuard(guard2);
-
-            const result = evaluateGuards(mockState, mockAction, mockContext);
-
-            expect(result).toEqual({type: 'ALLOW'});
-            expect(guard1Evaluate).toHaveBeenCalled();
-            expect(guard2Evaluate).toHaveBeenCalled();
-        });
-
-        it('should evaluate guards in registration order', () => {
-            const executionOrder: string[] = [];
-
-            const guard1: NavigationGuard = {
-                name: 'Guard1',
-                evaluate: () => {
-                    executionOrder.push('Guard1');
-                    return {type: 'ALLOW'};
-                },
-            };
-            const guard2: NavigationGuard = {
-                name: 'Guard2',
-                evaluate: () => {
-                    executionOrder.push('Guard2');
-                    return {type: 'ALLOW'};
-                },
-            };
-            const guard3: NavigationGuard = {
-                name: 'Guard3',
-                evaluate: () => {
-                    executionOrder.push('Guard3');
-                    return {type: 'ALLOW'};
-                },
-            };
-
-            registerGuard(guard1);
-            registerGuard(guard2);
-            registerGuard(guard3);
-
-            evaluateGuards(mockState, mockAction, mockContext);
-
-            expect(executionOrder).toEqual(['Guard1', 'Guard2', 'Guard3']);
-        });
-    });
-});
diff --git a/tests/unit/Navigation/guards/OnboardingGuard.test.ts b/tests/unit/Navigation/guards/OnboardingGuard.test.ts
deleted file mode 100644
index cd632508c2c6..000000000000
--- a/tests/unit/Navigation/guards/OnboardingGuard.test.ts
+++ /dev/null
@@ -1,275 +0,0 @@
-import type {NavigationAction, NavigationState} from '@react-navigation/native';
-import Onyx from 'react-native-onyx';
-import OnboardingGuard from '@libs/Navigation/guards/OnboardingGuard';
-import type {GuardContext} from '@libs/Navigation/guards/types';
-import CONST from '@src/CONST';
-import ONYXKEYS from '@src/ONYXKEYS';
-import SCREENS from '@src/SCREENS';
-import waitForBatchedUpdates from '../../../utils/waitForBatchedUpdates';
-
-describe('OnboardingGuard', () => {
-    const mockState: NavigationState = {
-        key: 'root',
-        index: 0,
-        routeNames: [SCREENS.HOME],
-        routes: [{key: 'home', name: SCREENS.HOME}],
-        stale: false,
-        type: 'root',
-    };
-
-    const mockAction: NavigationAction = {
-        type: 'NAVIGATE',
-        payload: {name: SCREENS.HOME},
-    };
-
-    const authenticatedContext: GuardContext = {
-        isAuthenticated: true,
-        isLoading: false,
-        currentUrl: '',
-    };
-
-    beforeEach(async () => {
-        await Onyx.clear();
-        await waitForBatchedUpdates();
-    });
-
-    describe('early return when onboarding completed', () => {
-        it('should return ALLOW when user has completed onboarding', async () => {
-            await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-                hasCompletedGuidedSetupFlow: true,
-            });
-            await waitForBatchedUpdates();
-
-            const result = OnboardingGuard.evaluate(mockState, mockAction, authenticatedContext);
-            expect(result.type).toBe('ALLOW');
-        });
-
-        it('should return ALLOW when onboarding data is undefined (old/migrated accounts)', async () => {
-            // Empty/null onboarding means old account - considered completed
-            await Onyx.set(ONYXKEYS.NVP_ONBOARDING, null);
-            await waitForBatchedUpdates();
-
-            const result = OnboardingGuard.evaluate(mockState, mockAction, authenticatedContext);
-            expect(result.type).toBe('ALLOW');
-        });
-    });
-
-    describe('early exit conditions', () => {
-        it('should allow during app transition', () => {
-            const transitionContext: GuardContext = {
-                isAuthenticated: true,
-                isLoading: false,
-                currentUrl: 'https://new.expensify.com/transition',
-            };
-
-            const result = OnboardingGuard.evaluate(mockState, mockAction, transitionContext);
-
-            expect(result.type).toBe('ALLOW');
-        });
-
-        it('should BLOCK RESET action when user is on onboarding and tries to reset to non-onboarding screen', async () => {
-            // User is currently on an onboarding screen
-            const onboardingState: NavigationState = {
-                key: 'root',
-                index: 0,
-                routeNames: [SCREENS.ONBOARDING.PURPOSE],
-                routes: [{key: 'purpose', name: SCREENS.ONBOARDING.PURPOSE}],
-                stale: false,
-                type: 'root',
-            };
-
-            // RESET action trying to navigate to a non-onboarding screen (HOME)
-            const resetAction: NavigationAction = {
-                type: CONST.NAVIGATION_ACTIONS.RESET,
-                payload: {
-                    key: 'root',
-                    index: 0,
-                    routeNames: [SCREENS.HOME],
-                    routes: [{key: 'home', name: SCREENS.HOME}],
-                    stale: false,
-                    type: 'root',
-                },
-            };
-
-            const result = OnboardingGuard.evaluate(onboardingState, resetAction, authenticatedContext) as {type: 'BLOCK'; reason?: string};
-
-            expect(result.type).toBe('BLOCK');
-            expect(result.reason).toBe('Cannot reset to non-onboarding screen while on onboarding');
-        });
-    });
-
-    describe('skip onboarding conditions', () => {
-        it('should allow when onboarding is completed', async () => {
-            await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-                hasCompletedGuidedSetupFlow: true,
-            });
-            await waitForBatchedUpdates();
-
-            const result = OnboardingGuard.evaluate(mockState, mockAction, authenticatedContext);
-
-            expect(result.type).toBe('ALLOW');
-        });
-
-        it('should allow migrated users', async () => {
-            await Onyx.merge(ONYXKEYS.NVP_TRY_NEW_DOT, {
-                classicRedirect: {
-                    dismissed: false,
-                },
-                nudgeMigration: {
-                    timestamp: new Date(),
-                    cohort: 'test',
-                },
-            });
-            await waitForBatchedUpdates();
-
-            const result = OnboardingGuard.evaluate(mockState, mockAction, authenticatedContext);
-
-            expect(result.type).toBe('ALLOW');
-        });
-
-        it('should allow users with single entry from HybridApp', async () => {
-            await Onyx.merge(ONYXKEYS.HYBRID_APP, {
-                isSingleNewDotEntry: true,
-            });
-            await waitForBatchedUpdates();
-
-            const result = OnboardingGuard.evaluate(mockState, mockAction, authenticatedContext);
-
-            expect(result.type).toBe('ALLOW');
-        });
-
-        it('should allow users with non-personal policies', async () => {
-            await Onyx.merge(ONYXKEYS.HAS_NON_PERSONAL_POLICY, true);
-            await waitForBatchedUpdates();
-
-            const result = OnboardingGuard.evaluate(mockState, mockAction, authenticatedContext);
-
-            expect(result.type).toBe('ALLOW');
-        });
-
-        it('should allow invited users', async () => {
-            await Onyx.merge(ONYXKEYS.NVP_INTRO_SELECTED, {
-                choice: CONST.INTRO_CHOICES.SUBMIT,
-            });
-            await waitForBatchedUpdates();
-
-            const result = OnboardingGuard.evaluate(mockState, mockAction, authenticatedContext);
-
-            expect(result.type).toBe('ALLOW');
-        });
-    });
-
-    describe('redirect to onboarding', () => {
-        it('should redirect when authenticated user needs onboarding', async () => {
-            await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-                hasCompletedGuidedSetupFlow: false,
-            });
-            await Onyx.merge(ONYXKEYS.ACCOUNT, {
-                isFromPublicDomain: true,
-            });
-            await waitForBatchedUpdates();
-
-            const result = OnboardingGuard.evaluate(mockState, mockAction, authenticatedContext) as {type: 'REDIRECT'; route: string};
-
-            expect(result.type).toBe('REDIRECT');
-            expect(result.route).toContain('onboarding');
-        });
-
-        it('should redirect to correct step for users with accessible policies', async () => {
-            await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-                hasCompletedGuidedSetupFlow: false,
-            });
-            await Onyx.merge(ONYXKEYS.ACCOUNT, {
-                isFromPublicDomain: false,
-                hasAccessibleDomainPolicies: true,
-            });
-            await waitForBatchedUpdates();
-
-            const result = OnboardingGuard.evaluate(mockState, mockAction, authenticatedContext) as {type: 'REDIRECT'; route: string};
-
-            expect(result.type).toBe('REDIRECT');
-            expect(result.route).toContain('onboarding');
-        });
-
-        it('should redirect when user tries to access wrong onboarding step', async () => {
-            // User is on onboarding/purpose but should be on onboarding/work-email
-            const onboardingState: NavigationState = {
-                key: 'root',
-                index: 0,
-                routeNames: [SCREENS.ONBOARDING.PURPOSE],
-                routes: [{key: 'purpose', name: SCREENS.ONBOARDING.PURPOSE}],
-                stale: false,
-                type: 'root',
-            };
-
-            await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-                hasCompletedGuidedSetupFlow: false,
-            });
-            await Onyx.merge(ONYXKEYS.ACCOUNT, {
-                isFromPublicDomain: true,
-            });
-            await waitForBatchedUpdates();
-
-            const result = OnboardingGuard.evaluate(onboardingState, mockAction, authenticatedContext) as {type: 'REDIRECT'; route: string};
-
-            expect(result.type).toBe('REDIRECT');
-            expect(result.route).toContain('onboarding');
-        });
-
-        it('should redirect when user in onboarding tries to access non-onboarding path', async () => {
-            // User is on onboarding screen but tries to navigate to home
-            const onboardingState: NavigationState = {
-                key: 'root',
-                index: 0,
-                routeNames: [SCREENS.ONBOARDING.PURPOSE],
-                routes: [{key: 'purpose', name: SCREENS.ONBOARDING.PURPOSE}],
-                stale: false,
-                type: 'root',
-            };
-
-            const homeAction: NavigationAction = {
-                type: 'NAVIGATE',
-                payload: {name: SCREENS.HOME},
-            };
-
-            await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-                hasCompletedGuidedSetupFlow: false,
-            });
-            await Onyx.merge(ONYXKEYS.ACCOUNT, {
-                isFromPublicDomain: true,
-            });
-            await waitForBatchedUpdates();
-
-            const result = OnboardingGuard.evaluate(onboardingState, homeAction, authenticatedContext) as {type: 'REDIRECT'; route: string};
-
-            expect(result.type).toBe('REDIRECT');
-            expect(result.route).toContain('onboarding');
-        });
-
-        it('should always redirect to correct onboarding step when user needs onboarding', async () => {
-            // Even if user is on an onboarding screen, guard redirects to the correct step
-            const onboardingState: NavigationState = {
-                key: 'root',
-                index: 0,
-                routeNames: [SCREENS.ONBOARDING.WORK_EMAIL],
-                routes: [{key: 'work-email', name: SCREENS.ONBOARDING.WORK_EMAIL}],
-                stale: false,
-                type: 'root',
-            };
-
-            await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-                hasCompletedGuidedSetupFlow: false,
-            });
-            await Onyx.merge(ONYXKEYS.ACCOUNT, {
-                isFromPublicDomain: true,
-            });
-            await waitForBatchedUpdates();
-
-            const result = OnboardingGuard.evaluate(onboardingState, mockAction, authenticatedContext) as {type: 'REDIRECT'; route: string};
-
-            // Guard should redirect to ensure user is on correct step
-            expect(result.type).toBe('REDIRECT');
-            expect(result.route).toContain('onboarding');
-        });
-    });
-});
diff --git a/tests/unit/Navigation/guards/TestDriveModalGuard.test.ts b/tests/unit/Navigation/guards/TestDriveModalGuard.test.ts
deleted file mode 100644
index 26dc5f713529..000000000000
--- a/tests/unit/Navigation/guards/TestDriveModalGuard.test.ts
+++ /dev/null
@@ -1,216 +0,0 @@
-import type {NavigationAction, NavigationState} from '@react-navigation/native';
-import Onyx from 'react-native-onyx';
-import TestDriveModalGuard, {resetSessionFlag} from '@libs/Navigation/guards/TestDriveModalGuard';
-import type {GuardContext} from '@libs/Navigation/guards/types';
-import CONST from '@src/CONST';
-import NAVIGATORS from '@src/NAVIGATORS';
-import ONYXKEYS from '@src/ONYXKEYS';
-import ROUTES from '@src/ROUTES';
-import SCREENS from '@src/SCREENS';
-import waitForBatchedUpdates from '../../../utils/waitForBatchedUpdates';
-
-describe('TestDriveModalGuard', () => {
-    const mockState: NavigationState = {
-        key: 'root',
-        index: 0,
-        routeNames: [SCREENS.HOME],
-        routes: [{key: 'home', name: SCREENS.HOME}],
-        stale: false,
-        type: 'root',
-    };
-
-    const mockAction: NavigationAction = {
-        type: 'NAVIGATE',
-        payload: {name: SCREENS.HOME},
-    };
-
-    const defaultContext: GuardContext = {
-        isAuthenticated: true,
-        isLoading: false,
-        currentUrl: '',
-    };
-
-    beforeEach(async () => {
-        await Onyx.clear();
-        resetSessionFlag();
-        await waitForBatchedUpdates();
-    });
-
-    it('should allow when app is loading', () => {
-        const result = TestDriveModalGuard.evaluate(mockState, mockAction, {...defaultContext, isLoading: true});
-        expect(result.type).toBe('ALLOW');
-    });
-
-    it('should redirect when onboarding complete and modal not dismissed', async () => {
-        await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-            hasCompletedGuidedSetupFlow: true,
-            testDriveModalDismissed: false,
-        });
-        await waitForBatchedUpdates();
-
-        const result = TestDriveModalGuard.evaluate(mockState, mockAction, defaultContext);
-        expect(result.type).toBe('REDIRECT');
-        if (result.type === 'REDIRECT') {
-            expect(result.route).toBe(ROUTES.TEST_DRIVE_MODAL_ROOT.route);
-        }
-    });
-
-    it('should allow when modal dismissed', async () => {
-        await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-            hasCompletedGuidedSetupFlow: true,
-            testDriveModalDismissed: true,
-        });
-        await waitForBatchedUpdates();
-
-        const result = TestDriveModalGuard.evaluate(mockState, mockAction, defaultContext);
-        expect(result.type).toBe('ALLOW');
-    });
-
-    it('should allow when onboarding not complete', async () => {
-        await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-            hasCompletedGuidedSetupFlow: false,
-            testDriveModalDismissed: false,
-        });
-        await waitForBatchedUpdates();
-
-        const result = TestDriveModalGuard.evaluate(mockState, mockAction, defaultContext);
-        expect(result.type).toBe('ALLOW');
-    });
-
-    it('should not redirect multiple times (session flag)', async () => {
-        await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-            hasCompletedGuidedSetupFlow: true,
-            testDriveModalDismissed: false,
-        });
-        await waitForBatchedUpdates();
-
-        const firstResult = TestDriveModalGuard.evaluate(mockState, mockAction, defaultContext);
-        expect(firstResult.type).toBe('REDIRECT');
-
-        const secondResult = TestDriveModalGuard.evaluate(mockState, mockAction, defaultContext);
-        expect(secondResult.type).toBe('ALLOW');
-    });
-
-    it('should skip modal when user has accessible workspace', async () => {
-        await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-            hasCompletedGuidedSetupFlow: true,
-            testDriveModalDismissed: false,
-        });
-        await Onyx.set(ONYXKEYS.ONBOARDING_POLICY_ID, 'policy123');
-        await Onyx.set(ONYXKEYS.HAS_NON_PERSONAL_POLICY, true);
-        await waitForBatchedUpdates();
-
-        const result = TestDriveModalGuard.evaluate(mockState, mockAction, defaultContext);
-        expect(result.type).toBe('ALLOW');
-    });
-
-    it('should redirect to home when accessing dismissed modal via URL', async () => {
-        await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-            hasCompletedGuidedSetupFlow: true,
-            testDriveModalDismissed: true,
-        });
-        await waitForBatchedUpdates();
-
-        const testDriveModalState: NavigationState = {
-            key: 'root',
-            index: 0,
-            routeNames: [SCREENS.TEST_DRIVE_MODAL.ROOT],
-            routes: [{key: 'testDrive', name: SCREENS.TEST_DRIVE_MODAL.ROOT}],
-            stale: false,
-            type: 'root',
-        };
-
-        const result = TestDriveModalGuard.evaluate(testDriveModalState, mockAction, defaultContext);
-        expect(result.type).toBe('REDIRECT');
-        if (result.type === 'REDIRECT') {
-            expect(result.route).toBe(ROUTES.HOME);
-        }
-    });
-
-    describe('shouldBlockWhileModalActive', () => {
-        const stateWithModalOnTop: NavigationState = {
-            key: 'root',
-            index: 1,
-            routeNames: [SCREENS.HOME, NAVIGATORS.TEST_DRIVE_MODAL_NAVIGATOR],
-            routes: [
-                {key: 'home', name: SCREENS.HOME},
-                {key: 'testDriveModal', name: NAVIGATORS.TEST_DRIVE_MODAL_NAVIGATOR},
-            ],
-            stale: false,
-            type: 'stack',
-        };
-
-        const tabSwitchAction: NavigationAction = {
-            type: CONST.NAVIGATION.ACTION_TYPE.PUSH,
-            payload: {name: NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR},
-        };
-
-        const dismissModalAction: NavigationAction = {
-            type: CONST.NAVIGATION.ACTION_TYPE.DISMISS_MODAL,
-        };
-
-        const goBackAction: NavigationAction = {
-            type: CONST.NAVIGATION.ACTION_TYPE.GO_BACK,
-        };
-
-        it('should block tab switches when the test drive modal is on top', async () => {
-            await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-                hasCompletedGuidedSetupFlow: true,
-                testDriveModalDismissed: false,
-            });
-            await waitForBatchedUpdates();
-
-            // Trigger the redirect first so hasRedirectedToTestDriveModal is true
-            TestDriveModalGuard.evaluate(mockState, mockAction, defaultContext);
-
-            const result = TestDriveModalGuard.evaluate(stateWithModalOnTop, tabSwitchAction, defaultContext);
-            expect(result.type).toBe('BLOCK');
-        });
-
-        it('should allow DISMISS_MODAL when the test drive modal is on top', async () => {
-            await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-                hasCompletedGuidedSetupFlow: true,
-                testDriveModalDismissed: false,
-            });
-            await waitForBatchedUpdates();
-
-            // Trigger the redirect first
-            TestDriveModalGuard.evaluate(mockState, mockAction, defaultContext);
-
-            const result = TestDriveModalGuard.evaluate(stateWithModalOnTop, dismissModalAction, defaultContext);
-            expect(result.type).not.toBe('BLOCK');
-        });
-
-        it('should allow GO_BACK when the test drive modal is on top', async () => {
-            await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-                hasCompletedGuidedSetupFlow: true,
-                testDriveModalDismissed: false,
-            });
-            await waitForBatchedUpdates();
-
-            // Trigger the redirect first
-            TestDriveModalGuard.evaluate(mockState, mockAction, defaultContext);
-
-            const result = TestDriveModalGuard.evaluate(stateWithModalOnTop, goBackAction, defaultContext);
-            expect(result.type).not.toBe('BLOCK');
-        });
-
-        it('should not block when the modal has been dismissed', async () => {
-            await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {
-                hasCompletedGuidedSetupFlow: true,
-                testDriveModalDismissed: false,
-            });
-            await waitForBatchedUpdates();
-
-            // Trigger the redirect first
-            TestDriveModalGuard.evaluate(mockState, mockAction, defaultContext);
-
-            // Now mark modal as dismissed
-            await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {testDriveModalDismissed: true});
-            await waitForBatchedUpdates();
-
-            const result = TestDriveModalGuard.evaluate(stateWithModalOnTop, tabSwitchAction, defaultContext);
-            expect(result.type).not.toBe('BLOCK');
-        });
-    });
-});
diff --git a/tests/unit/navigateAfterOnboardingTest.ts b/tests/unit/navigateAfterOnboardingTest.ts
index 600cedbd5896..1fc7414a5ef4 100644
--- a/tests/unit/navigateAfterOnboardingTest.ts
+++ b/tests/unit/navigateAfterOnboardingTest.ts
@@ -1,3 +1,4 @@
+import {waitFor} from '@testing-library/react-native';
 import type {OnyxEntry} from 'react-native-onyx';
 import Onyx from 'react-native-onyx';
 import {navigateAfterOnboarding} from '@libs/navigateAfterOnboarding';
@@ -143,4 +144,12 @@ describe('navigateAfterOnboarding', () => {
         navigateAfterOnboarding(true, true, '', new Set(), ONBOARDING_POLICY_ID, ONBOARDING_ADMINS_CHAT_REPORT_ID, (testSession?.email ?? '').includes('+'));
         expect(navigate).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(REPORT_ID));
     });
+
+    it('should navigate to Test Drive Modal if user wants to manage a small team', async () => {
+        const navigate = jest.spyOn(Navigation, 'navigate');
+        jest.spyOn(Navigation, 'isNavigationReady').mockReturnValue(Promise.resolve());
+
+        navigateAfterOnboarding(true, true, '', new Set());
+        await waitFor(() => expect(navigate).toHaveBeenCalledWith(ROUTES.TEST_DRIVE_MODAL_ROOT.route));
+    });
 });
