diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 9e112f4e5f02dfd5b625d160556bdf239fa480be..2a1dcbaaf1dfdc485e43630f6672573c1f2771a9 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -395,8 +395,6 @@ def by_negated_assignee(items)
     # We want CE users to be able to say "Issues not assigned to either PersonA nor PersonB"
     if not_params.assignees.present?
       items.not_assigned_to(not_params.assignees)
-    elsif not_params.assignee_id? || not_params.assignee_username? # assignee not found
-      items.none
     else
       items
     end
diff --git a/app/graphql/resolvers/concerns/issue_resolver_arguments.rb b/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
index 84b0dafe213228d6073e8f26df6476b91bf5396e..f95a676054adf978628f57e663aca567e8aa31b3 100644
--- a/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
+++ b/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
@@ -12,10 +12,10 @@ module IssueResolverArguments
     argument :iids, [GraphQL::STRING_TYPE],
               required: false,
               description: 'List of IIDs of issues. For example, [1, 2].'
-    argument :label_name, GraphQL::STRING_TYPE.to_list_type,
+    argument :label_name, [GraphQL::STRING_TYPE, null: true],
               required: false,
               description: 'Labels applied to this issue.'
-    argument :milestone_title, GraphQL::STRING_TYPE.to_list_type,
+    argument :milestone_title, [GraphQL::STRING_TYPE, null: true],
               required: false,
               description: 'Milestone applied to this issue.'
     argument :author_username, GraphQL::STRING_TYPE,
@@ -55,6 +55,10 @@ module IssueResolverArguments
               as: :issue_types,
               description: 'Filter issues by the given issue types.',
               required: false
+    argument :not, Types::Issues::NegatedIssueFilterInputType,
+             description: 'List of negated params.',
+             prepare: ->(negated_args, ctx) { negated_args.to_h },
+             required: false
   end
 
   def resolve_with_lookahead(**args)
@@ -69,11 +73,22 @@ def resolve_with_lookahead(**args)
     args[:iids] ||= [args.delete(:iid)].compact if args[:iid]
     args[:attempt_project_search_optimizations] = true if args[:search].present?
 
+    prepare_assignee_username_params(args)
+
     finder = IssuesFinder.new(current_user, args)
 
     continue_issue_resolve(parent, finder, **args)
   end
 
+  def ready?(**args)
+    if args.slice(*mutually_exclusive_assignee_username_args).compact.size > 1
+      arg_str = mutually_exclusive_assignee_username_args.map { |x| x.to_s.camelize(:lower) }.join(', ')
+      raise Gitlab::Graphql::Errors::ArgumentError, "only one of [#{arg_str}] arguments is allowed at the same time."
+    end
+
+    super
+  end
+
   class_methods do
     def resolver_complexity(args, child_complexity:)
       complexity = super
@@ -82,4 +97,15 @@ def resolver_complexity(args, child_complexity:)
       complexity
     end
   end
+
+  private
+
+  def prepare_assignee_username_params(args)
+    args[:assignee_username] = args.delete(:assignee_usernames) if args[:assignee_usernames].present?
+    args[:not][:assignee_username] = args[:not].delete(:assignee_usernames) if args.dig(:not, :assignee_usernames).present?
+  end
+
+  def mutually_exclusive_assignee_username_args
+    [:assignee_usernames, :assignee_username]
+  end
 end
diff --git a/app/graphql/types/boards/board_issuable_input_base_type.rb b/app/graphql/types/boards/board_issuable_input_base_type.rb
index a70d90ce253f1725153a2733ac8a93b88ddda4ba..2cd057347d60753e9e330e853bdd6e8a252f759f 100644
--- a/app/graphql/types/boards/board_issuable_input_base_type.rb
+++ b/app/graphql/types/boards/board_issuable_input_base_type.rb
@@ -4,7 +4,7 @@ module Types
   module Boards
     # Common arguments that we can be used to filter boards epics and issues
     class BoardIssuableInputBaseType < BaseInputObject
-      argument :label_name, GraphQL::STRING_TYPE.to_list_type,
+      argument :label_name, [GraphQL::STRING_TYPE, null: true],
                required: false,
                description: 'Filter by label name.'
 
diff --git a/app/graphql/types/boards/board_issue_input_base_type.rb b/app/graphql/types/boards/board_issue_input_base_type.rb
index 5bd2334c7221d25ff53d5361377ebf4d7113ce6b..7cf2dcb9c8294920e588d6f200d3e14ae23b2347 100644
--- a/app/graphql/types/boards/board_issue_input_base_type.rb
+++ b/app/graphql/types/boards/board_issue_input_base_type.rb
@@ -8,7 +8,7 @@ class BoardIssueInputBaseType < BoardIssuableInputBaseType
                required: false,
                description: 'Filter by milestone title.'
 
-      argument :assignee_username, GraphQL::STRING_TYPE.to_list_type,
+      argument :assignee_username, [GraphQL::STRING_TYPE, null: true],
                required: false,
                description: 'Filter by assignee username.'
 
diff --git a/app/graphql/types/issues/negated_issue_filter_input_type.rb b/app/graphql/types/issues/negated_issue_filter_input_type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..10bf6f21792e9da51c24a650481bb31dbeb78af8
--- /dev/null
+++ b/app/graphql/types/issues/negated_issue_filter_input_type.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Types
+  module Issues
+    class NegatedIssueFilterInputType < BaseInputObject
+      graphql_name 'NegatedIssueFilterInput'
+
+      argument :iids, [GraphQL::STRING_TYPE],
+                required: false,
+                description: 'List of IIDs of issues to exclude. For example, [1, 2].'
+      argument :label_name, [GraphQL::STRING_TYPE],
+                required: false,
+                description: 'Labels not applied to this issue.'
+      argument :milestone_title, [GraphQL::STRING_TYPE],
+                required: false,
+                description: 'Milestone not applied to this issue.'
+      argument :assignee_usernames, [GraphQL::STRING_TYPE],
+                required: false,
+                description: 'Usernames of users not assigned to the issue.'
+      argument :assignee_id, GraphQL::STRING_TYPE,
+                required: false,
+                description: 'ID of a user not assigned to the issues.'
+    end
+  end
+end
+
+Types::Issues::NegatedIssueFilterInputType.prepend_if_ee('::EE::Types::Issues::NegatedIssueFilterInputType')
diff --git a/app/models/pages/lookup_path.rb b/app/models/pages/lookup_path.rb
index 3f54aa4817d15cbf7add4e650d9edc0c5a77bcc9..9efea284b5ce0e12c4a254772a939e537197181f 100644
--- a/app/models/pages/lookup_path.rb
+++ b/app/models/pages/lookup_path.rb
@@ -52,8 +52,6 @@ def zip_source
 
       return if deployment.file.file_storage? && !Feature.enabled?(:pages_serve_with_zip_file_protocol, project, default_enabled: :yaml)
 
-      return if deployment.migrated? && !Feature.enabled?(:pages_serve_from_migrated_zip, project, default_enabled: true)
-
       global_id = ::Gitlab::GlobalId.build(deployment, id: deployment.id).to_s
 
       {
diff --git a/app/views/shared/deploy_tokens/_form.html.haml b/app/views/shared/deploy_tokens/_form.html.haml
index 2ddfcf437563c0bd29d66f808b5ac767943e3a5c..4d0858165a28b564d02272b7c9edb47e6c48cf10 100644
--- a/app/views/shared/deploy_tokens/_form.html.haml
+++ b/app/views/shared/deploy_tokens/_form.html.haml
@@ -22,29 +22,29 @@
     = f.label :scopes, _('Scopes [Select 1 or more]'), class: 'label-bold'
     %fieldset.form-group.form-check
       = f.check_box :read_repository, class: 'form-check-input qa-deploy-token-read-repository'
-      = label_tag ("deploy_token_read_repository"), 'read_repository', class: 'label-bold form-check-label'
+      = f.label :read_repository, 'read_repository', class: 'label-bold form-check-label'
       .text-secondary= s_('DeployTokens|Allows read-only access to the repository.')
 
     - if container_registry_enabled?(group_or_project)
       %fieldset.form-group.form-check
         = f.check_box :read_registry, class: 'form-check-input qa-deploy-token-read-registry'
-        = label_tag ("deploy_token_read_registry"), 'read_registry', class: 'label-bold form-check-label'
+        = f.label :read_registry, 'read_registry', class: 'label-bold form-check-label'
         .text-secondary= s_('DeployTokens|Allows read-only access to registry images.')
 
       %fieldset.form-group.form-check
         = f.check_box :write_registry, class: 'form-check-input'
-        = label_tag ("deploy_token_write_registry"), 'write_registry', class: 'label-bold form-check-label'
+        = f.label :write_registry, 'write_registry', class: 'label-bold form-check-label'
         .text-secondary= s_('DeployTokens|Allows write access to registry images.')
 
     - if packages_registry_enabled?(group_or_project)
       %fieldset.form-group.form-check
         = f.check_box :read_package_registry, class: 'form-check-input'
-        = label_tag ("deploy_token_read_package_registry"), 'read_package_registry', class: 'label-bold form-check-label'
+        = f.label :read_package_registry, 'read_package_registry', class: 'label-bold form-check-label'
         .text-secondary= s_('DeployTokens|Allows read access to the package registry.')
 
       %fieldset.form-group.form-check
         = f.check_box :write_package_registry, class: 'form-check-input'
-        = label_tag ("deploy_token_write_package_registry"), 'write_package_registry', class: 'label-bold form-check-label'
+        = f.label :write_package_registry, 'write_package_registry', class: 'label-bold form-check-label'
         .text-secondary= s_('DeployTokens|Allows write access to the package registry.')
 
   .gl-mt-3
diff --git a/changelogs/unreleased/300021-rollout-serving-migrated-data-feature-flag-pages_serve_from_migrat.yml b/changelogs/unreleased/300021-rollout-serving-migrated-data-feature-flag-pages_serve_from_migrat.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ccf19216909be1852a6c019bb8330469b44c9237
--- /dev/null
+++ b/changelogs/unreleased/300021-rollout-serving-migrated-data-feature-flag-pages_serve_from_migrat.yml
@@ -0,0 +1,5 @@
+---
+title: Remove pages_serve_from_migrated_zip feature flag
+merge_request: 59002
+author:
+type: added
diff --git a/changelogs/unreleased/300115-support-negated-issue-filters-gql.yml b/changelogs/unreleased/300115-support-negated-issue-filters-gql.yml
new file mode 100644
index 0000000000000000000000000000000000000000..356a5aed1c3cf422bbbd20653baedb73a45420d7
--- /dev/null
+++ b/changelogs/unreleased/300115-support-negated-issue-filters-gql.yml
@@ -0,0 +1,5 @@
+---
+title: Support negated filtering of issues by iids, label_name, milestone_title, assignee_usernames and assignee_id in GraphQL
+merge_request: 58154
+author:
+type: added
diff --git a/config/feature_flags/development/pages_serve_from_migrated_zip.yml b/config/feature_flags/development/pages_serve_from_migrated_zip.yml
deleted file mode 100644
index 2912beb39856545997e193569663f1c812b08fd4..0000000000000000000000000000000000000000
--- a/config/feature_flags/development/pages_serve_from_migrated_zip.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: pages_serve_from_migrated_zip
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52573
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/300021
-milestone: '13.9'
-type: development
-group: group::release
-default_enabled: true
diff --git a/doc/administration/geo/replication/docker_registry.md b/doc/administration/geo/replication/docker_registry.md
index 1669abbc52ae7a79cc775c810453692e85cbc84c..745ed28056f188af729047d1bf9fe18acdcd7c28 100644
--- a/doc/administration/geo/replication/docker_registry.md
+++ b/doc/administration/geo/replication/docker_registry.md
@@ -5,16 +5,16 @@ info: To determine the technical writer assigned to the Stage/Group associated w
 type: howto
 ---
 
-# Docker Registry for a secondary node **(PREMIUM SELF)**
+# Docker Registry for a secondary site **(PREMIUM SELF)**
 
 You can set up a [Docker Registry](https://docs.docker.com/registry/) on your
-**secondary** Geo node that mirrors the one on the **primary** Geo node.
+**secondary** Geo site that mirrors the one on the **primary** Geo site.
 
 ## Storage support
 
 Docker Registry currently supports a few types of storage. If you choose a
 distributed storage (`azure`, `gcs`, `s3`, `swift`, or `oss`) for your Docker
-Registry on the **primary** node, you can use the same storage for a **secondary**
+Registry on the **primary** site, you can use the same storage for a **secondary**
 Docker Registry as well. For more information, read the
 [Load balancing considerations](https://docs.docker.com/registry/deploying/#load-balancing-considerations)
 when deploying the Registry, and how to set up the storage driver for the GitLab
@@ -24,22 +24,22 @@ integrated [Container Registry](../../packages/container_registry.md#use-object-
 
 You can enable a storage-agnostic replication so it
 can be used for cloud or local storage. Whenever a new image is pushed to the
-**primary** node, each **secondary** node will pull it to its own container
+**primary** site, each **secondary** site will pull it to its own container
 repository.
 
 To configure Docker Registry replication:
 
-1. Configure the [**primary** node](#configure-primary-node).
-1. Configure the [**secondary** node](#configure-secondary-node).
+1. Configure the [**primary** site](#configure-primary-site).
+1. Configure the [**secondary** site](#configure-secondary-site).
 1. Verify Docker Registry [replication](#verify-replication).
 
-### Configure **primary** node
+### Configure **primary** site
 
 Make sure that you have Container Registry set up and working on
-the **primary** node before following the next steps.
+the **primary** site before following the next steps.
 
 We need to make Docker Registry send notification events to the
-**primary** node.
+**primary** site.
 
 1. SSH into your GitLab **primary** server and login as root:
 
@@ -85,27 +85,29 @@ We need to make Docker Registry send notification events to the
    gitlab-ctl reconfigure
    ```
 
-### Configure **secondary** node
+### Configure **secondary** site
 
 Make sure you have Container Registry set up and working on
-the **secondary** node before following the next steps.
+the **secondary** site before following the next steps.
 
-The following steps should be done on each **secondary** node you're
+The following steps should be done on each **secondary** site you're
 expecting to see the Docker images replicated.
 
-Because we need to allow the **secondary** node to communicate securely with
-the **primary** node Container Registry, we need to have a single key
-pair for all the nodes. The **secondary** node will use this key to
+Because we need to allow the **secondary** site to communicate securely with
+the **primary** site Container Registry, we need to have a single key
+pair for all the sites. The **secondary** site will use this key to
 generate a short-lived JWT that is pull-only-capable to access the
-**primary** node Container Registry.
+**primary** site Container Registry.
 
-1. SSH into the **secondary** node and login as the `root` user:
+For each application node on the **secondary** site: 
+
+1. SSH into the node and login as the `root` user:
 
    ```shell
    sudo -i
    ```
 
-1. Copy `/var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key` from the **primary** to the **secondary** node.
+1. Copy `/var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key` from the **primary** to the node.
 
 1. Edit `/etc/gitlab/gitlab.rb`:
 
@@ -114,7 +116,7 @@ generate a short-lived JWT that is pull-only-capable to access the
    gitlab_rails['geo_registry_replication_primary_api_url'] = 'https://primary.example.com:5050/' # Primary registry address, it will be used by the secondary node to directly communicate to primary registry
    ```
 
-1. Reconfigure the **secondary** node for the change to take effect:
+1. Reconfigure the node for the change to take effect:
 
    ```shell
    gitlab-ctl reconfigure
@@ -123,6 +125,6 @@ generate a short-lived JWT that is pull-only-capable to access the
 ### Verify replication
 
 To verify Container Registry replication is working, go to **Admin Area > Geo**
-(`/admin/geo/nodes`) on the **secondary** node.
+(`/admin/geo/nodes`) on the **secondary** site.
 The initial replication, or "backfill", will probably still be in progress.
-You can monitor the synchronization process on each Geo node from the **primary** node's **Geo Nodes** dashboard in your browser.
+You can monitor the synchronization process on each Geo site from the **primary** site's **Geo Nodes** dashboard in your browser.
diff --git a/ee/app/finders/ee/issues_finder/params.rb b/ee/app/finders/ee/issues_finder/params.rb
index bfc26ac2513e5fd91c322898a0c2758286a8d58f..cbd020a475f33db5b8858604b03f5ad50f0bfdcd 100644
--- a/ee/app/finders/ee/issues_finder/params.rb
+++ b/ee/app/finders/ee/issues_finder/params.rb
@@ -19,7 +19,7 @@ def filter_by_any_epic?
       end
 
       def weights?
-        params[:weight].present? && params[:weight] != ::Issue::WEIGHT_ALL
+        params[:weight].present? && params[:weight].to_s.casecmp(::Issue::WEIGHT_ALL) != 0
       end
 
       def filter_by_no_weight?
diff --git a/ee/app/graphql/ee/resolvers/issues_resolver.rb b/ee/app/graphql/ee/resolvers/issues_resolver.rb
index 72e831716d2b46abaeb1a169e454414efea9181c..ed0ada5a4cc230e94375f87d5de4d01920feb9ea 100644
--- a/ee/app/graphql/ee/resolvers/issues_resolver.rb
+++ b/ee/app/graphql/ee/resolvers/issues_resolver.rb
@@ -7,13 +7,15 @@ module IssuesResolver
       extend ::Gitlab::Utils::Override
 
       prepended do
-        argument :iteration_id, ::GraphQL::ID_TYPE.to_list_type,
+        argument :iteration_id, [::GraphQL::ID_TYPE, null: true],
                  required: false,
                  description: 'Iterations applied to the issue.'
-
         argument :epic_id, GraphQL::STRING_TYPE,
                  required: false,
                  description: 'ID of an epic associated with the issues, "none" and "any" values are supported.'
+        argument :weight, GraphQL::STRING_TYPE,
+                 required: false,
+                 description: 'Weight applied to the issue, "none" and "any" values are supported.'
       end
 
       private
diff --git a/ee/app/graphql/ee/types/issues/negated_issue_filter_input_type.rb b/ee/app/graphql/ee/types/issues/negated_issue_filter_input_type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..40dd8615e305c8c5d257e115b9f6a3cecf6fa8ad
--- /dev/null
+++ b/ee/app/graphql/ee/types/issues/negated_issue_filter_input_type.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module EE
+  module Types
+    module Issues
+      module NegatedIssueFilterInputType
+        extend ActiveSupport::Concern
+
+        prepended do
+          argument :epic_id, GraphQL::STRING_TYPE,
+                   required: false,
+                   description: 'ID of an epic not associated with the issues.'
+          argument :weight, GraphQL::STRING_TYPE,
+                   required: false,
+                   description: 'Weight not applied to the issue.'
+        end
+      end
+    end
+  end
+end
diff --git a/ee/changelogs/unreleased/300115-support-negated-issue-filters-gql.yml b/ee/changelogs/unreleased/300115-support-negated-issue-filters-gql.yml
new file mode 100644
index 0000000000000000000000000000000000000000..13f7ce96b7fdfe24b9a5d33481296a0ad0b1a5b4
--- /dev/null
+++ b/ee/changelogs/unreleased/300115-support-negated-issue-filters-gql.yml
@@ -0,0 +1,5 @@
+---
+title: Support negated filtering of issues by epic_id and weight in GraphQL
+merge_request: 58154
+author:
+type: added
diff --git a/ee/spec/graphql/ee/resolvers/issues_resolver_spec.rb b/ee/spec/graphql/ee/resolvers/issues_resolver_spec.rb
index 558aee95d3381891564e108d0ea99ce074de6166..3f31a37e7067df636f684d15de0fe7e75c79abc9 100644
--- a/ee/spec/graphql/ee/resolvers/issues_resolver_spec.rb
+++ b/ee/spec/graphql/ee/resolvers/issues_resolver_spec.rb
@@ -11,36 +11,39 @@
 
   context "with a project" do
     describe '#resolve' do
+      let_it_be(:epic1) { create :epic, group: group }
+      let_it_be(:epic2) { create :epic, group: group }
+
+      let_it_be(:iteration1) { create(:iteration, group: group, start_date: 2.weeks.ago, due_date: 1.week.ago) }
+      let_it_be(:current_iteration) { create(:iteration, :started, group: group, start_date: Date.today, due_date: 1.day.from_now) }
+
+      let_it_be(:issue1) { create :issue, project: project, epic: epic1, iteration: iteration1 }
+      let_it_be(:issue2) { create :issue, project: project, epic: epic2, weight: 1 }
+      let_it_be(:issue3) { create :issue, project: project, weight: 3, iteration: current_iteration }
+      let_it_be(:issue4) { create :issue, :published, project: project }
+
       before do
         project.add_developer(current_user)
       end
 
       describe 'sorting' do
         context 'when sorting by weight' do
-          let_it_be(:weight_issue1) { create(:issue, project: project, weight: 5) }
-          let_it_be(:weight_issue2) { create(:issue, project: project, weight: nil) }
-          let_it_be(:weight_issue3) { create(:issue, project: project, weight: 1) }
-          let_it_be(:weight_issue4) { create(:issue, project: project, weight: nil) }
-
           it 'sorts issues ascending' do
-            expect(resolve_issues(sort: :weight_asc).to_a).to eq [weight_issue3, weight_issue1, weight_issue4, weight_issue2]
+            expect(resolve_issues(sort: :weight_asc).to_a).to eq [issue2, issue3, issue4, issue1]
           end
 
           it 'sorts issues descending' do
-            expect(resolve_issues(sort: :weight_desc).to_a).to eq [weight_issue1, weight_issue3, weight_issue4, weight_issue2]
+            expect(resolve_issues(sort: :weight_desc).to_a).to eq [issue3, issue2, issue4, issue1]
           end
         end
 
         context 'when sorting by published' do
-          let_it_be(:not_published) { create(:issue, project: project) }
-          let_it_be(:published) { create(:issue, :published, project: project) }
-
           it 'sorts issues ascending' do
-            expect(resolve_issues(sort: :published_asc).to_a).to eq [not_published, published]
+            expect(resolve_issues(sort: :published_asc).to_a).to eq [issue3, issue2, issue1, issue4]
           end
 
           it 'sorts issues descending' do
-            expect(resolve_issues(sort: :published_desc).to_a).to eq [published, not_published]
+            expect(resolve_issues(sort: :published_desc).to_a).to eq [issue4, issue3, issue2, issue1]
           end
         end
 
@@ -64,32 +67,56 @@
       end
 
       describe 'filtering by iteration' do
-        let_it_be(:iteration1) { create(:iteration, group: group) }
-        let_it_be(:issue_with_iteration) { create(:issue, project: project, iteration: iteration1) }
-        let_it_be(:issue_without_iteration) { create(:issue, project: project) }
-
         it 'returns issues with iteration' do
-          expect(resolve_issues(iteration_id: [iteration1.id])).to contain_exactly(issue_with_iteration)
+          expect(resolve_issues(iteration_id: [iteration1.id.to_s])).to contain_exactly(issue1)
         end
       end
 
       describe 'filter by epic' do
-        let_it_be(:epic) { create :epic, group: group }
-        let_it_be(:epic2) { create :epic, group: group }
-        let_it_be(:issue1) { create :issue, project: project, epic: epic }
-        let_it_be(:issue2) { create :issue, project: project, epic: epic2 }
-        let_it_be(:issue3) { create :issue, project: project }
-
         it 'returns issues without epic when epic_id is "none"' do
-          expect(resolve_issues(epic_id: 'none')).to match_array([issue3])
+          expect(resolve_issues(epic_id: 'none')).to contain_exactly(issue4, issue3)
         end
 
         it 'returns issues with any epic when epic_id is "any"' do
-          expect(resolve_issues(epic_id: 'any')).to match_array([issue1, issue2])
+          expect(resolve_issues(epic_id: 'any')).to contain_exactly(issue1, issue2)
         end
 
         it 'returns issues with any epic when epic_id is specific' do
-          expect(resolve_issues(epic_id: epic.id)).to match_array([issue1])
+          expect(resolve_issues(epic_id: epic1.id.to_s)).to contain_exactly(issue1)
+        end
+      end
+
+      describe 'filter by weight' do
+        context 'when filtering by any weight' do
+          it 'only returns issues that have a weight assigned' do
+            expect(resolve_issues(weight: 'any')).to contain_exactly(issue2, issue3)
+          end
+        end
+
+        context 'when filtering by no weight' do
+          it 'only returns issues that have no weight assigned' do
+            expect(resolve_issues(weight: 'none')).to contain_exactly(issue1, issue4)
+          end
+        end
+
+        context 'when filtering by specific weight' do
+          it 'only returns issues that have the specified weight assigned' do
+            expect(resolve_issues(weight: '3')).to contain_exactly(issue3)
+          end
+        end
+      end
+
+      describe 'filtering by negated params' do
+        describe 'filter by negated epic' do
+          it 'returns issues without the specified epic_id' do
+            expect(resolve_issues(not: { epic_id: epic2.id.to_s })).to contain_exactly(issue1, issue3, issue4)
+          end
+        end
+
+        describe 'filtering by negated weight' do
+          it 'only returns issues that do not have the specified weight assigned' do
+            expect(resolve_issues(not: { weight: '3' })).to contain_exactly(issue1, issue2, issue4)
+          end
         end
       end
     end
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index b794ab626bfb88060cd24be158542a9a9df8ed56..a2aac857bf5f0cf7b56b6a16b53eedce00ca05ba 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -49,6 +49,13 @@
           let(:expected_issuables) { [issue3, issue4] }
         end
 
+        context 'when assignee_id does not exist' do
+          it_behaves_like 'assignee NOT ID filter' do
+            let(:params) { { not: { assignee_id: -100 } } }
+            let(:expected_issuables) { [issue1, issue2, issue3, issue4, issue5] }
+          end
+        end
+
         context 'filter by username' do
           let_it_be(:user3) { create(:user) }
 
@@ -71,6 +78,17 @@
             let(:params) { { not: { assignee_username: [user.username, user2.username] } } }
             let(:expected_issuables) { [issue3, issue4] }
           end
+
+          context 'when assignee_username does not exist' do
+            it_behaves_like 'assignee NOT username filter' do
+              before do
+                issue2.assignees = [user2]
+              end
+
+              let(:params) { { not: { assignee_username: 'non_existent_username' } } }
+              let(:expected_issuables) { [issue1, issue2, issue3, issue4, issue5] }
+            end
+          end
         end
 
         it_behaves_like 'no assignee filter' do
diff --git a/spec/graphql/resolvers/issue_status_counts_resolver_spec.rb b/spec/graphql/resolvers/issue_status_counts_resolver_spec.rb
index decc3569d6cdc2ff9100568a430e2fcf8f41c99a..3fbd9bd2368e96fbb24c2132baadde83efb10a07 100644
--- a/spec/graphql/resolvers/issue_status_counts_resolver_spec.rb
+++ b/spec/graphql/resolvers/issue_status_counts_resolver_spec.rb
@@ -69,6 +69,14 @@
       expect(result.closed).to eq 1
     end
 
+    context 'when both assignee_username and assignee_usernames are provided' do
+      it 'raises a mutually exclusive filter error' do
+        expect do
+          resolve_issue_status_counts(assignee_usernames: [current_user.username], assignee_username: current_user.username)
+        end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, 'only one of [assigneeUsernames, assigneeUsername] arguments is allowed at the same time.')
+      end
+    end
+
     private
 
     def resolve_issue_status_counts(args = {}, context = { current_user: current_user })
diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb
index 6e802bf7d255f0c527d7bdb6f056dd206f5c958b..7c2ceb5006645f2dc13ecf365c652e364fdccd4a 100644
--- a/spec/graphql/resolvers/issues_resolver_spec.rb
+++ b/spec/graphql/resolvers/issues_resolver_spec.rb
@@ -46,10 +46,6 @@
         expect(resolve_issues(milestone_title: [milestone.title])).to contain_exactly(issue1)
       end
 
-      it 'filters by assignee_username' do
-        expect(resolve_issues(assignee_username: [assignee.username])).to contain_exactly(issue2)
-      end
-
       it 'filters by two assignees' do
         assignee2 = create(:user)
         issue2.update!(assignees: [assignee, assignee2])
@@ -78,6 +74,24 @@
         expect(resolve_issues(label_name: [label1.title, label2.title])).to contain_exactly(issue2)
       end
 
+      describe 'filters by assignee_username' do
+        it 'filters by assignee_username' do
+          expect(resolve_issues(assignee_username: [assignee.username])).to contain_exactly(issue2)
+        end
+
+        it 'filters by assignee_usernames' do
+          expect(resolve_issues(assignee_usernames: [assignee.username])).to contain_exactly(issue2)
+        end
+
+        context 'when both assignee_username and assignee_usernames are provided' do
+          it 'raises a mutually exclusive filter error' do
+            expect do
+              resolve_issues(assignee_usernames: [assignee.username], assignee_username: assignee.username)
+            end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, 'only one of [assigneeUsernames, assigneeUsername] arguments is allowed at the same time.')
+          end
+        end
+      end
+
       describe 'filters by created_at' do
         it 'filters by created_before' do
           expect(resolve_issues(created_before: 2.hours.ago)).to contain_exactly(issue1)
@@ -144,6 +158,29 @@
         end
       end
 
+      describe 'filters by negated params' do
+        it 'returns issues without the specified iids' do
+          expect(resolve_issues(not: { iids: [issue1.iid] })).to contain_exactly(issue2)
+        end
+
+        it 'returns issues without the specified label names' do
+          expect(resolve_issues(not: { label_name: [label1.title] })).to be_empty
+          expect(resolve_issues(not: { label_name: [label2.title] })).to contain_exactly(issue1)
+        end
+
+        it 'returns issues without the specified milestone' do
+          expect(resolve_issues(not: { milestone_title: [milestone.title] })).to contain_exactly(issue2)
+        end
+
+        it 'returns issues without the specified assignee_usernames' do
+          expect(resolve_issues(not: { assignee_usernames: [assignee.username] })).to contain_exactly(issue1)
+        end
+
+        it 'returns issues without the specified assignee_id' do
+          expect(resolve_issues(not: { assignee_id: [assignee.id] })).to contain_exactly(issue1)
+        end
+      end
+
       describe 'sorting' do
         context 'when sorting by created' do
           it 'sorts issues ascending' do
diff --git a/spec/models/pages/lookup_path_spec.rb b/spec/models/pages/lookup_path_spec.rb
index 9e65635da91b296266c7d78be38d434eb3bd4966..17b1193b8adc30ccd2013f7f4fd88016acf67f3e 100644
--- a/spec/models/pages/lookup_path_spec.rb
+++ b/spec/models/pages/lookup_path_spec.rb
@@ -136,14 +136,6 @@
             )
           end
         end
-
-        context 'when pages_serve_from_migrated_zip feature flag is disabled' do
-          before do
-            stub_feature_flags(pages_serve_from_migrated_zip: false)
-          end
-
-          include_examples 'uses disk storage'
-        end
       end
     end
   end
diff --git a/spec/requests/api/graphql/project/issues_spec.rb b/spec/requests/api/graphql/project/issues_spec.rb
index f93822825e0853f3671d81e95196dd092ffa0670..dd9d44136e56b6f845ef0d5c19979da47037161d 100644
--- a/spec/requests/api/graphql/project/issues_spec.rb
+++ b/spec/requests/api/graphql/project/issues_spec.rb
@@ -12,6 +12,7 @@
   let_it_be(:issues, reload: true) { [issue_a, issue_b] }
 
   let(:issues_data) { graphql_data['project']['issues']['edges'] }
+  let(:issue_filter_params) { {} }
 
   let(:fields) do
     <<~QUERY
@@ -27,7 +28,7 @@
     graphql_query_for(
       'project',
       { 'fullPath' => project.full_path },
-      query_graphql_field('issues', {}, fields)
+      query_graphql_field('issues', issue_filter_params, fields)
     )
   end
 
@@ -50,6 +51,16 @@
     expect(issues_data[1]['node']['discussionLocked']).to eq(true)
   end
 
+  context 'when both assignee_username filters are provided' do
+    let(:issue_filter_params) { { assignee_username: current_user.username, assignee_usernames: [current_user.username] } }
+
+    it 'returns a mutually exclusive param error' do
+      post_graphql(query, current_user: current_user)
+
+      expect_graphql_errors_to_include('only one of [assigneeUsernames, assigneeUsername] arguments is allowed at the same time.')
+    end
+  end
+
   context 'when limiting the number of results' do
     let(:query) do
       <<~GQL