# State Hub Railiance Deployment Handoff This directory contains the State Hub deployment handoff for `CUST-WP-0011`. It is source-owned by `state-hub` and split along the Railiance ownership boundaries used for the actual cluster rollout. ## Ownership - `deploy/railiance/platform/` is the `railiance-platform` handoff for the `state-hub-db` CloudNativePG cluster, database bootstrap credential, and database NetworkPolicies in the `databases` namespace. - `deploy/railiance/apps/` is the `railiance-apps` handoff for the State Hub API Helm chart, non-secret production values, and app namespace runtime Secret template. - Runtime secret values are not stored here. Replace placeholder passwords only in an operator-controlled file, then encrypt or deliver through the approved platform secret path. ## Image The current image is pinned to: ```text gitea.coulomb.social/coulomb/state-hub:b536741 ``` railiance01 has already pulled this tag with `crictl`, and the image serves `GET /state/health` against the local WSL database in smoke testing. ## Render And Dry-Run Render the app chart without touching the cluster: ```bash make railiance-state-hub-render ``` Run client-side Kubernetes validation for the platform manifests, app Secret template, and rendered chart: ```bash make railiance-state-hub-client-dry-run ``` Run server-side dry-run against the configured representative cluster: ```bash KUBECONFIG=~/.kube/config-hosteurope make railiance-state-hub-server-dry-run ``` Server-side dry-run requires the CNPG CRDs, namespace permissions, and dry-run permission for resources in `databases` and `state-hub`. Before the `state-hub` namespace exists, Kubernetes cannot server-dry-run namespaced app objects into that namespace because dry-run Namespace creation is not persisted. The Make target therefore server-validates the platform and Namespace manifests, then falls back to client dry-run for namespaced app manifests with an explicit notice. ## Promotion Notes Platform promotion into `railiance-platform`: - copy `platform/state-hub-db-credentials.sops.yaml.template` to a real SOPS secret file with an operator-generated password; - apply or GitOps-manage `platform/state-hub-db-cluster.yaml`; - apply or GitOps-manage `platform/state-hub-db-networkpolicies.yaml`. App promotion into `railiance-apps`: - copy `apps/charts/state-hub/` to `charts/state-hub/`; - copy `apps/helm/state-hub-values.yaml` to `helm/state-hub-values.yaml`; - apply or GitOps-manage `apps/manifests/state-hub-namespace.yaml`; - create `state-hub-env` in the `state-hub` namespace from the approved secret-delivery path; - deploy with Helm using the production values file, which sets `namespace.create=false`, only after `state-hub-db` is healthy. ## Runtime Secret Contract The app chart expects a Kubernetes Secret named `state-hub-env` in the `state-hub` namespace with at least: ```text DATABASE_URL=postgresql+asyncpg://state_hub:@state-hub-db-rw.databases.svc.cluster.local:5432/state_hub ``` Optional runtime settings such as `CORS_ORIGINS` can live in the chart ConfigMap. The default chart keeps public ingress disabled; access should use the existing private tunnel/ops-bridge path until a separate exposure decision is recorded.