Skip to content

Comments

docs: add Unleash feature flags documentation and deployment scripts#653

Draft
maskarb wants to merge 2 commits intoambient-code:mainfrom
maskarb:rhoai-47012-docs-unleash-feature-flags
Draft

docs: add Unleash feature flags documentation and deployment scripts#653
maskarb wants to merge 2 commits intoambient-code:mainfrom
maskarb:rhoai-47012-docs-unleash-feature-flags

Conversation

@maskarb
Copy link
Contributor

@maskarb maskarb commented Feb 18, 2026

Adds documentation for feature flag management with Unleash and deployment script for Kubernetes/OpenShift clusters. Updates Makefile with unleash deployment targets.

@github-actions

This comment has been minimized.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 19, 2026

Claude Code Review

Summary

This PR adds Unleash feature flag infrastructure: deployment manifests for Unleash + PostgreSQL, updated backend/frontend deployments to consume the new credentials secret, Makefile targets, and documentation. The overall approach is sound, but there is one blocker that must be fixed before merge and several other issues worth addressing.


Issues by Severity

🚫 Blocker Issues

[B1] Production kustomization pointing to personal registry (components/manifests/overlays/production/kustomization.yaml)

The PR accidentally replaces quay.io/ambient_code/ with quay.io/mskarbek/ for four production images (backend, claude_runner, frontend, operator, state_sync). It also removes the vteam_state_sync override entry. If merged, this would redirect all production deployments to a personal registry that may not be accessible, breaking production.

- newName: quay.io/ambient_code/vteam_backend
+ newName: quay.io/mskarbek/vteam_backend   # ← personal registry, must revert

Fix: Revert all changes to components/manifests/overlays/production/kustomization.yaml entirely. This file should not be modified by this PR.


🔴 Critical Issues

[C1] Frontend env vars missing optional: true — breaks frontend if Unleash is not deployed (frontend-deployment.yaml)

The backend correctly marks all 6 Unleash env vars as optional: true. The frontend does NOT do this for UNLEASH_URL and UNLEASH_CLIENT_KEY. A missing optional: true means Kubernetes will refuse to start the pod with CreateContainerConfigError if the unleash-credentials secret doesn't exist. Since Unleash is an opt-in service (not required for core platform function), this creates a hard startup dependency that contradicts the documented "safe default when not configured" behavior.

# frontend-deployment.yaml — CURRENT (broken if secret absent)
- name: UNLEASH_URL
  valueFrom:
    secretKeyRef:
      name: unleash-credentials
      key: unleash-url
      # optional: true  ← MISSING

# REQUIRED fix
- name: UNLEASH_URL
  valueFrom:
    secretKeyRef:
      name: unleash-credentials
      key: unleash-url
      optional: true

Fix: Add optional: true to both UNLEASH_URL and UNLEASH_CLIENT_KEY in frontend-deployment.yaml.

[C2] Both Deployments missing securityContext (unleash-deployment.yaml)

Per CLAUDE.md security standards and the platform's own security-standards.md, all Job/Deployment pods must set SecurityContext with AllowPrivilegeEscalation: false and Capabilities.Drop: [ALL]. Neither the PostgreSQL container nor the Unleash container set these. This is especially important since Unleash is exposed via service and has network reachability within the cluster.

# Required on each container spec
securityContext:
  allowPrivilegeEscalation: false
  capabilities:
    drop: ["ALL"]

Fix: Add securityContext to both container specs in unleash-deployment.yaml. Note that the RHEL PostgreSQL image may need runAsUser set to match the image's expected UID — check the image documentation.


🟡 Major Issues

[M1] PostgreSQL image from registry.redhat.io will fail to pull in Kind/non-RH environments

registry.redhat.io/rhel10/postgresql-16:10.1 requires an authenticated Red Hat subscription. Kind clusters (used via make kind-up for local development) won't have pull secrets configured by default. New contributors following the dev quickstart will see ImagePullBackOff.

Additionally, the RHEL PostgreSQL image uses /var/lib/pgsql/data as its data directory (not /var/lib/postgresql/data/pgdata), so the PGDATA env var value will be wrong for this image — PostgreSQL initialization will fail silently or with a misleading error.

Consider using docker.io/library/postgres:16-alpine for broad compatibility. If the RHEL image is required (e.g., for OpenShift certification), add a note to the docs about the pull secret requirement and correct the PGDATA path.

[M2] Unleash added as mandatory base resource — all deployments now include it

Adding unleash-deployment.yaml to components/manifests/base/kustomization.yaml makes Unleash mandatory in every deployment (kind, dev, production). Users who don't want feature flags will still get a PostgreSQL + Unleash stack deployed. This also means the unleash-credentials secret becomes required in all environments (even if frontend env vars are fixed to optional: true, the Unleash pods themselves will fail without the secret).

Consider either:

  • Moving unleash-deployment.yaml to an optional overlay (e.g., overlays/with-unleash/)
  • Or keeping it in base but adding a note to the deployment docs that the unleash-credentials secret must be created (from the example) before make deploy

[M3] scripts/bootstrap-workspace.sh referenced but not verified in this PR

The kind-up Makefile target now calls ./scripts/bootstrap-workspace.sh if .dev-bootstrap.env exists. The dev-bootstrap target calls it unconditionally. If this script doesn't already exist in the repository, make dev-bootstrap will fail with a hard error. The PR should confirm the script exists or include it.


🔵 Minor Issues

[m1] Default credentials hardcoded in Makefile output

@echo "  Login: admin / unleash4all"

While unleash4all is Unleash's well-known default, printing it in Makefile output normalizes leaving default credentials in place. Consider omitting the password from the output and pointing to docs instead.

[m2] Hardcoded ambient-code namespace in secret example

unleash-credentials-secret.yaml.example hardcodes http://unleash.ambient-code.svc.cluster.local:4242/api as the unleash-url. Users deploying to a different namespace (e.g., vteam-dev for local dev) will use this URL verbatim and get connection failures. A comment noting the namespace should match the deployment namespace would help.

[m3] Frontend docs don't align with project's React Query patterns

feature-flags-unleash.md shows usage of useFlag(), useVariant(), and useFlagsStatus() hooks from @/lib/feature-flags — these are Unleash SDK hooks, not the project's standard React Query hooks. The docs are fine as-is since this is an SDK wrapper, but it would help to explicitly note that Unleash flag state is managed by the Unleash SDK (not React Query) and explain why this is an exception to the standard pattern.


Positive Highlights

  • Consistent optional: true on all 6 backend env vars — backend will gracefully degrade when Unleash is absent.
  • .gitignore update — correctly prevents accidental credential commits using the same pattern as minio-credentials-secret.yaml.
  • Good example secret template — clearly labeled sections for PostgreSQL, API URLs, and tokens with CHANGE_ME_ placeholders for credentials.
  • Resource requests/limits on both pods — follows platform standards for predictable scheduling.
  • Health probes on both PostgreSQL and Unleashpg_isready for PostgreSQL and /health HTTP probe for Unleash are correct choices.
  • Recreate strategy for PostgreSQL — appropriate for a single-replica stateful workload with ReadWriteOnce PVC (avoids the stuck pod issue with RollingUpdate).
  • Helpful Makefile targetsunleash-status and unleash-port-forward are developer-friendly additions.
  • Documentation is well-structured — clear separation of frontend vs. backend usage, admin UI section, and API endpoint table.

Recommendations

Prioritized action items before merge:

  1. [Must] Revert components/manifests/overlays/production/kustomization.yaml — accidental personal registry references.
  2. [Must] Add optional: true to both frontend env vars in frontend-deployment.yaml.
  3. [Must] Add securityContext (allowPrivilegeEscalation: false, capability drop) to both containers in unleash-deployment.yaml.
  4. [Should] Replace registry.redhat.io PostgreSQL image with postgres:16-alpine (or document auth requirements and fix PGDATA path for RHEL image).
  5. [Should] Move unleash-deployment.yaml to an optional overlay or document the pre-deploy secret creation requirement more prominently.
  6. [Should] Confirm scripts/bootstrap-workspace.sh exists in the repo.
  7. [Nice-to-have] Fix the hardcoded namespace in the secret example and remove the default password from Makefile output.

🔍 View AI decision process (logs available for 90 days)

📋 View memory system files loaded (click to expand)

What Amber Loaded for Code Review

Amber automatically loaded these repository standards from the memory system:

  1. CLAUDE.md - Master project instructions, development standards
  2. backend-development.md - Go backend, K8s integration patterns
  3. frontend-development.md - NextJS, Shadcn UI, React Query patterns
  4. security-standards.md - Auth, RBAC, token handling
  5. k8s-client-usage.md - User token vs service account patterns
  6. error-handling.md - Consistent error patterns
  7. react-query-usage.md - Data fetching patterns

Impact: This review used your repository's specific code quality standards, security patterns, and best practices from the memory system (PRs #359, #360) - not just generic code review guidelines.

@maskarb maskarb force-pushed the rhoai-47012-docs-unleash-feature-flags branch from b14e089 to 61bd219 Compare February 19, 2026 14:41
@github-actions
Copy link
Contributor

github-actions bot commented Feb 19, 2026

Claude Code Review

Summary

This PR adds Unleash feature flag integration: deployment manifests, Makefile targets, and documentation. The documentation is well-structured and the deployment approach follows existing patterns. However, there are critical issues that will break existing deployments and the documentation references code that does not yet exist in the repository.


Issues by Severity

🚫 Blocker Issues

1. Frontend deployment will break all existing installations

components/manifests/base/frontend-deployment.yaml:36-45

The comment says "optional" but the secretKeyRef entries are not marked optional: true:

# Unleash Feature Flags configuration (optional)  ← comment says optional
- name: UNLEASH_URL
  valueFrom:
    secretKeyRef:
      name: unleash-credentials
      key: unleash-url
      # ← missing: optional: true

Without optional: true, Kubernetes will refuse to start the frontend pod if the unleash-credentials secret does not exist. Every existing deployment that updates manifests without first creating this secret will have the frontend fail to start. The backend deployment (correctly) marks all its optional secrets with optional: true. Apply the same pattern here.


🔴 Critical Issues

2. Documentation references code that does not exist

The documentation describes and links to the following files, none of which are present in the repository:

File referenced in docs Exists?
components/backend/featureflags/featureflags.go
components/backend/handlers/featureflags.go
components/backend/handlers/featureflags_admin.go
@/lib/feature-flags (frontend)
components/frontend/src/services/queries/use-feature-flags-admin.ts
components/frontend/src/components/workspace-sections/feature-flags-section.tsx

The docs tell users how to call handlers.FeatureEnabled() and useFlag(), but those APIs don't exist. Either the implementation should be included in this PR, or the documentation should be scoped to what is actually implemented (deployment and configuration only), with a clear note that code integration is forthcoming.

3. Unleash added to base kustomization without prerequisite secret

components/manifests/base/kustomization.yaml now includes unleash-deployment.yaml in the base resources, making Unleash a mandatory component of all deployments. The unleash-deployment.yaml requires the unleash-credentials secret, which is not created automatically. Any make deploy without first manually creating the secret will result in PostgreSQL and Unleash pods failing to start.

Options:

  • Move Unleash to an optional overlay (e.g., components/manifests/overlays/unleash/)
  • Add the secret creation to deploy.sh with a check
  • Add a --wait or preflight check in the Makefile target

🟡 Major Issues

4. PostgreSQL image/path mismatch

components/manifests/base/unleash-deployment.yaml:44,61,65

The manifest mixes Red Hat image conventions with Debian PostgreSQL path conventions:

  • Image: registry.redhat.io/rhel10/postgresql-16:10.1 (RHEL, default data path /var/lib/pgsql/data)
  • PGDATA: /var/lib/postgresql/data/pgdata (Debian convention)
  • Volume mount: /var/lib/postgresql/data

The RHEL PostgreSQL image does support PGDATA overrides, but running the RHEL image with Debian-style paths is an untested combination. If initialization fails silently the pod will appear healthy but data won't persist. Either use the official postgres:16 image consistently with the Debian convention, or update the paths to match the RHEL convention (/var/lib/pgsql/data).

5. No SecurityContext on new pods

components/manifests/base/unleash-deployment.yaml

Neither the PostgreSQL nor the Unleash containers have a securityContext. CLAUDE.md explicitly requires SecurityContext for all pods:

securityContext:
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: false
  capabilities:
    drop: ["ALL"]

OpenShift with restricted SCC will reject pods without these settings.

6. New docs not registered in mkdocs.yml

mkdocs.yml does not include the new docs/feature-flags/ pages in the nav. The pages are unreachable from the documentation site. Add entries under an appropriate section (e.g., under Developer Guide or a new Integrations section).


🔵 Minor Issues

7. Third-party Docker Hub image

unleash-deployment.yaml:117 uses unleashorg/unleash-server:5.11.3 from Docker Hub directly. Other platform components use quay.io/. If the org has image registry policies or air-gapped environments are a concern, this bypasses them. Consider mirroring or documenting this requirement explicitly.

8. Default credentials exposed in Makefile

Makefile:678 prints Login: admin / unleash4all as the default credentials. While this is the Unleash default, making it prominent in the Makefile could encourage leaving defaults in place. A note to check the actual configured credentials would be more appropriate.

9. Example tokens are clearly placeholder but could be used as-is

unleash-credentials-secret.yaml.example contains:

admin-api-token: "*:*.unleash-admin-token"
client-api-token: "default:development.unleash-client-token"

These are non-functional placeholder strings, not actual token format. The warning exists but the placeholder values may confuse users about whether they need to generate real tokens vs. just substitute values. A comment clarifying that real tokens must be generated from the Unleash UI would help.


Positive Highlights

  • The .gitignore entry for **/unleash-credentials-secret.yaml is correct and consistent with the existing minio-credentials-secret.yaml pattern.
  • The backend deployment correctly uses optional: true for all six new Unleash env vars.
  • The unleash-status Makefile target with a graceful fallback message is a good UX touch.
  • The documentation structure (overview + detailed guide) mirrors the existing Langfuse observability docs pattern.
  • Using a Recreate strategy for the PostgreSQL deployment is appropriate for a single-replica stateful service.
  • Health probes on both PostgreSQL and Unleash are well-configured with sensible initial delays.

Recommendations

Prioritized action items:

  1. [Blocker] Add optional: true to both frontend secretKeyRef entries (UNLEASH_URL, UNLEASH_CLIENT_KEY).
  2. [Critical] Either include the implementation code (featureflags/featureflags.go, React hooks, etc.) or explicitly scope the docs to deployment-only with a "code integration coming in a follow-up PR" notice.
  3. [Critical] Move Unleash out of the base kustomization into an optional overlay, or add a preflight check that creates the secret if it does not exist.
  4. [Major] Align the PostgreSQL image and paths — either switch to postgres:16 with /var/lib/postgresql/data, or use RHEL conventions with /var/lib/pgsql/data.
  5. [Major] Add SecurityContext to both containers to satisfy OpenShift SCC requirements.
  6. [Major] Register the new docs in mkdocs.yml nav so they are accessible from the documentation site.

🔍 View AI decision process (logs available for 90 days)

📋 View memory system files loaded (click to expand)

What Amber Loaded for Code Review

Amber automatically loaded these repository standards from the memory system:

  1. CLAUDE.md - Master project instructions, development standards
  2. backend-development.md - Go backend, K8s integration patterns
  3. frontend-development.md - NextJS, Shadcn UI, React Query patterns
  4. security-standards.md - Auth, RBAC, token handling
  5. k8s-client-usage.md - User token vs service account patterns
  6. error-handling.md - Consistent error patterns
  7. react-query-usage.md - Data fetching patterns

Impact: This review used your repository's specific code quality standards, security patterns, and best practices from the memory system (PRs #359, #360) - not just generic code review guidelines.

@maskarb maskarb force-pushed the rhoai-47012-docs-unleash-feature-flags branch from 61bd219 to f9304de Compare February 19, 2026 19:40
@github-actions
Copy link
Contributor

github-actions bot commented Feb 19, 2026

Claude Code Review

Summary

PR #653 adds Unleash feature flag infrastructure to the Ambient Code Platform: new PostgreSQL and Unleash Kubernetes deployments integrated into the base kustomize manifests, environment-specific overlays (kind, local-dev, production), documentation, a standalone e2e deployment script, and Makefile convenience targets.

Despite the docs: prefix, this PR fundamentally changes the default platform deployment by adding two new services to the base kustomization — every make deploy will now install PostgreSQL and Unleash. The scope deserves closer scrutiny than a documentation-only change.


Issues by Severity

🚫 Blocker Issues

1. Documentation describes unimplemented code

docs/feature-flags/feature-flags-unleash.md documents handlers.FeatureEnabled(), handlers.FeatureEnabledForRequest(), and frontend hooks useFlag() / useVariant() / useFlagsStatus() — but none of these exist in the codebase. Publishing API documentation for code that hasn't been written yet will confuse users who try to follow the guide and find nothing there.

Fix: Either add the implementation in this PR, or clearly label those sections as "Planned API (not yet implemented)".

2. Default admin password in Makefile echo

@echo "  Login: admin / unleash4all"

unleash4all is the publicly known Unleash default admin password. Baking it into the Makefile echo: (a) encourages leaving the default password in place, (b) goes stale when operators change it, and (c) violates the spirit of the project's token-handling standards (never put credentials in source-controlled files where they can be overlooked).

Fix: Remove the credential hint and point to the README instead, e.g. See docs/feature-flags/README.md for default credentials.


🔴 Critical Issues

3. Version mismatch between manifests and deploy script

components/manifests/base/unleash-deployment.yaml pins unleashorg/unleash-server:5.11.3, but e2e/scripts/deploy-unleash.sh deploys version 6. These will diverge in behavior, schema, and supported features. Teams running via the manifests path and the script path will end up with different Unleash versions.

Fix: Align on a single version across both files.

4. Two competing deployment paths

The base kustomize manifests deploy Unleash via make deploy (using a raw Deployment + the project's own PostgreSQL manifest), while e2e/scripts/deploy-unleash.sh is a standalone script that installs PostgreSQL via the Bitnami Helm chart. These are fundamentally different topologies. Operators will have no clear guidance on which to use, and they cannot coexist without conflict.

Fix: Choose one canonical deployment approach. If the script is for one-off or legacy scenarios, document that explicitly and mark it as non-authoritative.

5. Missing SecurityContext on all new pods

Per the project's established security standards, every pod spec must include:

securityContext:
  allowPrivilegeEscalation: false
  capabilities:
    drop: ["ALL"]

Neither postgresql-deployment.yaml nor unleash-deployment.yaml include SecurityContext. This is especially important for the PostgreSQL container, which runs as root by default in the upstream Docker Hub image.

Fix: Add explicit SecurityContext to both Deployment pod specs.


🟡 Major Issues

6. Services added to base kustomization will silently break make deploy without manual prerequisite

PostgreSQL and Unleash reference postgresql-credentials and unleash-credentials Secrets (via secretKeyRef). The production overlay does not include these secrets (correct — they shouldn't be in git), but there is no deploy-time check or early failure message. The result is that pods enter CreateContainerConfigError with no clear indication of what's missing, unless the operator already read the example files carefully.

Fix: Add a pre-deploy check or clearly document the required manual steps at the top of the production overlay README. A kubectl apply --dry-run step in make deploy that validates secret existence would also help.

7. No CPU/memory resource requests or limits

Neither the PostgreSQL nor Unleash Deployments show resource requests/limits. Without these, the Kubernetes scheduler cannot make good placement decisions, QoS class defaults to BestEffort, and either service can consume all node resources under load.

Fix: Add conservative requests and sensible limits to both Deployments.

8. Commit type mismatch obscures scope

The PR title and base commit are prefixed docs:, but the actual changes add two new persistent services to the default platform deployment. Conventional commit discipline (docs: = documentation only) matters here because it affects how reviewers and CI treat the change. This should be feat: or at minimum a mixed feat!: that calls out the new default services.


🔵 Minor Issues

9. e2e/scripts/deploy-unleash.sh is in the wrong location

The e2e/scripts/ directory is for end-to-end test infrastructure. A 356-line operational deployment script belongs in a more appropriate location (e.g. components/manifests/scripts/ or a top-level scripts/ directory).

10. Shell variable in SQL heredoc

In the postgresql-init-scripts ConfigMap:

SELECT 'CREATE DATABASE $db_name'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$db_name')\gexec

The variable $db_name is currently hardcoded to "unleash", so there is no actual injection risk today. However the pattern — shell variable expansion into a SQL heredoc — will introduce SQL injection if future maintainers extend the script with user-controllable input.

Fix: Use psql's --dbname flag or a parameterised approach rather than string interpolation.

11. PVC sizing guidance absent for production

The base uses 10Gi, and the kind overlay patches it down to 1Gi. There is no guidance on appropriate production sizing for a PostgreSQL instance that may serve multiple platform services over time.


Positive Highlights

  • Clean .gitignore additions: **/postgresql-credentials-secret.yaml and **/unleash-credentials-secret.yaml prevent accidental credential commits.
  • Good kustomize overlay structure: Per-environment credentials (kind, local-dev, production separate) follows the project's established overlay pattern correctly.
  • Init container for RHEL PostgreSQL: The unleash-init-db-patch.yaml init container workaround (for the RHEL image's lack of /docker-entrypoint-initdb.d/) is a clean, idiomatic Kubernetes solution.
  • Example secret files: Providing .yaml.example files makes the required secret structure explicit and discoverable.
  • Makefile convenience targets: unleash-port-forward and unleash-status are practical day-to-day developer helpers.
  • Idempotent DB creation: The WHERE NOT EXISTS guard in the init script handles re-runs safely.

Recommendations (prioritized)

  1. [Blocker] Mark undocumented API sections as "Planned" or implement them in this PR.
  2. [Blocker] Remove the hardcoded admin / unleash4all credential from the Makefile.
  3. [Critical] Add SecurityContext to all new pod specs (PostgreSQL + Unleash).
  4. [Critical] Align Unleash version (5.11.3 vs 6) across manifests and deploy script.
  5. [Critical] Decide on one canonical deployment path and deprecate/remove the other.
  6. [Major] Add resource requests/limits to both Deployments.
  7. [Major] Add pre-deploy secret validation or clear runbook for production operators.
  8. [Major] Update commit/PR type from docs: to feat: to reflect true scope.
  9. [Minor] Move e2e/scripts/deploy-unleash.sh to an operational scripts directory.

Review generated by Claude Code (claude-sonnet-4-6) against project standards in CLAUDE.md and .claude/context/ memory files.


🔍 View AI decision process (logs available for 90 days)

📋 View memory system files loaded (click to expand)

What Amber Loaded for Code Review

Amber automatically loaded these repository standards from the memory system:

  1. CLAUDE.md - Master project instructions, development standards
  2. backend-development.md - Go backend, K8s integration patterns
  3. frontend-development.md - NextJS, Shadcn UI, React Query patterns
  4. security-standards.md - Auth, RBAC, token handling
  5. k8s-client-usage.md - User token vs service account patterns
  6. error-handling.md - Consistent error patterns
  7. react-query-usage.md - Data fetching patterns

Impact: This review used your repository's specific code quality standards, security patterns, and best practices from the memory system (PRs #359, #360) - not just generic code review guidelines.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 19, 2026

Claude Code Review

Summary

This PR adds an Unleash feature flag server and shared PostgreSQL deployment to the platform manifests, along with documentation and a standalone deployment script. The Kubernetes overlay structure (kind/local-dev/production) is well thought-out and the RHEL image handling shows good platform awareness. However, there are critical issues: the documentation describes SDK integration code (useFlag(), handlers.FeatureEnabled(), API endpoints) that does not exist anywhere in the codebase, and the standalone deploy script (deploy-unleash.sh) conflicts architecturally with the kustomize-based deployment added in the same PR.

Issues by Severity

🚫 Blocker Issues

1. Documentation references non-existent code

docs/feature-flags/README.md and docs/feature-flags/feature-flags-unleash.md document the following as if they exist:

  • useFlag(), useVariant(), useFlagsStatus() from @/lib/feature-flags
  • handlers.FeatureEnabled() / handlers.FeatureEnabledForRequest() backend functions
  • API endpoints: GET/POST /api/projects/:projectName/feature-flags/...
  • Reference files: components/backend/featureflags/featureflags.go, components/backend/handlers/featureflags.go, components/frontend/src/components/workspace-sections/feature-flags-section.tsx

None of these exist in this PR or the codebase. A developer following this documentation will hit dead ends immediately. The docs should either be scoped to infrastructure-only (what this PR actually delivers), or the implementation must accompany them.

🔴 Critical Issues

2. deploy-unleash.sh conflicts with the kustomize-based deployment

This PR simultaneously adds Unleash to components/manifests/base/kustomization.yaml (deployed via make deploy) AND adds e2e/scripts/deploy-unleash.sh which uses a completely different approach:

  • Script deploys PostgreSQL via Bitnami Helm chart (release name unleash-postgresql) — separate from the postgresql-deployment.yaml added to the base manifests
  • Script deploys Unleash via raw kubectl apply with unleashorg/unleash-server:6 — different image tag from unleashorg/unleash-server:5.11.3 in the manifests
  • Result: two deployment paths, two PostgreSQL instances, two different Unleash versions

The script reads like it was written before the decision to use kustomize manifests. It should either be removed (since make deploy now handles this) or rewritten to complement the kustomize approach. The Makefile comment already acknowledges make deploy handles Unleash — the standalone script is now misleading.

3. Missing SecurityContext on all workloads

CLAUDE.md explicitly requires setting SecurityContext on all Job/Deployment pods with AllowPrivilegeEscalation: false and Drop: ALL. Neither postgresql-deployment.yaml nor unleash-deployment.yaml has any SecurityContext:

# Required for both postgresql and unleash deployments
spec:
  template:
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: postgresql  # or unleash
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]

Note: PostgreSQL requires write access to its data directory so readOnlyRootFilesystem: true is not appropriate here, but the other controls are required.

🟡 Major Issues

4. Default admin credentials exposed in Makefile

Makefile line in unleash-port-forward target:

@echo "  Login: admin / unleash4all"

Hardcoding default credentials in the Makefile trains developers to rely on them and makes it easy to accidentally deploy with these defaults. Remove this line or replace with a pointer to the credentials secret.

5. DATABASE_SSL=false hardcoded in base manifest

unleash-deployment.yaml has DATABASE_SSL: "false" as a hardcoded environment variable in the base (production-targeted) manifest. For an in-cluster connection this may be acceptable, but it should be a configurable value (e.g., sourced from the unleash-credentials secret) so production operators can enable SSL without patching the manifest.

🔵 Minor Issues

6. Duplicate overlay files

components/manifests/overlays/local-dev/postgresql-patch.yaml and components/manifests/overlays/production/postgresql-patch.yaml are byte-for-byte identical. Same for unleash-init-db-patch.yaml in both overlays. Consider promoting these to the base or a shared location, or at minimum add a comment noting they're intentionally identical.

7. Unleash version inconsistency

  • Base manifest: unleashorg/unleash-server:5.11.3 (pinned — good)
  • deploy-unleash.sh: unleashorg/unleash-server:6 (floating major tag — will silently upgrade)

If the script is kept, align the versions.

8. mkdocs.yml not updated

The new docs/feature-flags/ directory won't appear in the MkDocs navigation without adding it to mkdocs.yml. The docs will build but be unreachable from the navigation.

9. PostgreSQL readiness probe uses hardcoded username

readinessProbe:
  exec:
    command: [pg_isready, -U, postgres]

This bypasses the secret-configured username. Should use $(POSTGRES_USER) or reference the env var. Minor but breaks if the username is ever changed.

Positive Highlights

  • The overlay structure (kind/local-dev/production) is well-designed and handles platform differences cleanly
  • The init container pattern for RHEL environments (RHEL PostgreSQL doesn't support /docker-entrypoint-initdb.d) is a good solution
  • PVC size reduction for kind overlay (1Gi vs 10Gi) is a thoughtful developer experience choice
  • Example secret files with detailed comments are clear and helpful
  • .gitignore correctly protects actual credential files while committing only .example templates
  • Resource limits and liveness/readiness probes are configured on all deployments
  • set -euo pipefail in the deployment script
  • The unleash-status Makefile target is a nice operational convenience

Recommendations

Priority order:

  1. Scope or gate the documentation — Either remove/rewrite the SDK integration sections to only document what exists (the infrastructure), or add the actual featureflags.go, useFlag(), and handler/API implementations in this PR
  2. Remove or reconcile deploy-unleash.sh — If make deploy now handles Unleash, the script should be removed. If the script is intended as a standalone alternative, remove Unleash from the kustomize base manifests and document the two paths clearly
  3. Add SecurityContext to both Deployments — Required per CLAUDE.md project standards
  4. Remove the hardcoded credentials echo from the Makefile
  5. Make DATABASE_SSL configurable via the credentials secret
  6. Update mkdocs.yml to include docs/feature-flags/ in the navigation

Review generated by Claude Code (claude-sonnet-4-6)


🔍 View AI decision process (logs available for 90 days)

📋 View memory system files loaded (click to expand)

What Amber Loaded for Code Review

Amber automatically loaded these repository standards from the memory system:

  1. CLAUDE.md - Master project instructions, development standards
  2. backend-development.md - Go backend, K8s integration patterns
  3. frontend-development.md - NextJS, Shadcn UI, React Query patterns
  4. security-standards.md - Auth, RBAC, token handling
  5. k8s-client-usage.md - User token vs service account patterns
  6. error-handling.md - Consistent error patterns
  7. react-query-usage.md - Data fetching patterns

Impact: This review used your repository's specific code quality standards, security patterns, and best practices from the memory system (PRs #359, #360) - not just generic code review guidelines.

@maskarb maskarb marked this pull request as draft February 19, 2026 20:10
@maskarb maskarb marked this pull request as draft February 19, 2026 20:10
maskarb and others added 2 commits February 19, 2026 16:28
- Add PostgreSQL deployment with credentials secret management
- Add overlays for kind, local-dev, production, and e2e environments
- Use JSON patches for RHEL PostgreSQL image in production/local-dev
- Move init-scripts to kind overlay (production uses init containers)
- Fix kustomize deprecation warnings (migrate to unified patches syntax)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Unleash deployment with credentials secret management
- Add init container patches for RHEL environments (local-dev, production)
- Add documentation for feature flags setup
- Add Makefile targets for Unleash port-forwarding and status
- Add deploy-unleash.sh script for standalone deployment

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@maskarb maskarb force-pushed the rhoai-47012-docs-unleash-feature-flags branch from cdc7964 to 9c16a20 Compare February 19, 2026 21:33
@github-actions
Copy link
Contributor

github-actions bot commented Feb 19, 2026

Claude Code Review

Summary

PR #653 adds Unleash feature flag deployment infrastructure (PostgreSQL + Unleash manifests, kustomize overlays for all environments, Makefile targets) and documentation. The manifest structure is well-organized with clear environment separation. However, as a DRAFT PR there are several issues—two of which will cause deployment failures—that should be resolved before merge.


Issues by Severity

Blocker Issues

1. Documentation references non-existent implementation files

Both doc files reference backend/frontend code that does not exist in the repository:

  • components/backend/featureflags/featureflags.go
  • components/backend/handlers/featureflags.go
  • components/backend/handlers/featureflags_admin.go
  • components/frontend/src/components/workspace-sections/feature-flags-section.tsx
  • components/frontend/src/services/queries/use-feature-flags-admin.ts

docs/feature-flags/feature-flags-unleash.md and docs/feature-flags/README.md document usage patterns, API endpoints, and React hooks for code that does not exist yet. Merging docs that reference phantom files will confuse contributors and break any doc validation. Options:

  • Hold this PR until the implementation lands
  • Clearly mark referenced files as "planned" / "not yet implemented"
  • Split into infra PR (this) and docs PR (after implementation)

Critical Issues

2. local-dev overlay is missing postgresql-credentials.yaml

components/manifests/overlays/local-dev/kustomization.yaml includes unleash-credentials.yaml but does not include a postgresql-credentials.yaml. Because postgresql-deployment.yaml (from base) requires the postgresql-credentials secret, CRC/local-dev deployments will fail at startup with secret "postgresql-credentials" not found. The unleash-credentials.yaml has a URL pointing to vteam-postgresql (correct for the namePrefix), but PostgreSQL itself will never start without its credentials.

Fix: add a postgresql-credentials.yaml to the local-dev overlay (similar to how unleash-credentials.yaml is provided), or document the manual creation step prominently.

3. Production/local-dev missing explicit pre-deploy documentation for required secrets

Both production and local-dev are missing unleash-credentials and postgresql-credentials secrets as kustomize resources. For production the github-app-secret.yaml exclusion is already documented with a comment -- the same pattern should be applied here. Currently there is no warning in the production overlay kustomization that these two secrets must be created manually before make deploy.


Major Issues

4. Unleash image version mismatch

components/manifests/base/unleash-deployment.yaml pins unleashorg/unleash-server:5.11.3, but e2e/scripts/deploy-unleash.sh (line 210) uses the floating unleashorg/unleash-server:6. These should match. Floating major-version tags break reproducibility and can introduce breaking changes silently.

5. mkdocs.yml not updated

The new docs/feature-flags/ directory is not registered in mkdocs.yml. The documentation will not appear in the rendered docs site at all.

6. deploy-unleash.sh blocks in non-interactive environments

Line 117 uses read -p "Use simple test passwords? (y/n, default: y)". This blocks indefinitely in CI or any automated context. The existing deploy-langfuse.sh has the same pattern -- but this is a known pain point. Add a --test-credentials / --yes flag or check [ -t 0 ] (stdin is a terminal) and default to test credentials in non-interactive mode.

7. deploy-unleash.sh prints credentials in plaintext

Lines 354-356:

echo "Credentials used:"
echo "   PostgreSQL: $POSTGRES_PASSWORD"

When POSTGRES_PASSWORD is the secure randomly-generated value, this leaks it to terminal output (and any CI log capture). Omit the password echo or replace with a note to retrieve it from the secret.


Minor Issues

8. Duplicate init script ConfigMaps

components/manifests/overlays/e2e/postgresql-init-scripts.yaml and components/manifests/overlays/kind/postgresql-init-scripts.yaml are byte-for-byte identical. Kustomize does not support symlinks, but a comment pointing to the canonical source and a note to keep them in sync would reduce confusion when adding future databases.

9. Default Unleash password hardcoded in Makefile

unleash-port-forward echoes Login: admin / unleash4all. While this is Unleash default, embedding it in the Makefile creates a false impression it is a permanent credential. A comment like # default password -- change after first login in production would clarify intent.

10. deploy-unleash.sh defaults to separate unleash namespace

The script defaults NAMESPACE="unleash" (line 9), but the kustomize manifests deploy to ambient-code. A user following the docs could end up with two separate Unleash instances in different namespaces. Either align the default namespace or add a note in the script help text clarifying the two deployment paths.

11. unleash-deployment.yaml hardcodes DATABASE_SSL: "false"

This is acceptable for dev, but for production setups with TLS-enabled PostgreSQL it silently disables SSL. Consider sourcing this from the unleash-credentials secret so it can be toggled per environment without patching the base manifest.


Positive Highlights

  • Clean overlay structure: The four-environment split (base to e2e / kind / local-dev / production) with targeted JSON and strategic-merge patches is well-executed and follows the existing platform pattern.
  • RHEL image handling: Using a JSON patch to swap the PostgreSQL image and env vars for OpenShift/RHEL environments (rather than duplicating the full manifest) is the right approach.
  • Init container pattern for RHEL: The unleash-init-db-patch.yaml initContainer correctly handles the RHEL PostgreSQL limitation with /docker-entrypoint-initdb.d/ and provides proper readiness waiting.
  • SQL injection defense in init scripts: postgresql-init-scripts.yaml validates database names with ^[a-zA-Z_][a-zA-Z0-9_]*$ before executing DDL -- good defensive practice.
  • Secret references for API tokens: unleash-deployment.yaml correctly sources all API tokens from the unleash-credentials secret rather than hardcoding them (unlike the standalone deploy script).
  • PVC size override for kind: Reducing from 10Gi to 1Gi for local kind development via postgresql-pvc-patch.yaml is a thoughtful UX improvement.
  • Probe configuration: Both services have appropriate readiness/liveness probes with sensible timeouts and delays.

Recommendations

Before removing DRAFT status:

  1. Resolve the local-dev missing postgresql-credentials secret (will break dev environments today)
  2. Align Unleash image version between manifests and deploy script
  3. Add mkdocs.yml nav entries for the new docs
  4. Either implement the referenced backend/frontend code or mark those doc sections as "coming soon"

Before merge:

  1. Add --yes / non-interactive mode to deploy-unleash.sh
  2. Remove/redact credentials from the deploy script final output
  3. Add pre-deploy secret creation instructions to production overlay kustomization comment (matching the github-app-secret.yaml pattern)

Reviewed by Claude Code using project memory system


🔍 View AI decision process (logs available for 90 days)

📋 View memory system files loaded (click to expand)

What Amber Loaded for Code Review

Amber automatically loaded these repository standards from the memory system:

  1. CLAUDE.md - Master project instructions, development standards
  2. backend-development.md - Go backend, K8s integration patterns
  3. frontend-development.md - NextJS, Shadcn UI, React Query patterns
  4. security-standards.md - Auth, RBAC, token handling
  5. k8s-client-usage.md - User token vs service account patterns
  6. error-handling.md - Consistent error patterns
  7. react-query-usage.md - Data fetching patterns

Impact: This review used your repository's specific code quality standards, security patterns, and best practices from the memory system (PRs #359, #360) - not just generic code review guidelines.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant