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>
5 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | related | origin | origin_ref | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| RPF-WP-0020 | workplan | Close CCR schema drift: one active lane unmigrated, one draft the suite cannot express | financials | railiance-platform | proposed | codex | railiance | 2026-08-18 | 2026-08-18 |
|
residual | RPF-WP-0019 |
RPF-WP-0020 — CCR schema drift
Goal
Make tests/test_credential_change.py::test_all_repo_ccrs_validate pass for
the right reason: because every credential-change request in the repo is
either valid or explicitly declared in-flight — not because the assertion was
loosened until it stopped complaining.
Why this is its own workplan
The test has been failing on main. It was found while closing
RPF-WP-0019 and confirmed to predate that work (it fails at HEAD with the
apps-pg changes stashed), so it is neither a regression from that workplan nor
something to fix inside it.
A single red test is hiding two unrelated problems with opposite remedies. That is the reason to split them out and name them, rather than fix whichever one makes the suite green first.
The two problems
P1 — an active credential lane is unmigrated.
credential-change-requests/CCR-2026-0010-email-connect-transactional.yaml
carries status: active and readiness: ready, and is missing the entire
openbao.auth block: method, mount, role, policies, bound_claims.
The validator gained those requirements and this CCR was never brought
forward.
This is the one that matters. A live lane whose declaration does not describe how the workload authenticates is a governance gap, not a lint failure — the document that is supposed to be the authority on the lane cannot answer the first question anyone would ask of it. The lane itself is presumably working, which is exactly what makes it easy to leave.
P2 — a genuine in-flight draft the suite cannot express.
CCR-2026-0011-scaleway-object-storage-bootstrap.yaml carries
status: apply_pending and readiness: waiting-on-ui-replace-of-xxx-placeholders.
It is a founder-bootstrap credential still holding placeholder values, and
ops-warden already tracks it as a draft lane. Its errors include a
readiness value outside the permitted enum, which is the file honestly
reporting that it is not finished.
This one is not a defect. The defect is that a suite asserting all CCRs validate has no way to say "this one is deliberately incomplete", so an honest draft and a real gap produce identical output.
Boundaries
- No secret values are read, written or rotated. This is declaration
hygiene. Anything requiring a mint, a rotation or an apply belongs to the
credential-change approval flow in
docs/credential-change-approval.md. - P2 is not closed by filling in placeholders. The Scaleway bootstrap key is a live commercial credential with an owner outside this repo.
- The validator's rules are not relaxed to accommodate either file.
Tasks
id: RPF-WP-0020-T01
status: todo
priority: high
Migrate CCR-2026-0010 to the current schema. Determine the actual
authentication path for the email-connect transactional lane — Kubernetes
auth mount, role, bound claims, and the policy name that must match
openbao.policy_name — from the live OpenBao configuration and the existing
policy file, not by inventing plausible values. If the live configuration and
the declaration disagree, the live configuration is the fact and the
disagreement is the finding.
id: RPF-WP-0020-T02
status: todo
priority: medium
Give the suite a way to express a draft. Add an explicit in-flight state
so CCR-2026-0011 is skipped by declaration rather than by exception list —
a status the validator recognises as not-yet-complete, with the test
asserting that such files are still well-formed in every other respect. An
allowlist of filenames would work today and rot on the next draft.
id: RPF-WP-0020-T03
status: todo
priority: medium
Report the drift rather than only fixing it. If the openbao.auth
requirement was added without migrating existing active CCRs, other repos
carrying CCRs may have the same gap and no failing test to reveal it. Confirm
whether the requirement originated here or upstream, and notify accordingly.
id: RPF-WP-0020-T04
status: todo
priority: low
Make the suite green and keep it that way. With T01 and T02 done, the full
suite passes. Record in docs/credential-change-approval.md that a new
required field obliges a migration pass over existing active CCRs — the
omission that produced P1.
Risks
T01 invents values to make the test pass. The likeliest failure and the worst one: a declaration that is well-formed and wrong is more dangerous than one that is visibly incomplete, because it stops anyone looking. Mitigation is that T01 reads live configuration and treats disagreement as a finding.
T02 becomes a way to silence future failures. Mitigation is that the in-flight state still requires the file to be well-formed in every other respect, so it suppresses the completeness assertion and nothing else.