railiance-platform/workplans/RPF-WP-0009-platform-rapp-consistency.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

212 lines
9 KiB
Markdown

---
id: RPF-WP-0009
type: workplan
title: "Platform rapp consistency and deployment-management contract"
domain: financials
repo: railiance-platform
status: finished
owner: codex
topic_slug: railiance
created: "2026-08-11"
updated: "2026-08-13"
related_repos:
- railiance-master
- the-custodian
- reef-railiance
- rapp-openbao
- rapp-postgres
state_hub_workstream_id: "cd85bf28-7050-59a7-9af2-a7455b3df0fb"
---
# RPF-WP-0009 - Platform rapp consistency and deployment-management contract
## Goal
Bring the platform-owned managed workload packages (`rapp-openbao`,
`rapp-postgres`) onto one consistent, verifiable declaration and operations
contract, and establish the S3 pattern that later platform-service rapps are cut
from.
This workplan does **not** own the four-axis repo family model. That model lives
in `railiance-master/docs/repository-axes.md` and is being promoted to custodian
canon separately. S3's job here is to be the first family member that actually
conforms, and to supply the platform-service reference shape.
## Findings that motivate this workplan
Surveyed 2026-08-11 against the live cluster and all six family repos.
The concepts are in better shape than their enforcement. The four families are
cleanly defined and `RMASTER-WP-0018`/`RMASTER-WP-0019` in `railiance-master` are both
`finished`. Nothing, however, validates a declaration file, so the model has
been drifting quietly since the first wave.
1. **The rapp population diverged from the plan of record.** Planned wave 1 was
`rapp-openbao``rapp-vergabe-teilnahme``rapp-forgejo`. Actual is
`rapp-openbao`, plus `rapp-postgres` and `rapp-qonto` created ad hoc from
immediate need. `rapp-vergabe-teilnahme` was never built, so the
*user-facing* wrapper pattern it existed to prove is still unproven while the
platform-service pattern has been proven twice.
2. **`rapp.yaml` has no schema and has drifted three ways.** The bootstrap
contract names eight required fields but no shapes. Result: the
rollout/smoke/rollback contracts are mutually unreadable (`supported_commands`
lists in openbao and postgres versus `default_mode`/`production_gate`,
`required:` and `order:` in qonto); only qonto carries `contract_version`,
`readiness_state`, `data_classification` and `criticality`; only postgres has
`consumer_contract`; `workload_identity.name` is the workload name twice and
the repo name once. `rail.yaml` by contrast is consistent — the rail family
got a tighter contract than the rapp family.
3. **The reef binding registry is stale.** `reef-railiance` declares
`bound_rapps: [rapp-qonto]` while `rapp-openbao` and `rapp-postgres` both run
on Railiance01. The reef's stated purpose is recording what is bound where,
and it missed two of three.
4. **The model is not canon.** Custodian canon has no reef/rail/rapp standard,
and `repo-classification-standard_v1.0` does not admit the prefixes — the
same root cause as the open C-31 failures on `RAPP-*-WP-` work-record ids.
5. **Scale gap.** ~17 live non-system workloads, 3 rapps.
## Decisions taken (2026-08-11, operator-approved)
- **Granularity: grouped by bounded context.** One rapp per cohesive service
group that deploys, versions and rolls back together, not one per deployable.
A grouped rapp must declare its member services explicitly — grouping is only
legitimate where the members share a rollout and rollback fate.
- **Scope split.** S3 owns its own rapps and the platform-service pattern.
Schema, validator and family-model changes are routed to `railiance-master`;
canon promotion is routed to `the-custodian`. S3 does not author them.
- **Canon: promote now**, so `fix-consistency` can validate declarations.
- **Wave-1 gap: build `rapp-vergabe-teilnahme`** to prove the user-facing shape
before further extraction. That build is `railiance-apps`/master territory,
not S3's; this workplan only supplies the platform-service half of the pattern.
## Boundaries
This workplan may:
- change declarations and operations contracts of platform-owned rapps
(`rapp-openbao`, `rapp-postgres` — both declare `ownership_repo: railiance-platform`)
- define the S3 platform-service rapp reference pattern
- define how credential lanes and grant catalog entries bind to a rapp
- send proposals to the repos that own the model, schema and canon
It must not:
- author the four-axis model, the `rapp.yaml` schema, or canon standards here
- edit `reef-railiance`, `rail-*`, or `railiance-master` declarations directly
- absorb platform-wide policy into a rapp (the "shadow S3 repo" failure mode
named in `rapp-first-wave-candidates.md`)
- change any credential gate, grant delivery, or revocation semantic
## Tasks
```task
id: RPF-WP-0009-T01
status: done
priority: high
state_hub_task_id: "512adfef-a561-5b60-b4f3-f60e67696ef9"
```
Publish the S3 platform-service rapp pattern as `docs/rapp-platform-service-pattern.md`:
the reference `rapp.yaml` shape for a platform service, the ownership split
between rapp and S3, the grouped-rapp member declaration rule, and the
credential-lane binding. Generalize from the existing
`docs/rapp-openbao-boundary.md` and `docs/rapp-postgres-boundary.md` rather than
inventing a third boundary vocabulary.
```task
id: RPF-WP-0009-T02
status: done
priority: high
state_hub_task_id: "29b55ae5-74e2-5110-892c-ebb2b0cbf550"
```
Bring `rapp-openbao/declarations/rapp.yaml` and
`rapp-postgres/declarations/rapp.yaml` into a single consistent shape: add
`contract_version`, `readiness_state`, `data_classification` and `criticality`
(present in `rail.yaml` and in `rapp-qonto`, absent in both platform rapps), fix
`workload_identity.name` to be the workload rather than the repo where it drifts,
and align the rollout/smoke/rollback contract shape. Coordinate the target shape
with the `railiance-master` schema proposal (T04) before editing, so the two do
not converge on different answers.
```task
id: RPF-WP-0009-T03
status: done
priority: medium
state_hub_task_id: "53cb32e3-5cdc-5664-b7be-c46828849c56"
```
Correct the reef binding registry: propose to `reef-railiance` that
`bound_rapps` include `rapp-openbao` and `rapp-postgres`, with the evidence that
both are live on Railiance01. Proposal only — `reef-railiance` owns its
declaration. Ask that the binding be derived or checked rather than hand-listed,
since a hand-listed registry is what went stale.
```task
id: RPF-WP-0009-T04
status: done
priority: high
state_hub_task_id: "b157de50-ff34-57aa-800e-d2d79e65a731"
```
Route the schema and validator proposal to `railiance-master`: a
`rapp.schema.json` covering the eight required fields plus the four consistency
fields, a validator that runs over every family declaration, the grouped-rapp
member field, and a refresh of `rapp-first-wave-candidates.md` to reflect what
was actually built and the grouped-context wave-2 inventory.
```task
id: RPF-WP-0009-T05
status: done
priority: medium
state_hub_task_id: "57ed22c9-94b9-526d-beb0-0a090eeaac3a"
```
Route the canon promotion proposal to `the-custodian`: a
`railiance-repo-families` standard, declaration schemas under `canon/standards/schemas/`,
and admission of the `rail-`/`rapp-`/`reef-` prefixes into
`repo-classification-standard` and `work-record-types.yaml` — the latter closing
the open C-31 failures on multi-segment `RAPP-*-WP-` ids.
```task
id: RPF-WP-0009-T06
status: done
priority: medium
state_hub_task_id: "4423fa37-7e0d-5e2d-ac39-f6b505c60243"
```
Define how a rapp binds to its credential lane: the relationship between
`credential-grants/catalog.yaml` entries, CCR lanes, and a rapp's
`runtime_dependencies`/`secret_references`, so that a new rapp has one documented
way to acquire runtime secrets instead of re-deriving it per package. Must not
alter existing gate, delivery or revocation semantics — this documents and binds
the existing lane, it does not build a parallel one.
## Outcome
Session of 2026-08-11: T01 published the S3 platform-service pattern; T03, T04
and T05 routed their proposals to the owning repos (reef-railiance
f0f44ce0, railiance-master 04c776c4, the-custodian cc64764a). T02 was
held until railiance-master settled the schema.
Session of 2026-08-13: T02 done. `rapp-openbao` and `rapp-postgres`
`declarations/rapp.yaml` now pass `schemas/rapp.schema.json` (contract
metadata, `composition`, `bound_reefs: [reef-railiance]`, `commands`,
`smoke_contract.required`, `rollback_contract.order`). Live inventory for
the T06 coverage check is
`docs/evidence/reef-railiance-deployables.json`, refreshable with
`scripts/capture-reef-deployables.py`. Family-validator remainder is
outside this task: `rapp-qonto` still on the pre-schema shape, three
undeclared `rapp-*` engine repos, and `reef-railiance` `bound_rapps`
still hand-listed.
Session of 2026-08-13 (later): T06 done. Binding recipe is
`docs/rapp-credential-lane-binding.md`. Standing secrets bind through
a CCR `target.rapp` + `secret_references`; short-lived leases bind
through grant `rapp_id` (required when the grant id is `rapp-*/…`).
Stamped `rapp-postgres` catalog grants and `CCR-2026-0009`. Gate,
delivery, and revocation semantics are unchanged. Workplan finished.