Feature: Kubernetes Helm Chart Structure As a DevOps engineer I want a valid Helm chart in the k8s/ directory So that I can deploy the CleverAgents server to Kubernetes Background: Given the project root directory # -- Chart.yaml validation -- Scenario: Chart.yaml exists with required Helm v2 fields When I read the Helm chart metadata Then the chart API version should be "v2" And the chart name should be "cleveragents" And the chart type should be "application" And the chart version should be set Scenario: Chart.yaml declares optional Redis dependency When I read the Helm chart metadata Then the chart should have a dependency named "redis" And the Redis dependency should be conditional on "redis.enabled" # -- values.yaml validation -- Scenario: values.yaml has configurable replica count When I read the Helm chart values Then the values should contain key "replicaCount" And the default replica count should be 1 Scenario: values.yaml has configurable resource limits When I read the Helm chart values Then the values should contain key "resources" And the resources should have CPU and memory limits And the resources should have CPU and memory requests Scenario: values.yaml has ingress configuration with TLS support When I read the Helm chart values Then the values should contain key "ingress" And the ingress should have an enabled toggle And the ingress should have a TLS configuration section Scenario: values.yaml has optional Redis configuration When I read the Helm chart values Then the values should contain key "redis" And the Redis configuration should have an enabled toggle And the Redis configuration should have authentication settings Scenario: values.yaml has server configuration When I read the Helm chart values Then the values should contain key "server" And the server config should have host setting And the server config should have port setting And the server config should have workers setting Scenario: values.yaml has database configuration When I read the Helm chart values Then the values should contain key "database" And the database config should support existing secrets Scenario: values.yaml has security context for non-root execution When I read the Helm chart values Then the pod security context should enforce non-root execution And the container security context should drop all capabilities # -- Template file content validation -- Scenario: Deployment template has correct kind and API version When I read the template "k8s/templates/deployment.yaml" Then the template should contain "kind: Deployment" And the template should contain "apiVersion: apps/v1" And the template should contain "volumeMounts:" And the template should contain "mountPath: /tmp" And the template should contain "mountPath: /app/data" And the template should contain "sizeLimit: 100Mi" And the template should contain "sizeLimit: 1Gi" Scenario: Service template has correct kind and API version When I read the template "k8s/templates/service.yaml" Then the template should contain "kind: Service" And the template should contain "apiVersion: v1" Scenario: Ingress template has correct kind and API version When I read the template "k8s/templates/ingress.yaml" Then the template should contain "kind: Ingress" And the template should contain "networking.k8s.io/v1" And the template should match pattern "^\s+tls:" Scenario: ConfigMap template has correct kind and API version When I read the template "k8s/templates/configmap.yaml" Then the template should contain "kind: ConfigMap" And the template should contain "apiVersion: v1" Scenario: ServiceAccount template has correct kind and API version When I read the template "k8s/templates/serviceaccount.yaml" Then the template should contain "kind: ServiceAccount" And the template should contain "apiVersion: v1" And the template should contain "automountServiceAccountToken: false" Scenario: Secrets template has correct kind When I read the template "k8s/templates/secrets.yaml" Then the template should contain "kind: Secret" Scenario: Helpers template exists with chart helpers When I read the template "k8s/templates/_helpers.tpl" Then the template should contain "cleveragents.fullname" And the template should contain "cleveragents.labels" Scenario: NOTES.txt template exists with deployment info When I read the template "k8s/templates/NOTES.txt" Then the template should contain "CleverAgents Server has been deployed" # -- Server Dockerfile -- Scenario: Server-specific Dockerfile exists Then the chart file "Dockerfile.server" should exist Scenario: Server Dockerfile uses multi-stage build When I read the server Dockerfile Then it should have a builder stage And it should have a runtime stage Scenario: Server Dockerfile uses non-root user When I read the server Dockerfile Then it should create a non-root user with uid 1000 Scenario: Server Dockerfile exposes port 8000 When I read the server Dockerfile Then it should expose port 8000 Scenario: Server Dockerfile pins uv image version When I read the server Dockerfile Then it should not use unpinned uv latest tag Scenario: Server Dockerfile uses python -m cleveragents as ENTRYPOINT When I read the server Dockerfile Then the ENTRYPOINT should use "python -m cleveragents" Scenario: Server Dockerfile CMD uses server serve subcommand When I read the server Dockerfile Then the CMD should include "server" and "serve" # -- Secrets structure -- Scenario: Secrets template guards database secret with existingSecret check When I read the template "k8s/templates/secrets.yaml" Then the template should contain "database.existingSecret" And the template should contain "database.url" And the template should contain "database-url" Scenario: Secrets template guards Redis secret with existingSecret check When I read the template "k8s/templates/secrets.yaml" Then the template should contain "redis.auth.existingSecret" And the template should contain "redis.auth.password" And the template should contain "redis-password" # -- Deployment command/args -- Scenario: Deployment template overrides command with CLI server serve values When I read the template "k8s/templates/deployment.yaml" Then the template should contain "python" And the template should contain "cleveragents" And the template should contain "server" And the template should contain "serve" And the template should contain "--app" And the template should contain "cleveragents.a2a.asgi:app" And the template should contain "server.host" And the template should contain "server.port" And the template should contain "server.workers" And the template should contain "server.logLevel" # -- envFrom wiring -- Scenario: Deployment template injects ConfigMap via envFrom When I read the template "k8s/templates/deployment.yaml" Then the template should contain "envFrom" And the template should contain "configMapRef" # -- Redis host helper -- Scenario: Helpers template defines Redis host using Release.Name When I read the template "k8s/templates/_helpers.tpl" Then the template should contain "cleveragents.redisHost" And the template should contain ".Release.Name" # -- Probes -- Scenario: values.yaml splits liveness and readiness probe endpoints When I read the Helm chart values Then the liveness probe should target the live endpoint And the readiness probe should target the ready endpoint # -- Image defaults -- Scenario: values.yaml has sensible image defaults When I read the Helm chart values Then the image pull policy should be "IfNotPresent" And the image tag should default to empty for appVersion fallback # -- Service defaults -- Scenario: values.yaml service defaults to ClusterIP on port 8000 When I read the Helm chart values Then the service type should be "ClusterIP" And the service port should be 8000 # -- Conditional template branch validation -- Scenario: Ingress template is guarded by ingress.enabled condition When I read the template "k8s/templates/ingress.yaml" Then the template should match pattern "^\{\{-\s*if\s+\.Values\.ingress\.enabled" Scenario: Ingress template guards ssl-redirect against user annotation override When I read the template "k8s/templates/ingress.yaml" Then the template should match pattern "not.*hasKey.*\.Values\.ingress\.annotations.*ssl-redirect" Scenario: ServiceAccount template is guarded by serviceAccount.create condition When I read the template "k8s/templates/serviceaccount.yaml" Then the template should match pattern "^\{\{-\s*if\s+\.Values\.serviceAccount\.create" Scenario: Secrets template guards database secret with conditional logic When I read the template "k8s/templates/secrets.yaml" Then the template should match pattern "if\s+and\s+\.Values\.database\.url.*not\s+\.Values\.database\.existingSecret" Scenario: Secrets template guards Redis secret with conditional logic When I read the template "k8s/templates/secrets.yaml" Then the template should match pattern "if\s+and\s+\.Values\.redis\.enabled\s+\.Values\.redis\.auth\.enabled\s+\.Values\.redis\.auth\.password.*not\s+\.Values\.redis\.auth\.existingSecret" Scenario: Deployment template has database credential 3-way branching When I read the template "k8s/templates/deployment.yaml" Then the template should match pattern "if\s+\.Values\.database\.existingSecret" And the template should match pattern "else\s+if\s+\.Values\.database\.url" Scenario: Deployment template has Redis credential 3-way branching When I read the template "k8s/templates/deployment.yaml" Then the template should match pattern "if\s+\.Values\.redis\.auth\.existingSecret" And the template should match pattern "else\s+if\s+\.Values\.redis\.auth\.password" And the template should contain "name: {{ .Release.Name }}-redis" And the template should contain "key: redis-password" Scenario: Deployment template gates Redis env vars behind redis.enabled When I read the template "k8s/templates/deployment.yaml" Then the template should match pattern "if\s+\.Values\.redis\.enabled" And the template should match pattern "CLEVERAGENTS_REDIS_HOST" And the template should match pattern "CLEVERAGENTS_REDIS_PASSWORD" Scenario: Deployment template requires explicit database configuration When I read the template "k8s/templates/deployment.yaml" Then the template should contain "database configuration is required" Scenario: Helm render fails fast without database configuration When I render the Helm chart without database configuration Then the render should fail with required database configuration error Scenario: Helm render fails when ingress is enabled without TLS by default When I render the Helm chart with ingress enabled and no TLS Then the render should fail with required ingress TLS configuration error Scenario: Helm render allows explicit insecure ingress opt-out for development When I render the Helm chart with ingress enabled and insecure opt-out enabled Then the ingress render should succeed in insecure dev mode Scenario: Helm render succeeds when ingress TLS is explicitly configured When I render the Helm chart with ingress enabled and TLS configured Then the ingress render should succeed with TLS enabled Scenario: Deployment template disables service account token mounting When I read the template "k8s/templates/deployment.yaml" Then the template should match pattern "^\s+automountServiceAccountToken:\s+false" Scenario: Security context includes seccomp profile When I read the Helm chart values Then the container security context should have a seccomp profile Scenario: Security context enforces readOnlyRootFilesystem When I read the Helm chart values Then the container security context should set readOnlyRootFilesystem to true Scenario: Security context disables privilege escalation When I read the Helm chart values Then the container security context should set allowPrivilegeEscalation to false Scenario: Server Dockerfile pins uv version to specific semver When I read the server Dockerfile Then the uv image reference should use a specific semver tag Scenario: Server Dockerfile removes uv from runtime image When I read the server Dockerfile Then the Dockerfile should remove uv after installation # -- Deployment README -- Scenario: Deployment README exists with instructions When I read the deployment README Then it should contain quick start instructions And it should contain TLS configuration documentation And it should contain Redis configuration documentation And it should contain scaling instructions