The workflow built and pushed the image but never deployed it - the cluster objects had been created by hand. This adds a `deploy` job that applies the manifests in `kube/` and rolls the deployment. The deploy job is separate from the build job on purpose. The `KUBEC_CONFIG_BUILDX` secret is cluster-admin-equivalent, and a build step that never talks to the cluster should not be able to read it. Three things this job does that a naive `kubectl apply` does not: 1. `kubectl rollout restart`. The image tag is `:latest`, which is immutable in the manifest, so `apply` alone does not roll the pods. Without the restart the deployment reports success while the old pods keep serving the old image - a deploy that silently changes nothing. 2. Verifies the running digest against the registry's `:latest`. CI green and pods `Ready` do not prove the new code is live; the digest comparison does. 3. Smoke tests the running app - `/healthz` and `/readyz` - from inside the pod, so a deploy that comes up but cannot serve is caught in CI rather than by the next person to open the page. The Secrets (`beer-db`, `beer-app`) are hand-provisioned and are deliberately not in the apply set, so a deploy cannot clobber them.