From bd869613609619920dcf291628745d13a551c6b2 Mon Sep 17 00:00:00 2001
From: OSBotify <infra+osbotify@expensify.com>
Date: Mon, 1 Jun 2026 06:38:01 +0000
Subject: [PATCH 1/3] Update version to 9.3.89-6

(cherry picked from commit 6ba60d7133e85a0051b512b65a071db411625fb1)

(cherry-picked to staging by mountiny)
---
 android/app/build.gradle                    | 4 ++--
 ios/NewExpensify/Info.plist                 | 2 +-
 ios/NotificationServiceExtension/Info.plist | 2 +-
 ios/ShareViewController/Info.plist          | 2 +-
 package-lock.json                           | 4 ++--
 package.json                                | 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/android/app/build.gradle b/android/app/build.gradle
index ea097cb3c505..089347559a9b 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -111,8 +111,8 @@ android {
         minSdkVersion rootProject.ext.minSdkVersion
         targetSdkVersion rootProject.ext.targetSdkVersion
         multiDexEnabled rootProject.ext.multiDexEnabled
-        versionCode 1009038905
-        versionName "9.3.89-5"
+        versionCode 1009038906
+        versionName "9.3.89-6"
         // Supported language variants must be declared here to avoid from being removed during the compilation.
         // This also helps us to not include unnecessary language variants in the APK.
         resConfigs "en", "es"
diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist
index 920aa2dfd16b..0c091b5f9c8e 100644
--- a/ios/NewExpensify/Info.plist
+++ b/ios/NewExpensify/Info.plist
@@ -44,7 +44,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>9.3.89.5</string>
+	<string>9.3.89.6</string>
 	<key>FullStory</key>
 	<dict>
 		<key>OrgId</key>
diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist
index 031c13d99d7c..d70ad595d74d 100644
--- a/ios/NotificationServiceExtension/Info.plist
+++ b/ios/NotificationServiceExtension/Info.plist
@@ -13,7 +13,7 @@
 	<key>CFBundleShortVersionString</key>
 	<string>9.3.89</string>
 	<key>CFBundleVersion</key>
-	<string>9.3.89.5</string>
+	<string>9.3.89.6</string>
 	<key>NSExtension</key>
 	<dict>
 		<key>NSExtensionPointIdentifier</key>
diff --git a/ios/ShareViewController/Info.plist b/ios/ShareViewController/Info.plist
index 4adb4e78b525..d38626ef9164 100644
--- a/ios/ShareViewController/Info.plist
+++ b/ios/ShareViewController/Info.plist
@@ -13,7 +13,7 @@
 	<key>CFBundleShortVersionString</key>
 	<string>9.3.89</string>
 	<key>CFBundleVersion</key>
-	<string>9.3.89.5</string>
+	<string>9.3.89.6</string>
 	<key>NSExtension</key>
 	<dict>
 		<key>NSExtensionAttributes</key>
diff --git a/package-lock.json b/package-lock.json
index fe692e735fcd..51b8c7004fa2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "new.expensify",
-  "version": "9.3.89-5",
+  "version": "9.3.89-6",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "new.expensify",
-      "version": "9.3.89-5",
+      "version": "9.3.89-6",
       "hasInstallScript": true,
       "license": "MIT",
       "dependencies": {
diff --git a/package.json b/package.json
index 50d24a338c20..2e3bc2bfdcf1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "new.expensify",
-  "version": "9.3.89-5",
+  "version": "9.3.89-6",
   "author": "Expensify, Inc.",
   "homepage": "https://new.expensify.com",
   "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",

From c19efbc7dad0dd17270761f17bdb224ff2653137 Mon Sep 17 00:00:00 2001
From: OSBotify <infra+osbotify@expensify.com>
Date: Mon, 1 Jun 2026 06:38:49 +0000
Subject: [PATCH 2/3] Update Mobile-Expensify submodule version to 9.3.89-6

---
 Mobile-Expensify | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Mobile-Expensify b/Mobile-Expensify
index 0ab28c31df63..cb5f79c855fc 160000
--- a/Mobile-Expensify
+++ b/Mobile-Expensify
@@ -1 +1 @@
-Subproject commit 0ab28c31df638030eb7fa144184a03144a4967fa
+Subproject commit cb5f79c855fc89cec9963ed5c099e883d2969889

From 0787c8d515c21998d81d39f2156fb59a9ff71ea0 Mon Sep 17 00:00:00 2001
From: Vit Horacek <36083550+mountiny@users.noreply.github.com>
Date: Mon, 1 Jun 2026 08:33:16 +0200
Subject: [PATCH 3/3] Merge pull request #92140 from
 Expensify/melvin-revert-pr-90365

[CP Staging] Revert "Add enable-notifications banner above Concierge composer" (#90365)

(cherry picked from commit 80b1eb090cbaec8e753d2f82dfc899bbd73fbfb4)

(cherry-picked to staging by mountiny)
---
 src/ONYXKEYS.ts                               |  4 -
 src/components/Banner.tsx                     | 21 ++---
 src/languages/de.ts                           |  1 -
 src/languages/en.ts                           |  4 -
 src/languages/es.ts                           |  4 -
 src/languages/fr.ts                           |  1 -
 src/languages/it.ts                           |  1 -
 src/languages/ja.ts                           |  4 -
 src/languages/nl.ts                           |  1 -
 src/languages/pl.ts                           |  1 -
 src/languages/pt-BR.ts                        |  1 -
 src/languages/zh-hans.ts                      |  4 -
 .../LocalNotification/BrowserNotifications.ts | 27 ++++--
 .../notificationPermission/index.native.ts    |  8 --
 .../notificationPermission/index.ts           | 33 --------
 .../notificationPermission/types.ts           |  9 --
 .../actions/ConciergeNotificationBanner.ts    | 11 ---
 .../report/EnableNotificationsBanner.tsx      | 63 --------------
 src/pages/inbox/report/ReportFooter.tsx       | 14 +---
 .../useShouldShowEnableNotificationsBanner.ts | 36 --------
 src/setup/index.ts                            |  1 -
 .../ConciergeNotificationBannerTest.ts        | 24 ------
 tests/unit/EnableNotificationsBannerTest.tsx  | 82 -------------------
 ...houldShowEnableNotificationsBanner.test.ts | 66 ---------------
 24 files changed, 29 insertions(+), 392 deletions(-)
 delete mode 100644 src/libs/Notification/notificationPermission/index.native.ts
 delete mode 100644 src/libs/Notification/notificationPermission/index.ts
 delete mode 100644 src/libs/Notification/notificationPermission/types.ts
 delete mode 100644 src/libs/actions/ConciergeNotificationBanner.ts
 delete mode 100644 src/pages/inbox/report/EnableNotificationsBanner.tsx
 delete mode 100644 src/pages/inbox/report/useShouldShowEnableNotificationsBanner.ts
 delete mode 100644 tests/actions/ConciergeNotificationBannerTest.ts
 delete mode 100644 tests/unit/EnableNotificationsBannerTest.tsx
 delete mode 100644 tests/unit/hooks/useShouldShowEnableNotificationsBanner.test.ts

diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts
index 2bcf9e3f036d..a63f5503f492 100755
--- a/src/ONYXKEYS.ts
+++ b/src/ONYXKEYS.ts
@@ -568,9 +568,6 @@ const ONYXKEYS = {
     /** Stores the information if mobile selection mode is active */
     RAM_ONLY_MOBILE_SELECTION_MODE: 'mobileSelectionMode',
 
-    /** Session-scoped flag: user dismissed the "enable notifications" banner in the Concierge chat */
-    RAM_ONLY_HAS_DISMISSED_CONCIERGE_NOTIFICATION_BANNER: 'hasDismissedConciergeNotificationBanner',
-
     NVP_PRIVATE_CANCELLATION_DETAILS: 'nvp_private_cancellationDetails',
 
     /** Stores the information about duplicated workspace */
@@ -1566,7 +1563,6 @@ type OnyxValuesMapping = {
     [ONYXKEYS.ADD_NEW_PERSONAL_CARD]: OnyxTypes.AddNewPersonalCard;
     [ONYXKEYS.ASSIGN_CARD]: OnyxTypes.AssignCard;
     [ONYXKEYS.RAM_ONLY_MOBILE_SELECTION_MODE]: boolean;
-    [ONYXKEYS.RAM_ONLY_HAS_DISMISSED_CONCIERGE_NOTIFICATION_BANNER]: boolean;
     [ONYXKEYS.DUPLICATE_WORKSPACE]: OnyxTypes.DuplicateWorkspace;
     [ONYXKEYS.COPY_POLICY_SETTINGS]: OnyxTypes.CopyPolicySettings;
     [ONYXKEYS.NVP_FIRST_DAY_FREE_TRIAL]: string;
diff --git a/src/components/Banner.tsx b/src/components/Banner.tsx
index ad2ca1595e65..f652653f910f 100644
--- a/src/components/Banner.tsx
+++ b/src/components/Banner.tsx
@@ -53,9 +53,6 @@ type BannerProps = {
 
     /** Callback called when pressing the button */
     onButtonPress?: () => void;
-
-    /** Custom action content rendered in the right side of the banner. Overrides the configured `shouldShowButton` when provided. */
-    children?: React.ReactNode;
 };
 
 function Banner({
@@ -67,7 +64,6 @@ function Banner({
     onButtonPress,
     containerStyles,
     textStyles,
-    children,
     shouldRenderHTML = false,
     shouldShowIcon = false,
     shouldShowCloseButton = false,
@@ -122,15 +118,14 @@ function Banner({
                                     </Text>
                                 ))}
                         </View>
-                        {children ??
-                            (shouldShowButton && (
-                                <Button
-                                    success
-                                    style={[styles.ph3]}
-                                    text={translate('common.chatNow')}
-                                    onPress={onButtonPress}
-                                />
-                            ))}
+                        {shouldShowButton && (
+                            <Button
+                                success
+                                style={[styles.ph3]}
+                                text={translate('common.chatNow')}
+                                onPress={onButtonPress}
+                            />
+                        )}
                         {shouldShowCloseButton && !!onClose && (
                             <Tooltip text={translate('common.close')}>
                                 <PressableWithFeedback
diff --git a/src/languages/de.ts b/src/languages/de.ts
index a1428306253a..423f1202ab8f 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -508,7 +508,6 @@ const translations: TranslationDeepObject<typeof en> = {
     concierge: {
         collapseReasoning: 'Begründung einklappen',
         expandReasoning: 'Begründung erweitern',
-        enableNotifications: {prompt: 'Möchten Sie benachrichtigt werden, wenn Concierge antwortet?', cta: 'Benachrichtigen'},
     },
     supportalNoAccess: {
         title: 'Nicht so schnell',
diff --git a/src/languages/en.ts b/src/languages/en.ts
index b37663c2ee86..c5aa7bd356c5 100644
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -528,10 +528,6 @@ const translations = {
     concierge: {
         collapseReasoning: 'Collapse reasoning',
         expandReasoning: 'Expand reasoning',
-        enableNotifications: {
-            prompt: 'Want to be notified when Concierge responds?',
-            cta: 'Notify',
-        },
     },
     supportalNoAccess: {
         title: 'Not so fast',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 49c6c41c3537..5d4e00b0745f 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -460,10 +460,6 @@ const translations: TranslationDeepObject<typeof en> = {
     concierge: {
         collapseReasoning: 'Contraer razonamiento',
         expandReasoning: 'Expandir razonamiento',
-        enableNotifications: {
-            prompt: '¿Quieres que te avisemos cuando Concierge responda?',
-            cta: 'Notificar',
-        },
     },
     supportalNoAccess: {
         title: 'No tan rápido',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 28fa0270c5ca..da44bbabc323 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -508,7 +508,6 @@ const translations: TranslationDeepObject<typeof en> = {
     concierge: {
         collapseReasoning: 'Réduire le raisonnement',
         expandReasoning: 'Développer le raisonnement',
-        enableNotifications: {prompt: 'Vous souhaitez être averti lorsque Concierge répond ?', cta: 'Notifier'},
     },
     supportalNoAccess: {
         title: 'Pas si vite',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 8ab6b4ea1ee0..573625802130 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -508,7 +508,6 @@ const translations: TranslationDeepObject<typeof en> = {
     concierge: {
         collapseReasoning: 'Comprimi ragionamento',
         expandReasoning: 'Espandi ragionamento',
-        enableNotifications: {prompt: 'Vuoi ricevere una notifica quando Concierge risponde?', cta: 'Notifica'},
     },
     supportalNoAccess: {
         title: 'Non così in fretta',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index c2cd656b7a3c..2cf9ecb27880 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -507,10 +507,6 @@ const translations: TranslationDeepObject<typeof en> = {
     concierge: {
         collapseReasoning: '推論を折りたたむ',
         expandReasoning: '推論を展開',
-        enableNotifications: {
-            prompt: 'Conciergeから返信があったときに通知を受け取りますか？',
-            cta: '通知',
-        },
     },
     supportalNoAccess: {
         title: 'ちょっと待ってください',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 6a1181594d1a..94e500817459 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -507,7 +507,6 @@ const translations: TranslationDeepObject<typeof en> = {
     concierge: {
         collapseReasoning: 'Redenering inklappen',
         expandReasoning: 'Redenering uitklappen',
-        enableNotifications: {prompt: 'Wil je een melding krijgen wanneer Concierge reageert?', cta: 'Melden'},
     },
     supportalNoAccess: {
         title: 'Niet zo snel',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index a7140cf7275f..968b1a6e910e 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -507,7 +507,6 @@ const translations: TranslationDeepObject<typeof en> = {
     concierge: {
         collapseReasoning: 'Zwiń rozumowanie',
         expandReasoning: 'Rozwiń rozumowanie',
-        enableNotifications: {prompt: 'Chcesz otrzymywać powiadomienia, gdy Concierge odpowie?', cta: 'Powiadom'},
     },
     supportalNoAccess: {
         title: 'Nie tak szybko',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index d513966555f1..c082a056af57 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -506,7 +506,6 @@ const translations: TranslationDeepObject<typeof en> = {
     concierge: {
         collapseReasoning: 'Recolher raciocínio',
         expandReasoning: 'Expandir raciocínio',
-        enableNotifications: {prompt: 'Quer ser avisado quando o Concierge responder?', cta: 'Notificar'},
     },
     supportalNoAccess: {
         title: 'Calma aí',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 882adf310116..7923d5ed5f68 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -503,10 +503,6 @@ const translations: TranslationDeepObject<typeof en> = {
     concierge: {
         collapseReasoning: '收起推理',
         expandReasoning: '展开推理',
-        enableNotifications: {
-            prompt: '希望在Concierge回复时收到通知吗？',
-            cta: '通知',
-        },
     },
     supportalNoAccess: {
         title: '先别急',
diff --git a/src/libs/Notification/LocalNotification/BrowserNotifications.ts b/src/libs/Notification/LocalNotification/BrowserNotifications.ts
index c07ae3785754..5379bdd6acc5 100644
--- a/src/libs/Notification/LocalNotification/BrowserNotifications.ts
+++ b/src/libs/Notification/LocalNotification/BrowserNotifications.ts
@@ -5,7 +5,6 @@ import EXPENSIFY_ICON_URL from '@assets/images/expensify-logo-round-clearspace.p
 import * as AppUpdate from '@libs/actions/AppUpdate';
 import {translateLocal} from '@libs/Localize';
 import {getForReportAction} from '@libs/ModifiedExpenseMessage';
-import NotificationPermission from '@libs/Notification/notificationPermission';
 import {getTextFromHtml} from '@libs/ReportActionsUtils';
 import {getReportName} from '@libs/ReportNameUtils';
 import * as ReportUtils from '@libs/ReportUtils';
@@ -17,18 +16,28 @@ import type {LocalNotificationClickHandler, LocalNotificationData, LocalNotifica
 const notificationCache: Record<string, Notification> = {};
 
 /**
- * Checks if the user has granted permission to show browser notifications, prompting them
- * if they have not yet decided.
+ * Checks if the user has granted permission to show browser notifications
  */
 function canUseBrowserNotifications(): Promise<boolean> {
-    return NotificationPermission.getStatus().then((status) => {
-        if (status === 'granted') {
-            return true;
+    return new Promise((resolve) => {
+        // They have no browser notifications so we can't use this feature
+        if (!window.Notification) {
+            resolve(false);
+            return;
         }
-        if (status === 'denied') {
-            return false;
+
+        // Check if they previously granted or denied us access to send a notification
+        const permissionGranted = Notification.permission === 'granted';
+
+        if (permissionGranted || Notification.permission === 'denied') {
+            resolve(permissionGranted);
+            return;
         }
-        return NotificationPermission.request().then((requested) => requested === 'granted');
+
+        // Check their global preferences for browser notifications and ask permission if they have none
+        Notification.requestPermission().then((status) => {
+            resolve(status === 'granted');
+        });
     });
 }
 
diff --git a/src/libs/Notification/notificationPermission/index.native.ts b/src/libs/Notification/notificationPermission/index.native.ts
deleted file mode 100644
index 29123ad37089..000000000000
--- a/src/libs/Notification/notificationPermission/index.native.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import type NotificationPermissionModule from './types';
-
-const NotificationPermissionNative: NotificationPermissionModule = {
-    getStatus: () => Promise.resolve('denied'),
-    request: () => Promise.resolve('denied'),
-};
-
-export default NotificationPermissionNative;
diff --git a/src/libs/Notification/notificationPermission/index.ts b/src/libs/Notification/notificationPermission/index.ts
deleted file mode 100644
index d9a5fb7a4367..000000000000
--- a/src/libs/Notification/notificationPermission/index.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import Log from '@libs/Log';
-import type NotificationPermissionModule from './types';
-import type {NotificationPermissionStatus} from './types';
-
-function toStatus(permission: NotificationPermission): NotificationPermissionStatus {
-    if (permission === 'granted' || permission === 'denied') {
-        return permission;
-    }
-    return 'default';
-}
-
-const NotificationPermission: NotificationPermissionModule = {
-    getStatus(): Promise<NotificationPermissionStatus> {
-        if (typeof window === 'undefined' || !window.Notification) {
-            return Promise.resolve('denied');
-        }
-        return Promise.resolve(toStatus(Notification.permission));
-    },
-
-    request(): Promise<NotificationPermissionStatus> {
-        if (typeof window === 'undefined' || !window.Notification) {
-            return Promise.resolve('denied');
-        }
-        return Notification.requestPermission()
-            .then(toStatus)
-            .catch((error: unknown) => {
-                Log.warn('[NotificationPermission] request failed', {error: String(error)});
-                return 'denied';
-            });
-    },
-};
-
-export default NotificationPermission;
diff --git a/src/libs/Notification/notificationPermission/types.ts b/src/libs/Notification/notificationPermission/types.ts
deleted file mode 100644
index 9ffca38417ae..000000000000
--- a/src/libs/Notification/notificationPermission/types.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-type NotificationPermissionStatus = 'granted' | 'denied' | 'default';
-
-type NotificationPermissionModule = {
-    getStatus: () => Promise<NotificationPermissionStatus>;
-    request: () => Promise<NotificationPermissionStatus>;
-};
-
-export default NotificationPermissionModule;
-export type {NotificationPermissionStatus};
diff --git a/src/libs/actions/ConciergeNotificationBanner.ts b/src/libs/actions/ConciergeNotificationBanner.ts
deleted file mode 100644
index cd12ebe86389..000000000000
--- a/src/libs/actions/ConciergeNotificationBanner.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import Onyx from 'react-native-onyx';
-import ONYXKEYS from '@src/ONYXKEYS';
-
-function dismissForSession() {
-    Onyx.set(ONYXKEYS.RAM_ONLY_HAS_DISMISSED_CONCIERGE_NOTIFICATION_BANNER, true);
-}
-
-export {
-    // eslint-disable-next-line import/prefer-default-export -- Action files in src/libs/actions/ use named exports by convention so callers stay consistent as more actions are added
-    dismissForSession,
-};
diff --git a/src/pages/inbox/report/EnableNotificationsBanner.tsx b/src/pages/inbox/report/EnableNotificationsBanner.tsx
deleted file mode 100644
index 6d41a965f0a5..000000000000
--- a/src/pages/inbox/report/EnableNotificationsBanner.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import React from 'react';
-import {View} from 'react-native';
-import Banner from '@components/Banner';
-import Button from '@components/Button';
-import useLocalize from '@hooks/useLocalize';
-import useThemeStyles from '@hooks/useThemeStyles';
-import {dismissForSession} from '@libs/actions/ConciergeNotificationBanner';
-import NotificationPermission from '@libs/Notification/notificationPermission';
-import variables from '@styles/variables';
-import CONST from '@src/CONST';
-
-// Visual breathing room hidden behind the composer in addition to the corner-radius arc.
-const BANNER_EXTRA_OVERLAP_PX = 8;
-// Composer overlaps this banner; the overlap must be ≥ the composer's corner radius.
-const BANNER_COMPOSER_OVERLAP_PX = variables.componentBorderRadiusRounded + BANNER_EXTRA_OVERLAP_PX;
-const BANNER_VISIBLE_BOTTOM_GAP_PX = 12;
-
-const containerOverrideStyle = {
-    paddingBottom: BANNER_VISIBLE_BOTTOM_GAP_PX + BANNER_COMPOSER_OVERLAP_PX,
-    borderRadius: 0,
-    borderTopLeftRadius: variables.componentBorderRadiusLarge,
-    borderTopRightRadius: variables.componentBorderRadiusLarge,
-};
-
-function requestAndDismiss() {
-    NotificationPermission.request().then(dismissForSession);
-}
-
-function EnableNotificationsBanner() {
-    const styles = useThemeStyles();
-    const {translate} = useLocalize();
-
-    return (
-        <View
-            role={CONST.ROLE.STATUS}
-            accessibilityLiveRegion="polite"
-        >
-            <Banner
-                text={translate('concierge.enableNotifications.prompt')}
-                textStyles={[styles.textNormal, styles.mr3, styles.breakWord]}
-                containerStyles={[styles.pt3, styles.pr3, styles.pl4, containerOverrideStyle]}
-            >
-                <Button
-                    success
-                    small
-                    text={translate('concierge.enableNotifications.cta')}
-                    onPress={requestAndDismiss}
-                />
-                <Button
-                    small
-                    style={[styles.ml2]}
-                    text={translate('common.notNow')}
-                    onPress={dismissForSession}
-                />
-            </Banner>
-        </View>
-    );
-}
-
-EnableNotificationsBanner.displayName = 'EnableNotificationsBanner';
-
-export default EnableNotificationsBanner;
-export {BANNER_COMPOSER_OVERLAP_PX};
diff --git a/src/pages/inbox/report/ReportFooter.tsx b/src/pages/inbox/report/ReportFooter.tsx
index ab26c755e5f2..e61c585d3fcd 100644
--- a/src/pages/inbox/report/ReportFooter.tsx
+++ b/src/pages/inbox/report/ReportFooter.tsx
@@ -31,16 +31,12 @@ import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import {isLoadingInitialReportActionsSelector} from '@src/selectors/ReportMetaData';
 import type * as OnyxTypes from '@src/types/onyx';
-import EnableNotificationsBanner, {BANNER_COMPOSER_OVERLAP_PX} from './EnableNotificationsBanner';
 import ReportActionCompose from './ReportActionCompose/ReportActionCompose';
 import SystemChatReportFooterMessage from './SystemChatReportFooterMessage';
 import useShouldShowComposerForActiveEditDraft from './useShouldShowComposerForActiveEditDraft';
-import useShouldShowEnableNotificationsBanner from './useShouldShowEnableNotificationsBanner';
 
 const policyRoleSelector = (policy: OnyxEntry<OnyxTypes.Policy>) => policy?.role;
 
-const composerOverlapStyle = {marginTop: -BANNER_COMPOSER_OVERLAP_PX};
-
 /**
  * Footer component that decides between the composer and
  * archived/anonymous/blocked/system chat/admins-only footer.
@@ -75,7 +71,6 @@ function ReportFooter() {
 
     const isUserPolicyAdmin = policyRole === CONST.POLICY.ROLE.ADMIN;
     const isArchivedRoom = isArchivedNonExpenseReport(report, isReportArchived);
-    const shouldShowEnableNotificationsBanner = useShouldShowEnableNotificationsBanner(reportIDFromRoute);
 
     const shouldShowComposerOptimistically = !isAnonymousUser && isPublicRoom(report) && !!isLoadingInitialReportActions;
     const canPerformWriteAction = canUserPerformWriteAction(report, isReportArchived) ?? shouldShowComposerOptimistically;
@@ -95,12 +90,9 @@ function ReportFooter() {
     if (!shouldHideComposer) {
         return (
             <View style={[chatFooterStyles, isComposerFullSize && styles.chatFooterFullCompose]}>
-                {shouldShowEnableNotificationsBanner && <EnableNotificationsBanner />}
-                <View style={shouldShowEnableNotificationsBanner ? composerOverlapStyle : undefined}>
-                    <SwipeableView onSwipeDown={Keyboard.dismiss}>
-                        <ReportActionCompose reportID={reportIDFromRoute} />
-                    </SwipeableView>
-                </View>
+                <SwipeableView onSwipeDown={Keyboard.dismiss}>
+                    <ReportActionCompose reportID={reportIDFromRoute} />
+                </SwipeableView>
             </View>
         );
     }
diff --git a/src/pages/inbox/report/useShouldShowEnableNotificationsBanner.ts b/src/pages/inbox/report/useShouldShowEnableNotificationsBanner.ts
deleted file mode 100644
index 69ec25126fb8..000000000000
--- a/src/pages/inbox/report/useShouldShowEnableNotificationsBanner.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import {useEffect, useState} from 'react';
-import useOnyx from '@hooks/useOnyx';
-import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
-import NotificationPermission from '@libs/Notification/notificationPermission';
-import type {NotificationPermissionStatus} from '@libs/Notification/notificationPermission/types';
-import {isConciergeChatReport} from '@libs/ReportUtils';
-import ONYXKEYS from '@src/ONYXKEYS';
-
-function useShouldShowEnableNotificationsBanner(reportID: string | undefined): boolean {
-    const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(reportID)}`);
-    const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
-    const [hasDismissed] = useOnyx(ONYXKEYS.RAM_ONLY_HAS_DISMISSED_CONCIERGE_NOTIFICATION_BANNER);
-    const [permissionStatus, setPermissionStatus] = useState<NotificationPermissionStatus | undefined>();
-
-    const isConcierge = !!reportID && isConciergeChatReport(report, conciergeReportID);
-
-    useEffect(() => {
-        if (!isConcierge || hasDismissed) {
-            return;
-        }
-        let isMounted = true;
-        NotificationPermission.getStatus().then((status) => {
-            if (!isMounted) {
-                return;
-            }
-            setPermissionStatus(status);
-        });
-        return () => {
-            isMounted = false;
-        };
-    }, [isConcierge, hasDismissed]);
-
-    return isConcierge && !hasDismissed && permissionStatus === 'default';
-}
-
-export default useShouldShowEnableNotificationsBanner;
diff --git a/src/setup/index.ts b/src/setup/index.ts
index 38ff36a43178..7ee6c5dad5a3 100644
--- a/src/setup/index.ts
+++ b/src/setup/index.ts
@@ -70,7 +70,6 @@ export default function () {
             ONYXKEYS.RAM_ONLY_PLAID_LINK_TOKEN,
             ONYXKEYS.RAM_ONLY_MERGE_HR_LINK_TOKEN,
             ONYXKEYS.COLLECTION.RAM_ONLY_ISSUE_NEW_EXPENSIFY_CARD,
-            ONYXKEYS.RAM_ONLY_HAS_DISMISSED_CONCIERGE_NOTIFICATION_BANNER,
         ],
     });
 
diff --git a/tests/actions/ConciergeNotificationBannerTest.ts b/tests/actions/ConciergeNotificationBannerTest.ts
deleted file mode 100644
index 41902f3e15d7..000000000000
--- a/tests/actions/ConciergeNotificationBannerTest.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import Onyx from 'react-native-onyx';
-import {dismissForSession} from '@libs/actions/ConciergeNotificationBanner';
-import ONYXKEYS from '@src/ONYXKEYS';
-import getOnyxValue from '../utils/getOnyxValue';
-import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
-
-describe('ConciergeNotificationBanner', () => {
-    beforeAll(() => {
-        Onyx.init({keys: ONYXKEYS});
-    });
-
-    beforeEach(async () => {
-        await Onyx.clear();
-    });
-
-    describe('dismissForSession', () => {
-        it('writes true to the RAM-only dismissal flag', async () => {
-            dismissForSession();
-            await waitForBatchedUpdates();
-            const value = await getOnyxValue(ONYXKEYS.RAM_ONLY_HAS_DISMISSED_CONCIERGE_NOTIFICATION_BANNER);
-            expect(value).toBe(true);
-        });
-    });
-});
diff --git a/tests/unit/EnableNotificationsBannerTest.tsx b/tests/unit/EnableNotificationsBannerTest.tsx
deleted file mode 100644
index dfc3000c07f9..000000000000
--- a/tests/unit/EnableNotificationsBannerTest.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import {fireEvent, render, screen} from '@testing-library/react-native';
-import React from 'react';
-import Onyx from 'react-native-onyx';
-import {LocaleContextProvider} from '@components/LocaleContextProvider';
-import OnyxListItemProvider from '@components/OnyxListItemProvider';
-import {dismissForSession} from '@libs/actions/ConciergeNotificationBanner';
-import type {NotificationPermissionStatus} from '@libs/Notification/notificationPermission/types';
-import EnableNotificationsBanner from '@pages/inbox/report/EnableNotificationsBanner';
-import ONYXKEYS from '@src/ONYXKEYS';
-import waitForBatchedUpdatesWithAct from '../utils/waitForBatchedUpdatesWithAct';
-
-let mockRequestResult: NotificationPermissionStatus = 'default';
-const mockRequest = jest.fn(() => Promise.resolve(mockRequestResult));
-
-jest.mock('@libs/Notification/notificationPermission', () => ({
-    __esModule: true,
-    default: {
-        getStatus: () => Promise.resolve('default' as NotificationPermissionStatus),
-        request: () => mockRequest(),
-    },
-}));
-
-jest.mock('@libs/actions/ConciergeNotificationBanner', () => ({
-    dismissForSession: jest.fn(),
-}));
-
-function renderBanner() {
-    return render(
-        <OnyxListItemProvider>
-            <LocaleContextProvider>
-                <EnableNotificationsBanner />
-            </LocaleContextProvider>
-        </OnyxListItemProvider>,
-    );
-}
-
-describe('EnableNotificationsBanner', () => {
-    beforeAll(() => {
-        Onyx.init({keys: ONYXKEYS});
-    });
-
-    beforeEach(async () => {
-        jest.clearAllMocks();
-        mockRequestResult = 'default';
-        await Onyx.clear();
-    });
-
-    it('renders the prompt text and both action buttons', async () => {
-        renderBanner();
-        await waitForBatchedUpdatesWithAct();
-        expect(screen.getByText('Want to be notified when Concierge responds?')).toBeOnTheScreen();
-        expect(screen.getByText('Notify')).toBeOnTheScreen();
-        expect(screen.getByText('Not now')).toBeOnTheScreen();
-    });
-
-    it('calls dismissForSession when "Not now" is pressed', async () => {
-        renderBanner();
-        await waitForBatchedUpdatesWithAct();
-        fireEvent.press(screen.getByText('Not now'));
-        expect(dismissForSession).toHaveBeenCalledTimes(1);
-    });
-
-    it('requests permission when "Notify" is pressed and dismisses on grant', async () => {
-        mockRequestResult = 'granted';
-        renderBanner();
-        await waitForBatchedUpdatesWithAct();
-        fireEvent.press(screen.getByText('Notify'));
-        await waitForBatchedUpdatesWithAct();
-        expect(mockRequest).toHaveBeenCalledTimes(1);
-        expect(dismissForSession).toHaveBeenCalledTimes(1);
-    });
-
-    it('dismisses after request even when permission is denied so the banner does not get stuck', async () => {
-        mockRequestResult = 'denied';
-        renderBanner();
-        await waitForBatchedUpdatesWithAct();
-        fireEvent.press(screen.getByText('Notify'));
-        await waitForBatchedUpdatesWithAct();
-        expect(mockRequest).toHaveBeenCalledTimes(1);
-        expect(dismissForSession).toHaveBeenCalledTimes(1);
-    });
-});
diff --git a/tests/unit/hooks/useShouldShowEnableNotificationsBanner.test.ts b/tests/unit/hooks/useShouldShowEnableNotificationsBanner.test.ts
deleted file mode 100644
index d11b045fcc5c..000000000000
--- a/tests/unit/hooks/useShouldShowEnableNotificationsBanner.test.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import {renderHook, waitFor} from '@testing-library/react-native';
-import Onyx from 'react-native-onyx';
-import type {NotificationPermissionStatus} from '@libs/Notification/notificationPermission/types';
-import useShouldShowEnableNotificationsBanner from '@pages/inbox/report/useShouldShowEnableNotificationsBanner';
-import ONYXKEYS from '@src/ONYXKEYS';
-
-const CONCIERGE_REPORT_ID = '1';
-const OTHER_REPORT_ID = '2';
-
-let mockCurrentPermission: NotificationPermissionStatus = 'default';
-
-jest.mock('@libs/Notification/notificationPermission', () => ({
-    __esModule: true,
-    default: {
-        getStatus: () => Promise.resolve(mockCurrentPermission),
-        request: () => Promise.resolve(mockCurrentPermission),
-    },
-}));
-
-describe('useShouldShowEnableNotificationsBanner', () => {
-    beforeAll(() => {
-        Onyx.init({keys: ONYXKEYS});
-    });
-
-    beforeEach(async () => {
-        mockCurrentPermission = 'default';
-        await Onyx.clear();
-        await Onyx.merge(ONYXKEYS.CONCIERGE_REPORT_ID, CONCIERGE_REPORT_ID);
-        await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${CONCIERGE_REPORT_ID}`, {reportID: CONCIERGE_REPORT_ID});
-        await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${OTHER_REPORT_ID}`, {reportID: OTHER_REPORT_ID});
-    });
-
-    it('returns false when reportID is undefined', async () => {
-        const {result} = renderHook(() => useShouldShowEnableNotificationsBanner(undefined));
-        await waitFor(() => expect(result.current).toBe(false));
-    });
-
-    it('returns false in a non-Concierge report', async () => {
-        const {result} = renderHook(() => useShouldShowEnableNotificationsBanner(OTHER_REPORT_ID));
-        await waitFor(() => expect(result.current).toBe(false));
-    });
-
-    it('returns false when the user has already dismissed the banner this session', async () => {
-        await Onyx.set(ONYXKEYS.RAM_ONLY_HAS_DISMISSED_CONCIERGE_NOTIFICATION_BANNER, true);
-        const {result} = renderHook(() => useShouldShowEnableNotificationsBanner(CONCIERGE_REPORT_ID));
-        await waitFor(() => expect(result.current).toBe(false));
-    });
-
-    it('returns false when notifications are already granted', async () => {
-        mockCurrentPermission = 'granted';
-        const {result} = renderHook(() => useShouldShowEnableNotificationsBanner(CONCIERGE_REPORT_ID));
-        // Give the async probe a tick to resolve, then assert it stays false.
-        await waitFor(() => expect(result.current).toBe(false));
-    });
-
-    it('returns false when notifications are denied', async () => {
-        mockCurrentPermission = 'denied';
-        const {result} = renderHook(() => useShouldShowEnableNotificationsBanner(CONCIERGE_REPORT_ID));
-        await waitFor(() => expect(result.current).toBe(false));
-    });
-
-    it('returns true in the Concierge report when permission is default and not dismissed', async () => {
-        const {result} = renderHook(() => useShouldShowEnableNotificationsBanner(CONCIERGE_REPORT_ID));
-        await waitFor(() => expect(result.current).toBe(true));
-    });
-});
