Two reachable clusters each carry a CNPG Cluster named apps-pg in a
namespace named databases. KUBECONFIG is an environment variable, so the
Makefile ?= default never applied, and RAILIANCE01_KUBECONFIG pointed at
config-hosteurope - a different cluster. Had the environment pointed at the
other reachable cluster instead of an unauthorized one, make apps-pg-deploy
would have applied RPF-WP-0019 connection limits, role timeouts and backup
config to the wrong cluster and reported success. The Unauthorized error was
the only thing that prevented it.
Filename selection cannot protect against this: both kubeconfigs resolve to
a 127.0.0.1 tunnel port and the environment wins either way. railiance01-guard
pins identity instead, comparing the live kube-system namespace UID against
RAILIANCE01_CLUSTER_UID, and fails closed on mismatch or unreachability. It
gates apps-pg deploy, backup-deploy, overflow-dry-run, status and shell.
Verified refusing on the wrong cluster, refusing when unreachable, and
passing on railiance01. Not global: db-status legitimately targets the other
cluster for gitea-db.
RPF-WP-0019 blocker note corrected - the cluster was never unreachable, our
wiring was wrong.
RPF-WP-0020 seeded for the pre-existing CCR test failure, which is two
unrelated problems: CCR-2026-0010 is an active lane missing its whole
openbao.auth block, and CCR-2026-0011 is an honest in-flight draft the suite
has no way to express.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
RPF-WP-0018 closed: all seven tasks done. The provider-declaration finding
was adopted upstream and its canonical form is the provider: block in
tenancy.yaml; adaptive-pricing declined the standing co-signature and
supplied typed tier minima instead, recorded in ADR-0002. Three corrections
against our own output are recorded in the documents rather than edited
away.
RPF-WP-0019 T03 done (ceiling of three, memory binding, apps-pg-2 named as
overflow, enforced by make apps-pg-verify-capacity). T01/T02 are
repository-complete: backup target, retention, per-consumer connection
limits, role timeouts and Burstable resources are declared in source and
published in s3-consumer-interfaces 1.1.0 before rollout. They stay in
progress because no live application, backup success or restore proof
exists, and declared configuration is not a section 13 artifact. T04 waits
on that window.
apps-pg R reason corrected to say the target is declared-not-applied rather
than absent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Publish capacity, recovery, labor, and allocation-driver evidence for
resource:railiance:apps-pg so resource-control can forecast and allocate
without reading application data or inventing booked cost.
Adds the shared CloudNativePG cluster apps-pg for S5 application
databases:
- helm/apps-pg-cluster.yaml — Cluster CR, PG 16, 1 instance, 10Gi
- helm/apps-pg-networkpolicies.yaml — egress-to-kube-api +
ingress-from-cnpg-operator + label-based ingress opt-in
(railiance.io/postgres-client=apps-pg)
- helm/apps-pg-secret.sops.yaml.template — bootstrap credential
template (encrypt with SOPS before committing the real .sops.yaml)
- Makefile targets: apps-pg-deploy, apps-pg-status (with cnpg-plugin
fallback), apps-pg-shell (apps_admin/apps_meta), apps-pg-logs
- docs/apps-pg.md (codex) — consumer onboarding contract clarifying
the CNPG 1.28 role/database lifecycle boundary
Also fixes helm/gitea-db-cluster.yaml: spec.postgresql.version is not
a valid CNPG v1 field (strict decoding rejects it). Replaced with
spec.imageName matching the live cluster (postgresql:18.1-system-trixie)
so make db-deploy is a no-op instead of an apply rejection.
Live state at commit time: Cluster apps-pg in healthy state, primary
apps-pg-1 Running, smoke-tested via psql from a labeled temp ns.
Co-Authored-By: codex <noreply@openai.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>