railiance-platform/workplans/RPF-WP-0008-credential-change-suite-stabilization.md
codex e4af2a1d10
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
fix(workplans): migrate active workplans off the retired RAILIANCE-WP prefix
RAILIANCE-WP is a family name, not a repository (ADR-007, and the prefix
registry already lists it retired). Three repositories independently used one
number space for unrelated work — RAILIANCE-WP-0012 was openbao extraction here,
a cnpg backup in railiance-apps and a deploy-verify in railiance-cluster. This
repository also carried two files both numbered 0016.

Active workplans move to the successor prefix and are renumbered from 0001 in
historical order. Archived workplans keep their historical identifiers.

Projection UUIDs are re-derived from the new canonical ids. Records already
registered under the old identifiers leave orphaned hub rows behind; that debt
is recorded in CUST-WP-0068 and clears when ADR-012's reset-from-forge lands.

Refs CUST-WP-0068-T03

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
2026-08-25 22:58:35 +02:00

5 KiB

id type title domain repo status owner topic_slug created updated related_repos state_hub_workstream_id
RPF-WP-0008 workplan Credential-change test suite stabilization financials railiance-platform finished codex railiance 2026-08-11 2026-08-11
rapp-postgres
ops-warden
ec6b9fe2-5aae-5eb0-ba05-c1be241eda6b

RPF-WP-0008 - Credential-change test suite stabilization

Goal

Make python3 -m unittest discover -s tests -p 'test_credential*.py' pass non-interactively again, without weakening any approval or front-door gate.

Origin: the rapp-postgres coordination message of 2026-08-11, a residual from RAPP-POSTGRES-WP-0002-T04. The focused credential broker suite was green (9/9) at commit 9f6bdff, but full discovery reported five failures unrelated to the broker work.

Diagnosis

None of the five failures were broker regressions. Two were missing or invalid artifacts in CCR-2026-0009; three were test fixtures that had silently decayed as real CCR lanes advanced through their lifecycle.

The decay is the important finding. Three refusal tests used the live CCR-2026-0002 file as their "unapproved CCR" fixture. That lane has since been approved, applied and activated, so the refusal those tests assert stopped being the correct behaviour for that input — the gate did exactly the right thing and the tests failed anyway. applier-apply then walked past its (correctly ordered) blocker check into the interactive confirmation prompt and raised EOFError under a non-interactive runner. A refusal test that reads its approval state off a mutable production artifact will keep breaking every time a lane advances.

Boundaries

This workplan may:

  • repair credential-change test fixtures and add missing CCR source artifacts
  • correct schema-invalid field values in credential change requests

It must not:

  • relax applier_readiness_blockers, runbook_readiness_blockers, or the front-door resolvable/status coupling in scripts/credential-change.py
  • change grant delivery or revocation semantics in credential-grants/catalog.yaml
  • write or move any secret value

Tasks

id: RPF-WP-0008-T01
status: done
priority: high
state_hub_task_id: "300632b3-f89c-523e-a31f-b9bc98c8df30"

Repair CCR-2026-0009 (qonto-assistant workload KV read lane) so it validates:

  • add the missing openbao/policies/workload-kv-read-qonto-assistant.hcl, scoped read-only to tenants/{data,metadata}/binky/qonto-api and mirroring the workload-kv-read-binky-qonto-api.hcl shape
  • replace the schema-invalid access_frontdoor.readiness: proposed with pending-review, which is the correct state for a CCR still in review

The CCR stays status: proposed with resolvable: false — this task adds the missing source artifact, it does not advance the lane.

id: RPF-WP-0008-T02
status: done
priority: high
state_hub_task_id: "9533e97b-06dc-58d5-8249-fe299bad438d"

Stop the refusal tests depending on live CCR lifecycle state. Add a unapproved_ccr() helper to tests/test_credential_change.py that materializes a temp copy normalized to status: proposed, no review comments, readiness: pending-review, resolvable: false, and point test_applier_dry_run_refuses_unapproved_ccr, test_applier_apply_refuses_unapproved_ccr, test_runbook_refuses_unapproved_ccr and test_operator_commands_refuse_unapproved_ccr at it.

This also removes the EOFError: with a genuinely unapproved CCR, command_applier_apply returns 1 at its blocker check and never reaches the confirmation prompt. The gate ordering in scripts/credential-change.py was already correct and was left untouched.

id: RPF-WP-0008-T03
status: done
priority: medium
state_hub_task_id: "1b417fe7-6703-5663-9f3c-3a040ce1fe6f"

Fix test_approve_records_comment_but_unconfirmed_claim_still_blocks_apply, which demoted an active CCR to approved while leaving access_frontdoor.resolvable: true, tripping the resolvable=true requires status active rule. Build the fixture from unapproved_ccr() so the front-door state is consistent with the status the test actually wants. The validation rule is correct and unchanged.

id: RPF-WP-0008-T04
status: done
priority: high
state_hub_task_id: "83a4e8da-5ebb-5006-8aa8-2fe02169f9ba"

Confirm acceptance against the requested criteria:

  • python3 -m unittest discover -s tests -p 'test_credential*.py' < /dev/null — 52 tests, OK
  • full repo discovery -p 'test_*.py' — 61 tests, OK
  • make credential-change-validate — all nine CCRs OK
  • python3 scripts/credential-grants-validate.py — catalog valid, 3 grants
  • both rapp-postgres/audit-core-* openbao-database-credential grants still carry delivery.allowed: [exec-env] with child_only/redact_logs, and revocation.required: true with on_exec_exit: true

Outcome

Suite green non-interactively; no gate, blocker, validation rule or grant semantic was modified. The one behavioural change outside tests is the addition of a previously missing least-privilege policy artifact.