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
137 lines
5 KiB
Markdown
137 lines
5 KiB
Markdown
---
|
|
id: RPF-WP-0008
|
|
type: workplan
|
|
title: "Credential-change test suite stabilization"
|
|
domain: financials
|
|
repo: railiance-platform
|
|
status: finished
|
|
owner: codex
|
|
topic_slug: railiance
|
|
created: "2026-08-11"
|
|
updated: "2026-08-11"
|
|
related_repos:
|
|
- rapp-postgres
|
|
- ops-warden
|
|
state_hub_workstream_id: "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
|
|
|
|
```task
|
|
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.
|
|
|
|
```task
|
|
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.
|
|
|
|
```task
|
|
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.
|
|
|
|
```task
|
|
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.
|