railiance-platform/workplans/archived/260905-RPF-WP-0008-credential-change-suite-stabilization.md
codex 9f83e426c7 Consolidate platform workplans and assess intent gaps
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
2026-09-05 11:14:42 +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.