diff --git a/app/graphql/types/notes/note_type.rb b/app/graphql/types/notes/note_type.rb
index d1e917b73c79b3821ff0ce01c92bffe9609721c1..0f2a01d73901bca74c75031ee3abe06cecb9ced2 100644
--- a/app/graphql/types/notes/note_type.rb
+++ b/app/graphql/types/notes/note_type.rb
@@ -13,8 +13,6 @@ class NoteType < BaseObject
 
       implements Types::ResolvableInterface
 
-      present_using NotePresenter
-
       field :max_access_level_of_author, GraphQL::Types::String,
         null: true,
         description: "Max access level of the note author in the project.",
@@ -30,11 +28,11 @@ class NoteType < BaseObject
 
       field :author, Types::UserType,
         null: true,
-        description: 'User who wrote the note.'
+        description: 'User who wrote this note.'
 
       field :system, GraphQL::Types::Boolean,
         null: false,
-        description: 'Indicates whether the note was created by the system or by a user.'
+        description: 'Indicates whether this note was created by the system or by a user.'
       field :system_note_icon_name,
         GraphQL::Types::String,
         null: true,
@@ -51,7 +49,7 @@ class NoteType < BaseObject
 
       field :confidential, GraphQL::Types::Boolean,
         null: true,
-        description: 'Indicates if the note is confidential.',
+        description: 'Indicates if this note is confidential.',
         method: :confidential?,
         deprecated: {
           reason: :renamed,
@@ -61,7 +59,7 @@ class NoteType < BaseObject
 
       field :internal, GraphQL::Types::Boolean,
         null: true,
-        description: 'Indicates if the note is internal.',
+        description: 'Indicates if this note is internal.',
         method: :confidential?
 
       field :created_at, Types::TimeType,
@@ -69,16 +67,16 @@ class NoteType < BaseObject
         description: 'Timestamp of the note creation.'
       field :discussion, Types::Notes::DiscussionType,
         null: true,
-        description: 'Discussion the note is a part of.'
+        description: 'Discussion this note is a part of.'
       field :position, Types::Notes::DiffPositionType,
         null: true,
-        description: 'Position of the note on a diff.'
+        description: 'Position of this note on a diff.'
       field :updated_at, Types::TimeType,
         null: false,
         description: "Timestamp of the note's last activity."
       field :url, GraphQL::Types::String,
         null: true,
-        description: 'URL to view the note in the Web UI.'
+        description: 'URL to view this Note in the Web UI.'
 
       field :last_edited_at, Types::TimeType,
         null: true,
@@ -97,10 +95,7 @@ class NoteType < BaseObject
         null: true,
         description: 'Metadata for the given note if it is a system note.'
 
-      field :body_html, GraphQL::Types::String,
-        method: :note_html,
-        null: true,
-        description: "GitLab Flavored Markdown rendering of the content of the note."
+      markdown_field :body_html, null: true, method: :note
 
       def url
         ::Gitlab::UrlBuilder.build(object)
@@ -123,8 +118,7 @@ def author
       def id
         return super unless object.is_a?(SyntheticNote)
 
-        # object is a presenter, so object.object returns the concrete note object.
-        ::Gitlab::GlobalId.build(object, model_name: object.object.class.to_s, id: object.discussion_id)
+        ::Gitlab::GlobalId.build(object, model_name: object.class.to_s, id: object.discussion_id)
       end
     end
   end
diff --git a/app/models/service_desk_setting.rb b/app/models/service_desk_setting.rb
index eba39cd5f2b7abfaff4e6b6ab36b5fb4e5c5b7cb..095eb0b67f38a2d1607b948dc435f28d0d1ccb2f 100644
--- a/app/models/service_desk_setting.rb
+++ b/app/models/service_desk_setting.rb
@@ -23,7 +23,7 @@ class ServiceDeskSetting < ApplicationRecord
     length: { maximum: 255 },
     uniqueness: true,
     allow_nil: true,
-    format: Gitlab::Utils::Email::EMAIL_REGEXP_WITH_ANCHORS
+    format: /\A[\w\-._]+@[\w\-.]+\.{1}[a-zA-Z]{2,}\z/
 
   validates :custom_email_credential,
     presence: true,
diff --git a/app/models/system_note_metadata.rb b/app/models/system_note_metadata.rb
index 16a19de0f9dcfe7c962f945b077b548bdea43c09..58b46a2038688086748fefb98338e331a9e7ca05 100644
--- a/app/models/system_note_metadata.rb
+++ b/app/models/system_note_metadata.rb
@@ -25,7 +25,6 @@ class SystemNoteMetadata < ApplicationRecord
     tag due_date start_date_or_due_date pinned_embed cherry_pick health_status approved unapproved
     status alert_issue_added relate unrelate new_alert_added severity contact timeline_event
     issue_type relate_to_child unrelate_from_child relate_to_parent unrelate_from_parent override
-    issue_email_participants
   ].freeze
 
   validates :note, presence: true, unless: :importing?
diff --git a/app/presenters/note_presenter.rb b/app/presenters/note_presenter.rb
deleted file mode 100644
index 00eeded05b73908bae53723133624b0dbf151e40..0000000000000000000000000000000000000000
--- a/app/presenters/note_presenter.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-class NotePresenter < Gitlab::View::Presenter::Delegated # rubocop:disable Gitlab/NamespacedClass -- Note is not namespaced
-  presents ::Note, as: :object # because we also have a #note method
-
-  delegator_override :note
-  def note
-    obfuscate_participants_emails_in_system_note(object.note)
-  end
-
-  delegator_override :note_html
-  def note_html
-    # Always use `redacted_note_html` because it removes references
-    # based on the current user context.
-    # But fall back to `note_html` if redacted is not available (same behavior as `markdown_field`)
-    obfuscate_participants_emails_in_system_note(object.redacted_note_html || object.note_html)
-  end
-
-  private
-
-  def obfuscate_participants_emails_in_system_note(text)
-    return text unless object.system?
-    return text if can?(current_user, :read_external_emails, object.project)
-    return text if object.system_note_metadata&.action != 'issue_email_participants'
-
-    Gitlab::Utils::Email.obfuscate_emails_in_text(text)
-  end
-end
diff --git a/app/serializers/note_entity.rb b/app/serializers/note_entity.rb
index 919d8f08a150c605daad27811fc0b501d7790e2b..a50d893d24459efdeff7062215f65d2e1a9ba575 100644
--- a/app/serializers/note_entity.rb
+++ b/app/serializers/note_entity.rb
@@ -17,13 +17,9 @@ class NoteEntity < API::Entities::Note
   expose :author, using: NoteUserEntity
 
   unexpose :note, as: :body
-  expose :note do |note|
-    note_presenter(note).note
-  end
+  expose :note
 
-  expose :note_html do |note|
-    note_presenter(note).note_html
-  end
+  expose :redacted_note_html, as: :note_html
 
   expose :last_edited_at, if: -> (note, _) { note.edited? }
   expose :last_edited_by, using: NoteUserEntity, if: -> (note, _) { note.edited? }
@@ -122,10 +118,6 @@ def external_author
       Gitlab::Utils::Email.obfuscated_email(object.note_metadata.external_author, deform: true)
     end
   end
-
-  def note_presenter(note)
-    NotePresenter.new(note, current_user: current_user) # rubocop: disable CodeReuse/Presenter -- Directly instantiate NotePresenter because we don't have presenters for all subclasses of Note
-  end
 end
 
 NoteEntity.prepend_mod_with('NoteEntity')
diff --git a/app/services/system_notes/issuables_service.rb b/app/services/system_notes/issuables_service.rb
index 876e694dabf042905ec406604dbb11c008a18b92..a5aae83c32a3fbf866225c740faf27db249859e7 100644
--- a/app/services/system_notes/issuables_service.rb
+++ b/app/services/system_notes/issuables_service.rb
@@ -440,7 +440,7 @@ def mark_duplicate_issue(canonical_issue)
     end
 
     def email_participants(body)
-      create_note(NoteSummary.new(noteable, project, author, body, action: 'issue_email_participants'))
+      create_note(NoteSummary.new(noteable, project, author, body))
     end
 
     def discussion_lock
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index e8b9a9666d567ae521cbc1ea8d563c851e8c8ba4..7a19052bb7e2c49d318cc4bae22f1a78bda9fabb 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -2932,7 +2932,7 @@ Input type: `CreateDiffNoteInput`
 | <a id="mutationcreatediffnoteconfidential"></a>`confidential` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated:** This was renamed. Please use `internal`. Deprecated in GitLab 15.3. |
 | <a id="mutationcreatediffnoteinternal"></a>`internal` | [`Boolean`](#boolean) | Internal flag for a note. Default is false. |
 | <a id="mutationcreatediffnotenoteableid"></a>`noteableId` | [`NoteableID!`](#noteableid) | Global ID of the resource to add a note to. |
-| <a id="mutationcreatediffnoteposition"></a>`position` | [`DiffPositionInput!`](#diffpositioninput) | Position of the note on a diff. |
+| <a id="mutationcreatediffnoteposition"></a>`position` | [`DiffPositionInput!`](#diffpositioninput) | Position of this note on a diff. |
 
 #### Fields
 
@@ -3007,7 +3007,7 @@ Input type: `CreateImageDiffNoteInput`
 | <a id="mutationcreateimagediffnoteconfidential"></a>`confidential` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated:** This was renamed. Please use `internal`. Deprecated in GitLab 15.3. |
 | <a id="mutationcreateimagediffnoteinternal"></a>`internal` | [`Boolean`](#boolean) | Internal flag for a note. Default is false. |
 | <a id="mutationcreateimagediffnotenoteableid"></a>`noteableId` | [`NoteableID!`](#noteableid) | Global ID of the resource to add a note to. |
-| <a id="mutationcreateimagediffnoteposition"></a>`position` | [`DiffImagePositionInput!`](#diffimagepositioninput) | Position of the note on a diff. |
+| <a id="mutationcreateimagediffnoteposition"></a>`position` | [`DiffImagePositionInput!`](#diffimagepositioninput) | Position of this note on a diff. |
 
 #### Fields
 
@@ -7407,7 +7407,7 @@ Input type: `RepositionImageDiffNoteInput`
 | ---- | ---- | ----------- |
 | <a id="mutationrepositionimagediffnoteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
 | <a id="mutationrepositionimagediffnoteid"></a>`id` | [`DiffNoteID!`](#diffnoteid) | Global ID of the DiffNote to update. |
-| <a id="mutationrepositionimagediffnoteposition"></a>`position` | [`UpdateDiffImagePositionInput!`](#updatediffimagepositioninput) | Position of the note on a diff. |
+| <a id="mutationrepositionimagediffnoteposition"></a>`position` | [`UpdateDiffImagePositionInput!`](#updatediffimagepositioninput) | Position of this note on a diff. |
 
 #### Fields
 
@@ -8431,7 +8431,7 @@ Input type: `UpdateImageDiffNoteInput`
 | <a id="mutationupdateimagediffnotebody"></a>`body` | [`String`](#string) | Content of the note. |
 | <a id="mutationupdateimagediffnoteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
 | <a id="mutationupdateimagediffnoteid"></a>`id` | [`NoteID!`](#noteid) | Global ID of the note to update. |
-| <a id="mutationupdateimagediffnoteposition"></a>`position` | [`UpdateDiffImagePositionInput`](#updatediffimagepositioninput) | Position of the note on a diff. |
+| <a id="mutationupdateimagediffnoteposition"></a>`position` | [`UpdateDiffImagePositionInput`](#updatediffimagepositioninput) | Position of this note on a diff. |
 
 #### Fields
 
@@ -24902,30 +24902,30 @@ Represents the network policy.
 
 | Name | Type | Description |
 | ---- | ---- | ----------- |
-| <a id="noteauthor"></a>`author` | [`UserCore`](#usercore) | User who wrote the note. |
+| <a id="noteauthor"></a>`author` | [`UserCore`](#usercore) | User who wrote this note. |
 | <a id="noteauthoriscontributor"></a>`authorIsContributor` | [`Boolean`](#boolean) | Indicates whether the note author is a contributor. |
 | <a id="noteawardemoji"></a>`awardEmoji` | [`AwardEmojiConnection`](#awardemojiconnection) | List of emoji reactions associated with the note. (see [Connections](#connections)) |
 | <a id="notebody"></a>`body` | [`String!`](#string) | Content of the note. |
-| <a id="notebodyhtml"></a>`bodyHtml` | [`String`](#string) | GitLab Flavored Markdown rendering of the content of the note. |
+| <a id="notebodyhtml"></a>`bodyHtml` | [`String`](#string) | GitLab Flavored Markdown rendering of `note`. |
 | <a id="noteconfidential"></a>`confidential` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated** in GitLab 15.5. This was renamed. Use: `internal`. |
 | <a id="notecreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp of the note creation. |
-| <a id="notediscussion"></a>`discussion` | [`Discussion`](#discussion) | Discussion the note is a part of. |
+| <a id="notediscussion"></a>`discussion` | [`Discussion`](#discussion) | Discussion this note is a part of. |
 | <a id="noteid"></a>`id` | [`NoteID!`](#noteid) | ID of the note. |
-| <a id="noteinternal"></a>`internal` | [`Boolean`](#boolean) | Indicates if the note is internal. |
+| <a id="noteinternal"></a>`internal` | [`Boolean`](#boolean) | Indicates if this note is internal. |
 | <a id="notelasteditedat"></a>`lastEditedAt` | [`Time`](#time) | Timestamp when note was last edited. |
 | <a id="notelasteditedby"></a>`lastEditedBy` | [`UserCore`](#usercore) | User who last edited the note. |
 | <a id="notemaxaccesslevelofauthor"></a>`maxAccessLevelOfAuthor` | [`String`](#string) | Max access level of the note author in the project. |
-| <a id="noteposition"></a>`position` | [`DiffPosition`](#diffposition) | Position of the note on a diff. |
+| <a id="noteposition"></a>`position` | [`DiffPosition`](#diffposition) | Position of this note on a diff. |
 | <a id="noteproject"></a>`project` | [`Project`](#project) | Project associated with the note. |
 | <a id="noteresolvable"></a>`resolvable` | [`Boolean!`](#boolean) | Indicates if the object can be resolved. |
 | <a id="noteresolved"></a>`resolved` | [`Boolean!`](#boolean) | Indicates if the object is resolved. |
 | <a id="noteresolvedat"></a>`resolvedAt` | [`Time`](#time) | Timestamp of when the object was resolved. |
 | <a id="noteresolvedby"></a>`resolvedBy` | [`UserCore`](#usercore) | User who resolved the object. |
-| <a id="notesystem"></a>`system` | [`Boolean!`](#boolean) | Indicates whether the note was created by the system or by a user. |
+| <a id="notesystem"></a>`system` | [`Boolean!`](#boolean) | Indicates whether this note was created by the system or by a user. |
 | <a id="notesystemnoteiconname"></a>`systemNoteIconName` | [`String`](#string) | Name of the icon corresponding to a system note. |
 | <a id="notesystemnotemetadata"></a>`systemNoteMetadata` | [`SystemNoteMetadata`](#systemnotemetadata) | Metadata for the given note if it is a system note. |
 | <a id="noteupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp of the note's last activity. |
-| <a id="noteurl"></a>`url` | [`String`](#string) | URL to view the note in the Web UI. |
+| <a id="noteurl"></a>`url` | [`String`](#string) | URL to view this Note in the Web UI. |
 | <a id="noteuserpermissions"></a>`userPermissions` | [`NotePermissions!`](#notepermissions) | Permissions for the current user on the resource. |
 
 ### `NotePermissions`
diff --git a/lib/api/entities/note.rb b/lib/api/entities/note.rb
index 97f4810866215f0b3595e16629dd908e4024781d..c693edc611bbaf0150330d90fb259f3247c8e943 100644
--- a/lib/api/entities/note.rb
+++ b/lib/api/entities/note.rb
@@ -8,11 +8,7 @@ class Note < Grape::Entity
 
       expose :id
       expose :type
-
-      expose :body do |note|
-        NotePresenter.new(note, current_user: options[:current_user]).note
-      end
-
+      expose :note, as: :body
       expose :attachment_identifier, as: :attachment
       expose :author, using: Entities::UserBasic
       expose :created_at, :updated_at
diff --git a/lib/api/notes.rb b/lib/api/notes.rb
index 138b2fddc8363fbcd752b124b9f0593817d27f49..70b4a3735e3cc718567471fca64b598a81fff8d2 100644
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -51,7 +51,7 @@ class Notes < ::API::Base
           notes = paginate(raw_notes)
           notes = prepare_notes_for_rendering(notes)
           notes = notes.select { |note| note.readable_by?(current_user) }
-          present notes, with: Entities::Note, current_user: current_user
+          present notes, with: Entities::Note
         end
         # rubocop: enable CodeReuse/ActiveRecord
 
diff --git a/lib/gitlab/email/service_desk/custom_email.rb b/lib/gitlab/email/service_desk/custom_email.rb
index 2d2ca20aa115e88c5f1f4c207e95046aa5bf8717..1828f71984b8df935843b915f262891f1b0f3b06 100644
--- a/lib/gitlab/email/service_desk/custom_email.rb
+++ b/lib/gitlab/email/service_desk/custom_email.rb
@@ -8,6 +8,7 @@ module ServiceDesk
       # incoming_email and service_desk_email.
       module CustomEmail
         REPLY_ADDRESS_KEY_REGEXP = /\+([0-9a-f]{32})@/
+        EMAIL_REGEXP = /\A[\w\-._]+@[\w\-.]+\.{1}[a-zA-Z]{2,}\z/
 
         class << self
           def reply_address(issue, reply_key)
@@ -39,7 +40,7 @@ def key_from_reply_address(email)
 
           def find_service_desk_setting_from_reply_address(email, key)
             potential_custom_email = email.sub("+#{key}", '')
-            return unless Gitlab::Utils::Email::EMAIL_REGEXP_WITH_ANCHORS.match?(potential_custom_email)
+            return unless EMAIL_REGEXP.match?(potential_custom_email)
 
             ServiceDeskSetting.find_by_custom_email(potential_custom_email)
           end
diff --git a/lib/gitlab/utils/email.rb b/lib/gitlab/utils/email.rb
index 6decb3da8f87f8dfa5b2459166524b84abd2ca63..5eb57a66c63d9ff2804b21b1a140104c337eaedd 100644
--- a/lib/gitlab/utils/email.rb
+++ b/lib/gitlab/utils/email.rb
@@ -5,13 +5,6 @@ module Utils
     module Email
       extend self
 
-      # Don't use Devise.email_regexp or URI::MailTo::EMAIL_REGEXP to be a bit more restrictive
-      # on the format of an email. Especially for custom email addresses which cannot contain a `+`
-      # in app/models/service_desk_setting.rb
-      EMAIL_REGEXP = /[\w\-._]+@[\w\-.]+\.{1}[a-zA-Z]{2,}/
-      EMAIL_REGEXP_WITH_CAPTURING_GROUP = /(#{EMAIL_REGEXP})/
-      EMAIL_REGEXP_WITH_ANCHORS = /\A#{EMAIL_REGEXP.source}\z/
-
       # Replaces most visible characters with * to obfuscate an email address
       # deform adds a fix number of * to ensure the address cannot be guessed. Also obfuscates TLD with **
       def obfuscated_email(email, deform: false)
@@ -21,17 +14,6 @@ def obfuscated_email(email, deform: false)
         masker_class.new(email).masked
       end
 
-      # Runs email address obfuscation on the given text.
-      def obfuscate_emails_in_text(text)
-        return text unless text.present?
-
-        matches = text.scan(EMAIL_REGEXP_WITH_CAPTURING_GROUP).flatten.index_with do |match|
-          obfuscated_email(match, deform: true)
-        end
-
-        text.gsub(Regexp.union(matches.keys), matches)
-      end
-
       class Masker
         attr_reader :local_part, :sub_domain, :toplevel_domain, :at, :dot
 
diff --git a/spec/graphql/types/notes/note_type_spec.rb b/spec/graphql/types/notes/note_type_spec.rb
index 02f311785db2bfdf18fa3d4ba52d0bb2fbaa2dbb..8aabdb78562cfc3b087b16b0b0f48d015bc6cbfe 100644
--- a/spec/graphql/types/notes/note_type_spec.rb
+++ b/spec/graphql/types/notes/note_type_spec.rb
@@ -3,8 +3,6 @@
 require 'spec_helper'
 
 RSpec.describe GitlabSchema.types['Note'], feature_category: :team_planning do
-  include GraphqlHelpers
-
   it 'exposes the expected fields' do
     expected_fields = %i[
       author
@@ -39,35 +37,4 @@
 
   specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Note) }
   specify { expect(described_class).to require_graphql_authorizations(:read_note) }
-
-  context 'when system note with issue_email_participants action', feature_category: :service_desk do
-    let_it_be(:user) { build_stubbed(:user) }
-    let_it_be(:email) { 'user@example.com' }
-    let_it_be(:note_text) { "added #{email}" }
-    # Create project and issue separately because we need to public project.
-    # rubocop:disable RSpec/FactoryBot/AvoidCreate -- Notes::RenderService updates #note and #cached_markdown_version
-    let_it_be(:project) { create(:project, :public) }
-    let_it_be(:issue) { create(:issue, project: project) }
-    let_it_be(:note) do
-      create(:note, :system, project: project, noteable: issue, author: Users::Internal.support_bot, note: note_text)
-    end
-
-    let_it_be(:system_note_metadata) { create(:system_note_metadata, note: note, action: :issue_email_participants) }
-    # rubocop:enable RSpec/FactoryBot/AvoidCreate
-
-    let(:prepared_note) {  Notes::RenderService.new(user).execute([note]).first }
-    let(:obfuscated_email) { 'us*****@e*****.c**' }
-
-    describe '#body' do
-      subject { resolve_field(:body, prepared_note, current_user: user) }
-
-      it_behaves_like 'a note content field with obfuscated email address'
-    end
-
-    describe '#body_html' do
-      subject { resolve_field(:body_html, prepared_note, current_user: user) }
-
-      it_behaves_like 'a note content field with obfuscated email address'
-    end
-  end
 end
diff --git a/spec/lib/gitlab/utils/email_spec.rb b/spec/lib/gitlab/utils/email_spec.rb
index 430002eb520fbfed8546c2a8239332145c7da784..c81c2558f706b00ea45380e12ac1482d445202a1 100644
--- a/spec/lib/gitlab/utils/email_spec.rb
+++ b/spec/lib/gitlab/utils/email_spec.rb
@@ -51,20 +51,4 @@
       end
     end
   end
-
-  describe '.obfuscate_emails_in_text' do
-    where(:input, :output) do
-      nil | nil
-      '' | ''
-      'added no email address' | 'added no email address'
-      'added user@example.com' | 'added us*****@e*****.c**'
-      'added user@example.com and hello@example.com' | 'added us*****@e*****.c** and he*****@e*****.c**'
-      'removed user@example.com, hello@example.com and bye@example.com' |
-        'removed us*****@e*****.c**, he*****@e*****.c** and by*****@e*****.c**'
-    end
-
-    with_them do
-      it { expect(described_class.obfuscate_emails_in_text(input)).to eq(output) }
-    end
-  end
 end
diff --git a/spec/presenters/note_presenter_spec.rb b/spec/presenters/note_presenter_spec.rb
deleted file mode 100644
index 2a8ae38f08274ce4e92112af859644116eee9c32..0000000000000000000000000000000000000000
--- a/spec/presenters/note_presenter_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe NotePresenter, feature_category: :team_planning do
-  let_it_be(:user) { build_stubbed(:user) }
-  let_it_be(:email) { 'user@example.com' }
-  let_it_be(:note_text) { "added #{email}" }
-  # rubocop:disable RSpec/FactoryBot/AvoidCreate -- Notes::RenderService updates #note and #cached_markdown_version
-  let_it_be_with_reload(:note) { create(:note, :system, author: Users::Internal.support_bot, note: note_text) }
-  let_it_be(:system_note_metadata) { create(:system_note_metadata, note: note, action: :issue_email_participants) }
-  # rubocop:enable RSpec/FactoryBot/AvoidCreate
-
-  let(:obfuscated_email) { 'us*****@e*****.c**' }
-
-  subject(:presenter) do
-    # The RenderService calls Banzai::ObjectRenderer which
-    # populates `redacted_note_html`. We also do this in
-    # API controllers.
-    prepared_notes = Notes::RenderService.new(user).execute([note])
-    described_class.new(prepared_notes.first, current_user: user)
-  end
-
-  describe '#note' do
-    subject { presenter.note }
-
-    it_behaves_like 'a note content field with obfuscated email address'
-  end
-
-  describe '#note_html' do
-    subject { presenter.note_html }
-
-    it_behaves_like 'a note content field with obfuscated email address'
-
-    context 'when redacted_note_html is not present' do
-      subject(:presenter) do
-        described_class.new(note, current_user: user).note_html
-      end
-
-      it 'falls back to note_html and obfuscates emails' do
-        is_expected.to include(obfuscated_email)
-      end
-    end
-  end
-end
diff --git a/spec/requests/api/graphql/notes/note_spec.rb b/spec/requests/api/graphql/notes/note_spec.rb
index 2a2ea8ce49b1dba32745d214cdaa7be75face07a..daceaec0b94cd6002e622d980284043df4a52486 100644
--- a/spec/requests/api/graphql/notes/note_spec.rb
+++ b/spec/requests/api/graphql/notes/note_spec.rb
@@ -6,7 +6,6 @@
   include GraphqlHelpers
 
   let_it_be(:current_user) { create(:user) }
-  let_it_be(:reporter_user) { create(:user) }
   let_it_be(:project) { create(:project, :private) }
   let_it_be(:issue) { create(:issue, project: project) }
   let_it_be(:note) { create(:note, noteable: issue, project: project) }
@@ -20,10 +19,6 @@
     graphql_query_for('note', note_params, note_fields)
   end
 
-  before_all do
-    project.add_reporter(reporter_user)
-  end
-
   it_behaves_like 'a working graphql query' do
     before do
       post_graphql(query, current_user: current_user)
@@ -49,7 +44,7 @@
   end
 
   context 'when the user has access to read the note' do
-    before_all do
+    before do
       project.add_guest(current_user)
     end
 
@@ -67,40 +62,6 @@
 
         expect(note_data['id']).to eq(global_id_of(system_note).to_s)
       end
-
-      context 'with issue_email_participants action' do
-        let_it_be(:email) { 'user@example.com' }
-        let_it_be(:note_text) { "added #{email}" }
-        let_it_be(:issue_email_participants_system_note) do
-          create(:note, :system,
-            project: project, noteable: issue, author: Users::Internal.support_bot, note: note_text)
-        end
-
-        let_it_be(:system_note_metadata) do
-          create(:system_note_metadata, note: issue_email_participants_system_note, action: :issue_email_participants)
-        end
-
-        let(:obfuscated_email) { 'us*****@e*****.c**' }
-        let(:note_params) { { 'id' => global_id_of(issue_email_participants_system_note) } }
-
-        it 'returns obfuscated email' do
-          post_graphql(query, current_user: current_user)
-
-          expect(note_data['id']).to eq(global_id_of(issue_email_participants_system_note).to_s)
-          expect(note_data['body']).to include(obfuscated_email)
-          expect(note_data['bodyHtml']).to include(obfuscated_email)
-        end
-
-        context 'when user has at least the reporter role in project' do
-          it 'returns email' do
-            post_graphql(query, current_user: reporter_user)
-
-            expect(note_data['id']).to eq(global_id_of(issue_email_participants_system_note).to_s)
-            expect(note_data['body']).to include(email)
-            expect(note_data['bodyHtml']).to include(email)
-          end
-        end
-      end
     end
 
     context 'and notes widget is not available' do
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index e7ff7baaa6ce09def70ab9baa591dd9b1d265f34..497bbeced38b4a1fff1c8af4a84abbfad87702b4 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -49,37 +49,6 @@
       end
     end
 
-    context 'when system note with issue_email_participants action' do
-      let!(:email) { 'user@example.com' }
-      let!(:note_text) { "added #{email}" }
-      let!(:note) do
-        create(:note, :system, project: project, noteable: issue, author: Users::Internal.support_bot, note: note_text)
-      end
-
-      let!(:system_note_metadata) { create(:system_note_metadata, note: note, action: :issue_email_participants) }
-      let!(:another_user) { create(:user) }
-
-      let(:obfuscated_email) { 'us*****@e*****.c**' }
-
-      it 'returns obfuscated email' do
-        get api("/projects/#{project.id}/issues/#{issue.iid}/notes", another_user)
-
-        expect(response).to have_gitlab_http_status(:ok)
-        expect(response).to include_pagination_headers
-        expect(json_response.first['body']).to include(obfuscated_email)
-      end
-
-      context 'when user has at least the reporter role in project' do
-        it 'returns email' do
-          get api("/projects/#{project.id}/issues/#{issue.iid}/notes", user)
-
-          expect(response).to have_gitlab_http_status(:ok)
-          expect(response).to include_pagination_headers
-          expect(json_response.first['body']).to include(email)
-        end
-      end
-    end
-
     context "when referencing other project" do
       # For testing the cross-reference of a private issue in a public project
       let(:private_project) do
diff --git a/spec/serializers/note_entity_spec.rb b/spec/serializers/note_entity_spec.rb
index 51335c5f73204b027bf93f77e25c66f09d3a0278..d5c4a31a93785c4fd0250ecceb6c5547f8ff55e3 100644
--- a/spec/serializers/note_entity_spec.rb
+++ b/spec/serializers/note_entity_spec.rb
@@ -2,17 +2,14 @@
 
 require 'spec_helper'
 
-RSpec.describe NoteEntity, feature_category: :team_planning do
+RSpec.describe NoteEntity do
   include Gitlab::Routing
 
-  # rubocop:disable RSpec/FactoryBot/AvoidCreate -- Persisted records required
-  let_it_be(:note) { create(:note) }
-  let_it_be(:user) { create(:user) }
-  # rubocop:enable RSpec/FactoryBot/AvoidCreate
-
   let(:request) { double('request', current_user: user, noteable: note.noteable) }
 
   let(:entity) { described_class.new(note, request: request) }
+  let(:note) { create(:note) }
+  let(:user) { create(:user) }
 
   subject { entity.as_json }
 
@@ -56,8 +53,9 @@
     end
   end
 
-  describe 'with email participant', feature_category: :service_desk do
-    let_it_be(:note_metadata) { create(:note_metadata, note: note) } # rubocop:disable RSpec/FactoryBot/AvoidCreate -- Persisted records required
+  describe 'with email participant' do
+    let_it_be(:note) { create(:note) }
+    let_it_be(:note_metadata) { create(:note_metadata, note: note) }
 
     subject { entity.as_json[:external_author] }
 
@@ -68,36 +66,4 @@
       it_behaves_like 'external author'
     end
   end
-
-  context 'when system note with issue_email_participants action', feature_category: :service_desk do
-    let_it_be(:email) { 'user@example.com' }
-    let_it_be(:note_text) { "added #{email}" }
-    # rubocop:disable RSpec/FactoryBot/AvoidCreate -- Notes::RenderService updates #note and #cached_markdown_version
-    let_it_be(:note) { create(:note, :system, author: Users::Internal.support_bot, note: note_text) }
-    let_it_be(:system_note_metadata) { create(:system_note_metadata, note: note, action: :issue_email_participants) }
-    # rubocop:enable RSpec/FactoryBot/AvoidCreate
-
-    let(:obfuscated_email) { 'us*****@e*****.c**' }
-    let(:expected_text) { obfuscated_email }
-
-    subject(:entity_hash) do
-      # The RenderService calls Banzai::ObjectRenderer which
-      # populates `redacted_note_html`. We also do this in
-      # API controllers.
-      prepared_notes = Notes::RenderService.new(user).execute([note])
-      described_class.new(prepared_notes.first, request: request).as_json
-    end
-
-    describe 'note' do
-      subject { entity_hash[:note] }
-
-      it_behaves_like 'a note content field with obfuscated email address'
-    end
-
-    describe 'note_html' do
-      subject { entity_hash[:note_html] }
-
-      it_behaves_like 'a note content field with obfuscated email address'
-    end
-  end
 end
diff --git a/spec/services/issue_email_participants/create_service_spec.rb b/spec/services/issue_email_participants/create_service_spec.rb
index 05c9162dde14872c3f64972f6f83a82889adc177..dc8d5a6ea74ec42b81b47121319fc8d224f253d1 100644
--- a/spec/services/issue_email_participants/create_service_spec.rb
+++ b/spec/services/issue_email_participants/create_service_spec.rb
@@ -12,7 +12,6 @@
       note = issue.notes.last
       expect(note.system?).to be true
       expect(note.author).to eq(user)
-      expect(note.system_note_metadata.action).to eq('issue_email_participants')
 
       participants_emails = issue.email_participants_emails_downcase
 
diff --git a/spec/support/shared_examples/graphql/notes_content_obfuscation_shared_examples.rb b/spec/support/shared_examples/graphql/notes_content_obfuscation_shared_examples.rb
deleted file mode 100644
index 0f8f24a034f2e8825fb676bd42e83fe340c7395c..0000000000000000000000000000000000000000
--- a/spec/support/shared_examples/graphql/notes_content_obfuscation_shared_examples.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.shared_examples 'a note content field with obfuscated email address' do
-  context 'when anonymous' do
-    let(:user) { nil }
-
-    it { is_expected.to include(obfuscated_email) }
-  end
-
-  context 'with signed in user' do
-    before do
-      stub_member_access_level(note.project, access_level => user) if access_level
-    end
-
-    context 'when user has no role in project' do
-      let(:access_level) { nil }
-
-      it { is_expected.to include(obfuscated_email) }
-    end
-
-    context 'when user has guest role in project' do
-      let(:access_level) { :guest }
-
-      it { is_expected.to include(obfuscated_email) }
-    end
-
-    context 'when user has reporter role in project' do
-      let(:access_level) { :reporter }
-
-      it { is_expected.to include(email) }
-    end
-
-    context 'when user has developer role in project' do
-      let(:access_level) { :developer }
-
-      it { is_expected.to include(email) }
-    end
-  end
-end