diff --git a/.gitlab/ci/qa-common/main.gitlab-ci.yml b/.gitlab/ci/qa-common/main.gitlab-ci.yml
index e2e4bc55cb566e9d0a1a8df52580e462c2b5a66c..85f0142c77d2ea76a6d76ec958cb992092798510 100644
--- a/.gitlab/ci/qa-common/main.gitlab-ci.yml
+++ b/.gitlab/ci/qa-common/main.gitlab-ci.yml
@@ -63,14 +63,7 @@ stages:
 .update-script:
   script:
     - !reference [.bundle-prefix]
-    - export QA_COMMAND="$BUNDLE_PREFIX gitlab-qa Test::Omnibus::UpdateFromPrevious $RELEASE $GITLAB_SEMVER_VERSION $UPDATE_TYPE $UPDATE_FROM_EDITION -- $QA_RSPEC_TAGS $RSPEC_REPORT_OPTS"
-    - echo "Running - '$QA_COMMAND'"
-    - eval "$QA_COMMAND"
-
-.update-with-ai-components-script:
-  script:
-    - !reference [.bundle-prefix]
-    - export QA_COMMAND="$BUNDLE_PREFIX gitlab-qa Test::Omnibus::UpdateFromPreviousAi $RELEASE $GITLAB_SEMVER_VERSION $UPDATE_TYPE $UPDATE_FROM_EDITION -- $QA_RSPEC_TAGS $RSPEC_REPORT_OPTS"
+    - export QA_COMMAND="$BUNDLE_PREFIX gitlab-qa ${QA_SCENARIO:-Test::Omnibus::UpdateFromPrevious} $RELEASE $GITLAB_SEMVER_VERSION $UPDATE_TYPE $UPDATE_FROM_EDITION -- $QA_RSPEC_TAGS $RSPEC_REPORT_OPTS"
     - echo "Running - '$QA_COMMAND'"
     - eval "$QA_COMMAND"
 
diff --git a/.gitlab/ci/qa-common/rules.gitlab-ci.yml b/.gitlab/ci/qa-common/rules.gitlab-ci.yml
index 6624d4548fd2219fa8ef14a6dc96d4737110e068..82d21a1a3f1a955642d41e02b495d95849c77f32 100644
--- a/.gitlab/ci/qa-common/rules.gitlab-ci.yml
+++ b/.gitlab/ci/qa-common/rules.gitlab-ci.yml
@@ -91,6 +91,17 @@ include:
     - !reference [.qa:rules:code-merge-request, rules]
     - *default-branch
 
+.rules:test:update-patch:
+  rules:
+    # skip upgrade jobs if gitlab version is not in semver compatible format
+    # these jobs need gitlab version because we can't reliably detect it from just the image
+    - if: $GITLAB_SEMVER_VERSION !~ /^\d+\.\d+\.\d+/
+      when: never
+    # update jobs are only relevant in testing app updates that can be affected by code changes only
+    # by checking code patterns, skip running job on changes that can't affect the outcome
+    # subset of update jobs only applicable for backport MRs to verify patch upgrade paths
+    - !reference [.qa:rules:code-merge-request-targeting-stable-branch, rules]
+
 .rules:test:never-schedule-pipeline:
   rules:
     - <<: *if-schedule-pipeline
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index 507a27768a73231198dd2570b1d16a06e96446f1..e6381383a66387c8de607e7a4435daccd37608d3 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -1669,6 +1669,11 @@
     - <<: *if-merge-request
       changes: *code-patterns
 
+.qa:rules:code-merge-request-targeting-stable-branch:
+  rules:
+    - <<: *if-merge-request-targeting-stable-branch
+      changes: *code-patterns
+
 .qa:rules:code-merge-request-allowed-to-fail:
   rules:
     - <<: *if-merge-request
diff --git a/.gitlab/ci/test-on-omnibus-nightly/main.gitlab-ci.yml b/.gitlab/ci/test-on-omnibus-nightly/main.gitlab-ci.yml
index 7ee700b1ab077bd34ee82e75b3d4700eb6774adf..8e34ea35d472452c1a445b8c2dfe96f814c1b896 100644
--- a/.gitlab/ci/test-on-omnibus-nightly/main.gitlab-ci.yml
+++ b/.gitlab/ci/test-on-omnibus-nightly/main.gitlab-ci.yml
@@ -187,9 +187,10 @@ gitlab-pages:
 update-minor-ee-ai-components:
   extends:
     - .qa
-    - .update-with-ai-components-script
+    - .update-script
     - .with-ignored-runtime-data
   variables:
+    QA_SCENARIO: Test::Omnibus::UpdateFromPreviousAi
     UPDATE_TYPE: minor
     UPDATE_FROM_EDITION: ee
     QA_RSPEC_TAGS: --tag ai_gateway
diff --git a/.gitlab/ci/test-on-omnibus/main.gitlab-ci.yml b/.gitlab/ci/test-on-omnibus/main.gitlab-ci.yml
index c7a1c4100fe3a39338a48b812dc39232ba72deaa..5e7e173ab3d4830180ccced08c300883951bdf54 100644
--- a/.gitlab/ci/test-on-omnibus/main.gitlab-ci.yml
+++ b/.gitlab/ci/test-on-omnibus/main.gitlab-ci.yml
@@ -400,6 +400,28 @@ update-major:
     - !reference [.rules:test:dependency-update-never, rules]
     - !reference [.rules:test:update, rules]
 
+update-patch:
+  extends:
+    - .qa
+    - .update-script
+  variables:
+    UPDATE_TYPE: patch
+    QA_RSPEC_TAGS: --tag health_check
+  rules:
+    - !reference [.rules:test:dependency-update-never, rules]
+    - !reference [.rules:test:update-patch, rules]
+
+update-from-patch-to-stable:
+  extends:
+    - .qa
+    - .update-script
+  variables:
+    QA_RSPEC_TAGS: --tag health_check
+    QA_SCENARIO: Test::Omnibus::UpdateToNext
+  rules:
+    - !reference [.rules:test:dependency-update-never, rules]
+    - !reference [.rules:test:update-patch, rules]
+
 update-ee-to-ce:
   extends:
     - .qa