Skip to content

feat (intelligent-assistant): add optional OKP flavour for Intelligent Assistant [RHIDP-16103] - #3370

Merged
openshift-merge-bot[bot] merged 3 commits into
redhat-developer:mainfrom
maysunfaisal:okp-integration-1
Sep 28, 2026
Merged

openshift-merge-bot[bot] merged 3 commits into
redhat-developer:mainfrom
maysunfaisal:okp-integration-1

Conversation

@maysunfaisal

@maysunfaisal maysunfaisal commented Aug 18, 2026 •

Copy link
Copy Markdown
Member

Description

Add Offline Knowledge Portal (OKP) as an optional add-on flavour for Intelligent Assistant, building on the generic flavour templating and plugin-dependency infrastructure introduced by #3477.

  • Keep the default intelligent-assistant experience unchanged and enabled without OKP.
  • Add an explicit intelligent-assistant-okp flavour that:
    • adds the okp dependency to the Intelligent Assistant backend plugin;
    • creates the OKP Deployment and Service;
    • selects the OKP-enabled LCORE configuration; and
    • adds the LCORE NetworkPolicy required for HTTP access to OKP.
  • On OpenShift, create an edge-terminated OKP Route and automatically configure OKP_SERVICE_URL with its HTTP URL.
  • On Kubernetes, leave registry authentication, Ingress, TLS, and the public OKP_SERVICE_URL to the user because the Operator does not manage Ingress.
  • Apply unmentioned default flavours first and explicitly configured flavours in CR declaration order, ensuring add-on patches deterministically override their base flavour.
  • Use the intelligent-assistant-okp-* resource prefix consistently for the OKP Deployment, Service, and Route.
  • Document OpenShift and Kubernetes enablement, including optional HTTPS with a private CA.
  • Regenerate the RHDH bundle and installer manifests and add integration coverage for both IA-only and IA-with-OKP configurations.

OKP remains disabled by default. The OKP image is large, so explicitly enabling it can make the first installation significantly slower while the image is downloaded.

Which issue(s) does this PR fix or relate to

https://redhat.atlassian.net/browse/RHIDP-16103

PR acceptance criteria

  • Tests
  • Documentation

How to test changes / Special notes to the reviewer

Intelligent Assistant without OKP

Deploy a Backstage CR with only the base flavour:

spec:
  flavours:
    - name: intelligent-assistant
      enabled: true

Verify that RHDH and LCORE become ready and that no intelligent-assistant-okp-* resources, OKP_SERVICE_URL, or OKP RAG configuration are present.

OpenShift with OKP

Enable both flavours:

spec:
  flavours:
    - name: intelligent-assistant
      enabled: true
    - name: intelligent-assistant-okp
      enabled: true

Verify:

oc get deployments,services,routes -n <namespace> | grep intelligent-assistant-okp
oc get deployment backstage-<backstage-name> -n <namespace> \
  -o jsonpath='{.spec.template.spec.containers[?(@.name=="lightspeed-core")].env}'

Confirm that the OKP Deployment, Service, and Route are ready, OKP_SERVICE_URL uses the generated HTTP Route, LCORE is ready, and Intelligent Assistant returns clickable OKP citations.

Optional HTTPS configuration for a private OpenShift router CA is documented in docs/intelligent-assistant-okp-openshift.md.

Kubernetes with OKP

Enable both flavours, configure registry.redhat.io authentication, create an Ingress, and inject its public URL as OKP_SERVICE_URL. Follow docs/intelligent-assistant-okp-kubernetes.md for the complete HTTP or HTTPS setup.

Confirm that the OKP Deployment and Service are ready, LCORE can reach the configured Ingress, and citation links are reachable from the browser.

Validation performed

  • make lint
  • make local-dynamic-plugins && make test
  • make integration-test ARGS='--focus "create default rhdh"'
  • make gosec
  • make bundles build-installers
  • OpenShift: IA-only, OKP over HTTP, and OKP over HTTPS with a private router CA
  • Kind on AMD64 Linux: IA-only and OKP with user-managed HTTP and HTTPS Ingress

@maysunfaisal
maysunfaisal requested review from a team as code owners August 18, 2026 19:16
@codecov

codecov Bot commented Aug 18, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.11765% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.07%. Comparing base (b0d6a0d) to head (78519cd).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
pkg/model/flavour.go 94.11% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3370      +/-   ##
==========================================
+ Coverage   59.84%   60.07%   +0.23%     
==========================================
  Files          51       51              
  Lines        3586     3612      +26     
==========================================
+ Hits         2146     2170      +24     
- Misses       1246     1247       +1     
- Partials      194      195       +1     
Flag Coverage Δ
nightly ?
unittests 60.07% <94.11%> (+0.23%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
pkg/model/flavour.go 81.25% <94.11%> (+5.32%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@maysunfaisal
maysunfaisal force-pushed the okp-integration-1 branch 2 times, most recently from 51db81c to 3bbec01 Compare August 18, 2026 20:51
Comment thread docs/lightspeed.md Outdated
Comment thread internal/controller/okp.go Outdated
@maysunfaisal

Copy link
Copy Markdown
Member Author

Corresponding rhdh-chart PR redhat-developer/rhdh-chart#500

maysunfaisal added a commit to maysunfaisal/rhdh-operator that referenced this pull request Aug 21, 2026
Move the OKP (Offline Knowledge Portal) Deployment, Service, and Route
out of imperative Go construction in internal/controller/okp.go and into
the lightspeed flavour as YAML manifests, so OKP is described like every
other flavour resource and its image string rides in the bundle
ConfigMap (visible to midstream image pinning). Addresses PR redhat-developer#3370
review comment: "should OKP be in the flavour YAML rather than Go?".

Each OKP object is a separately registered model key (OkpDeploymentKey,
OkpServiceKey, OkpRouteKey) with its own MergeFunc, and stays gated to
OpenShift in addToModel. Flavour gating is implicit (files live only in
flavours/lightspeed/). The runtime behavior is unchanged: same objects,
same OpenShift-only gating, same OKP_SERVICE_URL injection into the
lightspeed-core sidecar before apply (no dual ReplicaSet).

Remove applyOkpResources; OKP now flows through the normal
applyObjects(GetRuntimeObjects()) SSA path. Keep prepareOkpEnvVar and
prepareOkpConfig as controller wiring. Regenerate bundle manifests and
dist/rhdh/install.yaml.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
maysunfaisal added a commit to maysunfaisal/rhdh-operator that referenced this pull request Aug 21, 2026
Move the OKP (Offline Knowledge Portal) Deployment, Service, and Route
out of imperative Go construction in internal/controller/okp.go and into
the lightspeed flavour as YAML manifests, so OKP is described like every
other flavour resource and its image string rides in the bundle
ConfigMap (visible to midstream image pinning). Addresses PR redhat-developer#3370
review comment: "should OKP be in the flavour YAML rather than Go?".

Each OKP object is a separately registered model key (OkpDeploymentKey,
OkpServiceKey, OkpRouteKey) with its own MergeFunc, and stays gated to
OpenShift in addToModel. Flavour gating is implicit (files live only in
flavours/lightspeed/). The runtime behavior is unchanged: same objects,
same OpenShift-only gating, same OKP_SERVICE_URL injection into the
lightspeed-core sidecar before apply (no dual ReplicaSet).

Remove applyOkpResources; OKP now flows through the normal
applyObjects(GetRuntimeObjects()) SSA path. Keep prepareOkpEnvVar and
prepareOkpConfig as controller wiring. Regenerate bundle manifests and
dist/rhdh/install.yaml.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@rm3l

rm3l commented Aug 24, 2026

Copy link
Copy Markdown
Member

/build-images

@github-actions

Copy link
Copy Markdown
Contributor

❌ Image build failed

See workflow run for details: https://github.com/redhat-developer/rhdh-operator/actions/runs/32705736214

Triggered by @rm3l

@rm3l

rm3l commented Aug 24, 2026

Copy link
Copy Markdown
Member

/build-images

@github-actions

Copy link
Copy Markdown
Contributor

❌ Image build failed

See workflow run for details: https://github.com/redhat-developer/rhdh-operator/actions/runs/32705962118

Triggered by @rm3l

maysunfaisal added a commit to maysunfaisal/rhdh-operator that referenced this pull request Aug 24, 2026
Move the OKP (Offline Knowledge Portal) Deployment, Service, and Route
out of imperative Go construction in internal/controller/okp.go and into
the lightspeed flavour as YAML manifests, so OKP is described like every
other flavour resource and its image string rides in the bundle
ConfigMap (visible to midstream image pinning). Addresses PR redhat-developer#3370
review comment: "should OKP be in the flavour YAML rather than Go?".

Each OKP object is a separately registered model key (OkpDeploymentKey,
OkpServiceKey, OkpRouteKey) with its own MergeFunc, and stays gated to
OpenShift in addToModel. Flavour gating is implicit (files live only in
flavours/lightspeed/). The runtime behavior is unchanged: same objects,
same OpenShift-only gating, same OKP_SERVICE_URL injection into the
lightspeed-core sidecar before apply (no dual ReplicaSet).

Remove applyOkpResources; OKP now flows through the normal
applyObjects(GetRuntimeObjects()) SSA path. Keep prepareOkpEnvVar and
prepareOkpConfig as controller wiring. Regenerate bundle manifests and
dist/rhdh/install.yaml.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@maysunfaisal

Copy link
Copy Markdown
Member Author

/build-images

@github-actions

Copy link
Copy Markdown
Contributor

✅ PR images built successfully!

Images are available for testing:

  1. Operator: quay.io/rhdh-community/operator:2.0.0-pr-3370-9726670
  2. Bundle: quay.io/rhdh-community/operator-bundle:2.0.0-pr-3370-9726670
  3. Catalog: quay.io/rhdh-community/operator-catalog:2.0.0-pr-3370-9726670

Also available with PR number tag:

  • quay.io/rhdh-community/operator:2.0.0-pr-3370
  • quay.io/rhdh-community/operator-bundle:2.0.0-pr-3370
  • quay.io/rhdh-community/operator-catalog:2.0.0-pr-3370

Triggered by @maysunfaisal

@Jdubrick Jdubrick left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a general question as well: will OKP get cleaned up if someone disables the lightspeed flavour?

Comment thread config/profile/rhdh/default-config/flavours/lightspeed/dynamic-plugins.yaml Outdated
Comment thread docs/lightspeed.md Outdated
Comment thread docs/lightspeed.md Outdated
@rm3l

rm3l commented Aug 26, 2026

Copy link
Copy Markdown
Member

/cc @gazarenkov

@openshift-ci
openshift-ci Bot requested a review from gazarenkov August 26, 2026 13:13
@maysunfaisal

Copy link
Copy Markdown
Member Author

/build-images

@github-actions

Copy link
Copy Markdown
Contributor

✅ PR images built successfully!

Images are available for testing:

  1. Operator: quay.io/rhdh-community/operator:2.0.0-pr-3370-ec0b6e3
  2. Bundle: quay.io/rhdh-community/operator-bundle:2.0.0-pr-3370-ec0b6e3
  3. Catalog: quay.io/rhdh-community/operator-catalog:2.0.0-pr-3370-ec0b6e3

Also available with PR number tag:

  • quay.io/rhdh-community/operator:2.0.0-pr-3370
  • quay.io/rhdh-community/operator-bundle:2.0.0-pr-3370
  • quay.io/rhdh-community/operator-catalog:2.0.0-pr-3370

Triggered by @maysunfaisal

@gazarenkov gazarenkov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To add the additional resources needed for your plugin please use Plugin dependencies feature instead.

You can see how it implemented in orchestrator flavour as well (it uses sonataflow dependencies).

@github-actions

Copy link
Copy Markdown
Contributor

✅ PR images built and pushed successfully!

Images are available for testing (expires in 7 days):

Image Full tag PR tag
Operator quay.io/rhdh-community/operator:2.1.0-pr-3370-fff2b29 quay.io/rhdh-community/operator:2.1.0-pr-3370
Bundle quay.io/rhdh-community/operator-bundle:2.1.0-pr-3370-fff2b29 quay.io/rhdh-community/operator-bundle:2.1.0-pr-3370
Catalog quay.io/rhdh-community/operator-catalog:2.1.0-pr-3370-fff2b29 quay.io/rhdh-community/operator-catalog:2.1.0-pr-3370

@maysunfaisal

maysunfaisal commented Sep 23, 2026 •

Copy link
Copy Markdown
Member Author

@rm3l @gazarenkov the PR has been rebased, pls take a look. thank you!

@Fortune-Ndlovu

Copy link
Copy Markdown
Member

/agentic_review

@rhdh-qodo-merge

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (2) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Portal pods fail on standard Kubernetes 🐞 Bug ≡ Correctness
Description
The newly unconditional ref: okp dependency activates an OKP Deployment whose container sets
runAsNonRoot: true, even though the image declares the non-numeric user default and the manifest
provides no numeric runAsUser. On Kubernetes, enabling the add-on causes the kubelet to reject the
container because it cannot verify the named user as non-root, leaving the portal pod unavailable
until an administrator patches the generated Deployment.
Code

config/profile/rhdh/default-config/flavours/intelligent-assistant-okp/dynamic-plugins.yaml[R8-11]

+      - package: ref://red-hat-developer-hub-backstage-plugin-intelligent-assistant-backend
+        enabled: true
+        dependencies:
+          - ref: okp
Relevance

●●● Strong

The guide explicitly documents Kubernetes rejection and requires a manual UID patch, confirming the
generated deployment can fail.

PR-#3477

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The added okp dependency brings the existing OKP Deployment into the Kubernetes add-on path, where
its security context enables runAsNonRoot without specifying a numeric UID. The Kubernetes
documentation identifies the image user as the named user default and prescribes a manual
runAsUser: 1001 patch for this exact rejection, confirming that the generated default can fail to
start.

config/profile/rhdh/default-config/flavours/intelligent-assistant-okp/dynamic-plugins.yaml[7-11]
config/profile/rhdh/plugin-deps/okp.yaml[23-29]
docs/intelligent-assistant-okp-kubernetes.md[45-52]
config/profile/rhdh/default-config/flavours/intelligent-assistant-okp/dynamic-plugins.yaml[1-11]
config/profile/rhdh/plugin-deps/okp.yaml[21-32]
docs/intelligent-assistant-okp-kubernetes.md[34-52]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Enabling the new OKP flavour activates the `okp` dependency on Kubernetes. Its Deployment uses `runAsNonRoot: true` without a numeric `runAsUser`, despite the image declaring the named user `default`, so Kubernetes can reject the pod and require a manual post-creation patch.

## Fix Focus Areas
- config/profile/rhdh/default-config/flavours/intelligent-assistant-okp/dynamic-plugins.yaml[8-11]
- config/profile/rhdh/plugin-deps/okp.yaml[21-32]

## Recommended Fix
Provide a Kubernetes-specific OKP Deployment security context with `runAsUser: 1001` so the generated Deployment satisfies `runAsNonRoot`, while retaining an OpenShift-compatible variant that permits the cluster-assigned UID. Select the appropriate Deployment through the existing platform annotation mechanism, regenerate the bundle and installer manifests, and update the Kubernetes instructions to remove the manual workaround once the generated manifest is fixed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Question screening gets a broken prompt 🐞 Bug ≡ Correctness
Description
QUESTION_VALIDATOR_PROMPT_TEMPLATE is an f-string, but the changed $ {{ "{{" }}message{{ "}}" }}
expression is not processed by the Go templater because this ConfigMap source contains no .Rhdh
template reference. Python consequently renders its doubled braces as literals, producing `$ { "{"
}message{ "}" } rather than the required ${message}` placeholder, so enabled question validation
receives a malformed prompt instead of the user's question for both the base and OKP configurations.
Code

config/profile/rhdh/default-config/flavours/intelligent-assistant/configmap-files.yaml[439]

+    ${{ "{{" }}message{{ "}}" }}
Relevance

●●● Strong

The escaping change is deterministic and malformed when Go templating does not process the ConfigMap
content.

PR-#3477

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed placeholder is inside an f-string, while the renderer explicitly returns content
unchanged unless it contains a .Rhdh template reference; neither the base nor OKP ConfigMap file
contains such a reference. Therefore Go-template escaping never runs and Python alone interprets the
doubled braces.

config/profile/rhdh/default-config/flavours/intelligent-assistant/configmap-files.yaml[389-440]
config/profile/rhdh/default-config/flavours/intelligent-assistant-okp/configmap-files.yaml[1-167]
pkg/template/template.go[63-92]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

Issue description
The profile ConfigMap is not parsed as a Go template because it has no `.Rhdh` template expression. The newly added Go-template escape syntax is therefore passed to Python unchanged, where the f-string renders it into malformed literal text instead of the LCORE `${message}` placeholder.

Fix Focus Areas
- config/profile/rhdh/default-config/flavours/intelligent-assistant/configmap-files.yaml[389-440]
- pkg/template/template.go[63-92]

Recommended Fix
Replace the changed expression in the Python f-string with Python's direct brace escape, `${{message}}`, so evaluation emits the literal `${message}`. Add a regression test that exercises this ConfigMap content without a `.Rhdh` template expression and verifies the rendered Python template still contains the intended placeholder.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Users cannot tell where resources run 📘 Rule violation ✧ Quality
Description
The new OKP guides say that the Operator creates a Deployment, Service, Route, and NetworkPolicy
without stating that these objects are placed in the Backstage custom resource's namespace. This
matters when users configure registry credentials, Ingress backends, or verification commands across
namespaces, because the implementation assigns generated objects to backstage.Namespace.
Code

docs/intelligent-assistant-okp-openshift.md[R18-21]

+On OpenShift, enabling the add-on causes the Operator to:
+
+- Add the `okp` dependency to the Intelligent Assistant backend plugin.
+- Create the OKP Deployment, Service, and edge-terminated Route.
Relevance

●●● Strong

Recent documentation precedents accept clarifying that generated resources use the RHDH instance
namespace.

PR-#1551

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 5 requires documentation to identify the namespace when namespaced resource creation depends on
it. The guides describe the generated resources without the namespace rule, while the model assigns
plugin dependency and NetworkPolicy objects to the Backstage resource's namespace.

Rule 5: Document resource creation namespace when behaviorally relevant
docs/intelligent-assistant-okp-openshift.md[18-24]
docs/intelligent-assistant-okp-kubernetes.md[1-5]
docs/intelligent-assistant.md[76-78]
pkg/model/plugin_deps.go[42-53]
pkg/model/runtime.go[228-235]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The OKP documentation lists resources created by the Operator but does not explicitly state that they are created in the same namespace as the Backstage custom resource.

## Fix Focus Areas
- docs/intelligent-assistant-okp-openshift.md[18-24]
- docs/intelligent-assistant-okp-kubernetes.md[1-5]
- docs/intelligent-assistant.md[76-78]

## Recommended Fix
State explicitly in the platform-specific guides and overview that the Operator creates the OKP Deployment, Service, Route where applicable, and NetworkPolicy in the same namespace as the Backstage custom resource. Relate `$NAMESPACE` and `RHDH_NAMESPACE` directly to that namespace.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Invalid add-on mix breaks deployment 🐞 Bug ≡ Correctness
Description
The add-on Deployment patch introduces a lightspeed-core container with arguments but no image,
relying implicitly on the base Intelligent Assistant flavour to define the rest of that container.
When a custom resource explicitly disables the base flavour while enabling the add-on,
GetEnabledFlavours accepts the combination and reconciliation attempts to create an invalid
image-less container instead of rejecting the configuration.
Code

config/profile/rhdh/default-config/flavours/intelligent-assistant-okp/deployment.yaml[R7-10]

+        - name: lightspeed-core
+          args:
+            - "--config"
+            - "/app-root/lightspeed-stack-okp.yaml"
Relevance

●●● Strong

Explicit base-flavour dependency is documented, and missing validation creates an invalid image-less
container.

PR-#3477

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The add-on patch defines only arguments and an optional environment variable for lightspeed-core,
while the base flavour supplies its image and security context. GetEnabledFlavours independently
applies each explicit boolean without dependency validation, even though the added documentation
states that the add-on must not be enabled with the base explicitly disabled.

config/profile/rhdh/default-config/flavours/intelligent-assistant-okp/deployment.yaml[5-17]
config/profile/rhdh/default-config/flavours/intelligent-assistant/deployment.yaml[5-15]
pkg/model/flavour.go[49-67]
docs/intelligent-assistant.md[61-72]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The operator accepts the portal add-on while the base Intelligent Assistant flavour is explicitly disabled, then merges a partial `lightspeed-core` container without an image into the Deployment.

## Fix Focus Areas
- pkg/model/flavour.go[49-67]
- config/profile/rhdh/default-config/flavours/intelligent-assistant-okp/deployment.yaml[7-12]

## Recommended Fix
Validate flavour dependencies before returning enabled flavours. If `intelligent-assistant-okp` is enabled while `intelligent-assistant` is explicitly disabled, return a clear reconciliation validation error and add a unit test for that combination.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Long instance names block portal installs 🐞 Bug ≡ Correctness
Description
The renamed portal resources and selector labels concatenate the 26-character
intelligent-assistant-okp- prefix directly with the full custom-resource name. Names longer than
37 characters therefore produce selector label values beyond Kubernetes' 63-character limit, causing
API validation to reject the portal Deployment and Service even when the existing Backstage
resources remain valid.
Code

config/profile/rhdh/plugin-deps/okp.yaml[R13-17]

+      app.kubernetes.io/name: intelligent-assistant-okp-{{backstage-name}}
  template:
    metadata:
      labels:
-        app.kubernetes.io/name: lightspeed-okp-{{backstage-name}}
+        app.kubernetes.io/name: intelligent-assistant-okp-{{backstage-name}}
Relevance

●● Moderate

The length-limit risk is plausible, but no close historical precedent establishes acceptance of this
naming concern.

PR-#3477

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The canonical dependency manifest uses the newly lengthened value both as a selector label and pod
label, and ReadPluginDeps performs only literal full-name substitution without normalization or
truncation. The Service selector repeats the same value, so an oversized label prevents the
connected resource set from being admitted consistently.

config/profile/rhdh/plugin-deps/okp.yaml[10-17]
config/profile/rhdh/plugin-deps/okp.yaml[84-94]
pkg/model/plugin_deps.go[88-100]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The longer portal prefix is concatenated with the complete Backstage name in resource names and selector labels, exceeding Kubernetes label limits for otherwise usable instance names.

## Fix Focus Areas
- config/profile/rhdh/plugin-deps/okp.yaml[13-17]
- config/profile/rhdh/plugin-deps/okp.yaml[69-75]
- config/profile/rhdh/plugin-deps/okp.yaml[85-91]
- config/profile/rhdh/default-config/flavours/intelligent-assistant-okp/deployment.yaml[15-16]

## Recommended Fix
Generate one deterministic length-bounded portal name, preserving uniqueness with a hash suffix when truncation is required. Use that same value for Deployment and Service names, selectors, Route references, and the computed OpenShift URL, then add boundary-name integration coverage and regenerate generated manifests.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

6. Disabled add-on leaves workloads running 📘 Rule violation ≡ Correctness
Description
The reconciliation path applies only resources from currently enabled flavours and has no pruning
path for resources created by the intelligent-assistant-okp dependency. After a user disables the
add-on, its Deployment, Service, Route, NetworkPolicy, and generated ConfigMaps can remain active
until the entire Backstage resource is deleted.
Code

config/profile/rhdh/default-config/flavours/intelligent-assistant-okp/metadata.yaml[R2-3]

+# OKP is opt-in on both OpenShift and Kubernetes.
+enabledByDefault: false
Relevance

● Weak

The team previously rejected cleanup requests when optional resources remain after disabling a
feature.

PR-#2733

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 10 requires optional CR-managed resources to reconcile idempotently when enabled and disabled.
The new metadata makes OKP optional, while the controller applies only current desired objects and
plugin dependencies without pruning objects removed when the flavour is disabled.

Rule 10: Use idempotent create-or-update reconciliation for optional CR-managed resources
config/profile/rhdh/default-config/flavours/intelligent-assistant-okp/metadata.yaml[1-3]
config/profile/rhdh/default-config/flavours/intelligent-assistant-okp/dynamic-plugins.yaml[6-11]
internal/controller/backstage_controller.go[145-172]
internal/controller/plugin-deps.go[21-34]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Disabling the optional `intelligent-assistant-okp` flavour removes its resources from the desired model, but reconciliation does not delete resources previously created by the flavour.

## Fix Focus Areas
- internal/controller/backstage_controller.go[145-172]
- internal/controller/plugin-deps.go[21-34]
- integration_tests/rhdh-config_test.go[395-467]

## Recommended Fix
Track resources owned by enabled flavours and plugin dependencies, then delete previously managed OKP resources that are absent from the current desired state while ignoring `NotFound` errors. Add an integration test that enables OKP, reconciles, disables it, reconciles again, and verifies that its Deployment, Service, Route, NetworkPolicy, and generated ConfigMaps are absent.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
⚠️ Tickets: not configured — ticket URL found in PR but could not be fetched — check ticket provider credentials
✅ Compliance rules (platform): 14 rules
✅ Cross-repo context — repo relationships
  Explored: repo: redhat-developer/rhdh (sha: 29f3871a)
  Explored: repo: redhat-developer/rhdh-plugins (sha: fdee4c6d)
Review mode: 🧠 Deep: This broad, behavior-changing PR spans flavour ordering, Kubernetes/OpenShift resource generation, plugin dependencies, configuration templating, networking, generated manifests, and integration tests, creating many independent paths where subtle defects could be missed.
ⓘ  2 issues published inline · 6 in summary

Grey Divider

Tip of the day
💡 Did you know, you can choose which labels appear on a finding, and whether they show icons or text

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@Fortune-Ndlovu

Copy link
Copy Markdown
Member

@maysunfaisal PTAL at the QODO comments above, thanks!

Comment thread pkg/model/flavour.go Outdated
@openshift-ci openshift-ci Bot added the lgtm label Sep 24, 2026
Comment thread pkg/model/flavour.go Outdated
Comment thread docs/intelligent-assistant.md
Comment thread docs/intelligent-assistant.md Outdated
Comment thread config/profile/rhdh/plugin-deps/okp.yaml Outdated
Comment thread integration_tests/rhdh-config_test.go

@Fortune-Ndlovu Fortune-Ndlovu left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OpenShift E2E (reviewer testing)

Environment: api-ci-ln-ml0w6fb-76ef8.origin-ci-int-aws.dev.rhcloud.com, operator quay.io/rhdh-community/operator:2.1.0-pr-3370-fff2b29 via make deploy. Five Backstage instances in okp-e2e-* namespaces (default IA, IA-only, IA+OKP doc order, OKP-only, reversed flavour order).

Worked: Doc-order IA+OKP and OKP-only — OKP Route HTTP 200, correct lightspeed-core args with lightspeed-stack-okp.yaml when IA is listed before OKP (or OKP-only). Default / IA-only had no OKP workloads.

Issues (details in inline comments): Reversed flavour order; OKP resources not removed when flavour disabled; temporary lightspeed-core CrashLoop until OKP image/Solr ready.

@openshift-ci openshift-ci Bot removed the lgtm label Sep 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ PR images built and pushed successfully!

Images are available for testing (expires in 7 days):

Image Full tag PR tag
Operator quay.io/rhdh-community/operator:2.1.0-pr-3370-97cbd88 quay.io/rhdh-community/operator:2.1.0-pr-3370
Bundle quay.io/rhdh-community/operator-bundle:2.1.0-pr-3370-97cbd88 quay.io/rhdh-community/operator-bundle:2.1.0-pr-3370
Catalog quay.io/rhdh-community/operator-catalog:2.1.0-pr-3370-97cbd88 quay.io/rhdh-community/operator-catalog:2.1.0-pr-3370

@maysunfaisal

maysunfaisal commented Sep 24, 2026 •

Copy link
Copy Markdown
Member Author

OpenShift E2E (reviewer testing)

Environment: api-ci-ln-ml0w6fb-76ef8.origin-ci-int-aws.dev.rhcloud.com, operator quay.io/rhdh-community/operator:2.1.0-pr-3370-fff2b29 via make deploy. Five Backstage instances in okp-e2e-* namespaces (default IA, IA-only, IA+OKP doc order, OKP-only, reversed flavour order).

Worked: Doc-order IA+OKP and OKP-only — OKP Route HTTP 200, correct lightspeed-core args with lightspeed-stack-okp.yaml when IA is listed before OKP (or OKP-only). Default / IA-only had no OKP workloads.

Issues (details in inline comments): Reversed flavour order; OKP resources not removed when flavour disabled; temporary lightspeed-core CrashLoop until OKP image/Solr ready.

@Fortune-Ndlovu tested all 5 scenarios + a new scenario (Qodo review no 4) where OKP flavor is enabled but base flavor IA default flavor is explicitly disabled - introduced requires config where OKP flavor defines this:

enabledByDefault: false
requires:
  - intelligent-assistant

maysunfaisal and others added 3 commits September 24, 2026 16:31
Keep Intelligent Assistant enabled without OKP by default and provide an explicit OKP add-on flavour for OpenShift and Kubernetes. Add platform-specific documentation, generated manifests, and integration coverage.

Preserve deterministic flavour merge precedence by applying unmentioned defaults first and explicitly configured flavours in CR declaration order.

Co-authored-by: Codex <noreply@openai.com>
Rename the OKP Service and Route resources to use the Intelligent Assistant prefix, update generated manifests and integration coverage, and consolidate the OpenShift OKP guidance.

Co-authored-by: Codex <noreply@openai.com>
Refine flavour ordering and validation, align the generated manifests, and update Intelligent Assistant OKP documentation and tests.

Co-authored-by: Codex <noreply@openai.com>
@sonarqubecloud

Copy link
Copy Markdown

@maysunfaisal

maysunfaisal commented Sep 24, 2026 •

Copy link
Copy Markdown
Member Author

@gazarenkov @rm3l @Fortune-Ndlovu pls take a look, reviews addressed (all reviewers + all Qodo reviews from high to low) and rebased with main, thank you.

@github-actions

Copy link
Copy Markdown
Contributor

✅ PR images built and pushed successfully!

Images are available for testing (expires in 7 days):

Image Full tag PR tag
Operator quay.io/rhdh-community/operator:2.1.0-pr-3370-78519cd quay.io/rhdh-community/operator:2.1.0-pr-3370
Bundle quay.io/rhdh-community/operator-bundle:2.1.0-pr-3370-78519cd quay.io/rhdh-community/operator-bundle:2.1.0-pr-3370
Catalog quay.io/rhdh-community/operator-catalog:2.1.0-pr-3370-78519cd quay.io/rhdh-community/operator-catalog:2.1.0-pr-3370

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to https://github.com/redhat-developer/rhdh-chart/blob/main/charts/rhdh/templates/intelligent-assistant/okp-deployment.yaml#L74-L84, it would be recommended to add some readiness and liveness probes to the OKP deployment. But can be addressed later.

@openshift-ci openshift-ci Bot added the lgtm label Sep 28, 2026
@openshift-merge-bot
openshift-merge-bot Bot merged commit 33a0c87 into redhat-developer:main Sep 28, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants