diff --git a/Cargo.lock b/Cargo.lock
index 31339b27..c64d3cc6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2976,7 +2976,7 @@ dependencies = [
 [[package]]
 name = "ruma"
 version = "0.10.1"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "assign",
  "js_int",
@@ -2998,7 +2998,7 @@ dependencies = [
 [[package]]
 name = "ruma-appservice-api"
 version = "0.10.0"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "js_int",
  "ruma-common",
@@ -3010,7 +3010,7 @@ dependencies = [
 [[package]]
 name = "ruma-client-api"
 version = "0.18.0"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "as_variant",
  "assign",
@@ -3033,7 +3033,7 @@ dependencies = [
 [[package]]
 name = "ruma-common"
 version = "0.13.0"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "as_variant",
  "base64 0.22.1",
@@ -3063,7 +3063,7 @@ dependencies = [
 [[package]]
 name = "ruma-events"
 version = "0.28.1"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "as_variant",
  "indexmap 2.6.0",
@@ -3087,7 +3087,7 @@ dependencies = [
 [[package]]
 name = "ruma-federation-api"
 version = "0.9.0"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "bytes",
  "http",
@@ -3105,7 +3105,7 @@ dependencies = [
 [[package]]
 name = "ruma-identifiers-validation"
 version = "0.9.5"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "js_int",
  "thiserror",
@@ -3114,7 +3114,7 @@ dependencies = [
 [[package]]
 name = "ruma-identity-service-api"
 version = "0.9.0"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "js_int",
  "ruma-common",
@@ -3124,7 +3124,7 @@ dependencies = [
 [[package]]
 name = "ruma-macros"
 version = "0.13.0"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "cfg-if",
  "once_cell",
@@ -3140,7 +3140,7 @@ dependencies = [
 [[package]]
 name = "ruma-push-gateway-api"
 version = "0.9.0"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "js_int",
  "ruma-common",
@@ -3152,7 +3152,7 @@ dependencies = [
 [[package]]
 name = "ruma-server-util"
 version = "0.3.0"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "headers",
  "http",
@@ -3165,7 +3165,7 @@ dependencies = [
 [[package]]
 name = "ruma-signatures"
 version = "0.15.0"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "base64 0.22.1",
  "ed25519-dalek",
@@ -3181,7 +3181,7 @@ dependencies = [
 [[package]]
 name = "ruma-state-res"
 version = "0.11.0"
-source = "git+https://github.com/girlbossceo/ruwuma?rev=d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73#d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+source = "git+https://github.com/girlbossceo/ruwuma?rev=39c1addd37a4eed612ac1135edc2cccd9d331d5e#39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 dependencies = [
  "futures-util",
  "itertools 0.13.0",
diff --git a/Cargo.toml b/Cargo.toml
index 64cd8ba3..73f16daf 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -315,7 +315,7 @@ version = "0.1.2"
 [workspace.dependencies.ruma]
 git = "https://github.com/girlbossceo/ruwuma"
 #branch = "conduwuit-changes"
-rev = "d7baeb7e5c3ae28e79ad3fe81c5e8b207a26cc73"
+rev = "39c1addd37a4eed612ac1135edc2cccd9d331d5e"
 features = [
     "compat",
     "rand",
@@ -346,6 +346,7 @@ features = [
     "unstable-msc4121",
     "unstable-msc4125",
     "unstable-msc4186",
+    "unstable-msc4210", # remove legacy mentions
     "unstable-extensible-events",
 ]
 
diff --git a/src/admin/debug/commands.rs b/src/admin/debug/commands.rs
index 7fe8addf..0fd3c91b 100644
--- a/src/admin/debug/commands.rs
+++ b/src/admin/debug/commands.rs
@@ -203,6 +203,7 @@ pub(super) async fn get_remote_pdu(
 			&server,
 			ruma::api::federation::event::get_event::v1::Request {
 				event_id: event_id.clone().into(),
+				include_unredacted_content: None,
 			},
 		)
 		.await
diff --git a/src/api/client/push.rs b/src/api/client/push.rs
index 103c0c5e..de280b32 100644
--- a/src/api/client/push.rs
+++ b/src/api/client/push.rs
@@ -1,18 +1,18 @@
 use axum::extract::State;
-use conduit::err;
+use conduit::{err, Err};
 use ruma::{
 	api::client::{
 		error::ErrorKind,
 		push::{
 			delete_pushrule, get_pushers, get_pushrule, get_pushrule_actions, get_pushrule_enabled, get_pushrules_all,
-			set_pusher, set_pushrule, set_pushrule_actions, set_pushrule_enabled, RuleScope,
+			set_pusher, set_pushrule, set_pushrule_actions, set_pushrule_enabled,
 		},
 	},
 	events::{
 		push_rules::{PushRulesEvent, PushRulesEventContent},
 		GlobalAccountDataEventType,
 	},
-	push::{InsertPushRuleError, RemovePushRuleError, Ruleset},
+	push::{InsertPushRuleError, PredefinedContentRuleId, PredefinedOverrideRuleId, RemovePushRuleError, Ruleset},
 	CanonicalJsonObject, CanonicalJsonValue,
 };
 use service::Services;
@@ -43,7 +43,24 @@ pub(crate) async fn get_pushrules_all_route(
 	let account_data_content = serde_json::from_value::<PushRulesEventContent>(content_value.into())
 		.map_err(|e| err!(Database(warn!("Invalid push rules account data event in database: {e}"))))?;
 
-	let global_ruleset: Ruleset = account_data_content.global;
+	let mut global_ruleset = account_data_content.global;
+
+	// remove old deprecated mentions push rules as per MSC4210
+	#[allow(deprecated)]
+	{
+		use ruma::push::RuleKind::*;
+
+		global_ruleset
+			.remove(Override, PredefinedOverrideRuleId::ContainsDisplayName)
+			.ok();
+		global_ruleset
+			.remove(Override, PredefinedOverrideRuleId::RoomNotif)
+			.ok();
+
+		global_ruleset
+			.remove(Content, PredefinedContentRuleId::ContainsUserName)
+			.ok();
+	};
 
 	Ok(get_pushrules_all::v3::Response {
 		global: global_ruleset,
@@ -58,6 +75,15 @@ pub(crate) async fn get_pushrule_route(
 ) -> Result<get_pushrule::v3::Response> {
 	let sender_user = body.sender_user.as_ref().expect("user is authenticated");
 
+	// remove old deprecated mentions push rules as per MSC4210
+	#[allow(deprecated)]
+	if body.rule_id.as_str() == PredefinedContentRuleId::ContainsUserName.as_str()
+		|| body.rule_id.as_str() == PredefinedOverrideRuleId::ContainsDisplayName.as_str()
+		|| body.rule_id.as_str() == PredefinedOverrideRuleId::RoomNotif.as_str()
+	{
+		return Err!(Request(NotFound("Push rule not found.")));
+	}
+
 	let event: PushRulesEvent = services
 		.account_data
 		.get_global(sender_user, GlobalAccountDataEventType::PushRules)
@@ -79,7 +105,7 @@ pub(crate) async fn get_pushrule_route(
 	}
 }
 
-/// # `PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}`
+/// # `PUT /_matrix/client/r0/pushrules/global/{kind}/{ruleId}`
 ///
 /// Creates a single specified push rule for this user.
 pub(crate) async fn set_pushrule_route(
@@ -88,13 +114,6 @@ pub(crate) async fn set_pushrule_route(
 	let sender_user = body.sender_user.as_ref().expect("user is authenticated");
 	let body = body.body;
 
-	if body.scope != RuleScope::Global {
-		return Err(Error::BadRequest(
-			ErrorKind::InvalidParam,
-			"Scopes other than 'global' are not supported.",
-		));
-	}
-
 	let mut account_data: PushRulesEvent = services
 		.account_data
 		.get_global(sender_user, GlobalAccountDataEventType::PushRules)
@@ -145,7 +164,7 @@ pub(crate) async fn set_pushrule_route(
 	Ok(set_pushrule::v3::Response {})
 }
 
-/// # `GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/actions`
+/// # `GET /_matrix/client/r0/pushrules/global/{kind}/{ruleId}/actions`
 ///
 /// Gets the actions of a single specified push rule for this user.
 pub(crate) async fn get_pushrule_actions_route(
@@ -153,11 +172,13 @@ pub(crate) async fn get_pushrule_actions_route(
 ) -> Result<get_pushrule_actions::v3::Response> {
 	let sender_user = body.sender_user.as_ref().expect("user is authenticated");
 
-	if body.scope != RuleScope::Global {
-		return Err(Error::BadRequest(
-			ErrorKind::InvalidParam,
-			"Scopes other than 'global' are not supported.",
-		));
+	// remove old deprecated mentions push rules as per MSC4210
+	#[allow(deprecated)]
+	if body.rule_id.as_str() == PredefinedContentRuleId::ContainsUserName.as_str()
+		|| body.rule_id.as_str() == PredefinedOverrideRuleId::ContainsDisplayName.as_str()
+		|| body.rule_id.as_str() == PredefinedOverrideRuleId::RoomNotif.as_str()
+	{
+		return Err!(Request(NotFound("Push rule not found.")));
 	}
 
 	let event: PushRulesEvent = services
@@ -178,7 +199,7 @@ pub(crate) async fn get_pushrule_actions_route(
 	})
 }
 
-/// # `PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/actions`
+/// # `PUT /_matrix/client/r0/pushrules/global/{kind}/{ruleId}/actions`
 ///
 /// Sets the actions of a single specified push rule for this user.
 pub(crate) async fn set_pushrule_actions_route(
@@ -186,13 +207,6 @@ pub(crate) async fn set_pushrule_actions_route(
 ) -> Result<set_pushrule_actions::v3::Response> {
 	let sender_user = body.sender_user.as_ref().expect("user is authenticated");
 
-	if body.scope != RuleScope::Global {
-		return Err(Error::BadRequest(
-			ErrorKind::InvalidParam,
-			"Scopes other than 'global' are not supported.",
-		));
-	}
-
 	let mut account_data: PushRulesEvent = services
 		.account_data
 		.get_global(sender_user, GlobalAccountDataEventType::PushRules)
@@ -221,7 +235,7 @@ pub(crate) async fn set_pushrule_actions_route(
 	Ok(set_pushrule_actions::v3::Response {})
 }
 
-/// # `GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/enabled`
+/// # `GET /_matrix/client/r0/pushrules/global/{kind}/{ruleId}/enabled`
 ///
 /// Gets the enabled status of a single specified push rule for this user.
 pub(crate) async fn get_pushrule_enabled_route(
@@ -229,11 +243,15 @@ pub(crate) async fn get_pushrule_enabled_route(
 ) -> Result<get_pushrule_enabled::v3::Response> {
 	let sender_user = body.sender_user.as_ref().expect("user is authenticated");
 
-	if body.scope != RuleScope::Global {
-		return Err(Error::BadRequest(
-			ErrorKind::InvalidParam,
-			"Scopes other than 'global' are not supported.",
-		));
+	// remove old deprecated mentions push rules as per MSC4210
+	#[allow(deprecated)]
+	if body.rule_id.as_str() == PredefinedContentRuleId::ContainsUserName.as_str()
+		|| body.rule_id.as_str() == PredefinedOverrideRuleId::ContainsDisplayName.as_str()
+		|| body.rule_id.as_str() == PredefinedOverrideRuleId::RoomNotif.as_str()
+	{
+		return Ok(get_pushrule_enabled::v3::Response {
+			enabled: false,
+		});
 	}
 
 	let event: PushRulesEvent = services
@@ -254,7 +272,7 @@ pub(crate) async fn get_pushrule_enabled_route(
 	})
 }
 
-/// # `PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/enabled`
+/// # `PUT /_matrix/client/r0/pushrules/global/{kind}/{ruleId}/enabled`
 ///
 /// Sets the enabled status of a single specified push rule for this user.
 pub(crate) async fn set_pushrule_enabled_route(
@@ -262,13 +280,6 @@ pub(crate) async fn set_pushrule_enabled_route(
 ) -> Result<set_pushrule_enabled::v3::Response> {
 	let sender_user = body.sender_user.as_ref().expect("user is authenticated");
 
-	if body.scope != RuleScope::Global {
-		return Err(Error::BadRequest(
-			ErrorKind::InvalidParam,
-			"Scopes other than 'global' are not supported.",
-		));
-	}
-
 	let mut account_data: PushRulesEvent = services
 		.account_data
 		.get_global(sender_user, GlobalAccountDataEventType::PushRules)
@@ -297,7 +308,7 @@ pub(crate) async fn set_pushrule_enabled_route(
 	Ok(set_pushrule_enabled::v3::Response {})
 }
 
-/// # `DELETE /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}`
+/// # `DELETE /_matrix/client/r0/pushrules/global/{kind}/{ruleId}`
 ///
 /// Deletes a single specified push rule for this user.
 pub(crate) async fn delete_pushrule_route(
@@ -305,13 +316,6 @@ pub(crate) async fn delete_pushrule_route(
 ) -> Result<delete_pushrule::v3::Response> {
 	let sender_user = body.sender_user.as_ref().expect("user is authenticated");
 
-	if body.scope != RuleScope::Global {
-		return Err(Error::BadRequest(
-			ErrorKind::InvalidParam,
-			"Scopes other than 'global' are not supported.",
-		));
-	}
-
 	let mut account_data: PushRulesEvent = services
 		.account_data
 		.get_global(sender_user, GlobalAccountDataEventType::PushRules)
diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs
index 0b2bbf73..026c5a4c 100644
--- a/src/service/rooms/event_handler/mod.rs
+++ b/src/service/rooms/event_handler/mod.rs
@@ -1159,6 +1159,7 @@ impl Service {
 						origin,
 						get_event::v1::Request {
 							event_id: (*next_id).to_owned(),
+							include_unredacted_content: None,
 						},
 					)
 					.await