railiance-platform/workplans/RAILIANCE-WP-0014-credential-change-suite-stabilization.md
codex b876a9b5ba
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Open RAILIANCE-WP-0015: platform rapp consistency
Survey of the four-axis repo family model against the live cluster and all six
family repos found the concepts sound but unenforced: rapp.yaml has no schema
and has drifted three ways across the three existing rapps, the reef binding
registry lists 1 of 3 live rapps, the rapp population diverged from the
first-wave plan of record, and the model is not in custodian canon so
fix-consistency cannot check it.

Operator decisions recorded in the workplan: grouped-by-bounded-context rapp
granularity, S3 owns only its own rapps and routes schema/canon changes to the
repos that own them, canonize the model now, and build the missing wave-1
user-facing exemplar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 11:08:44 +02:00

5 KiB

id type title domain repo status owner topic_slug created updated related_repos state_hub_workstream_id
RAILIANCE-WP-0014 workplan Credential-change test suite stabilization financials railiance-platform finished codex railiance 2026-08-11 2026-08-11
rapp-postgres
ops-warden
4dea40b7-43f5-499a-8919-79221623aa79

RAILIANCE-WP-0014 - 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: RAILIANCE-WP-0014-T01
status: done
priority: high
state_hub_task_id: "18d3358b-2cd6-4fe0-aab6-602f85d8cccd"

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: RAILIANCE-WP-0014-T02
status: done
priority: high
state_hub_task_id: "4705a142-4168-41a8-aba0-691d8fc3c6bd"

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: RAILIANCE-WP-0014-T03
status: done
priority: medium
state_hub_task_id: "dd34d578-97e5-4c26-aef8-faafc994c387"

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: RAILIANCE-WP-0014-T04
status: done
priority: high
state_hub_task_id: "457053f2-261f-4c80-92d4-c084e6236e88"

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.