Finish RAILIANCE-WP-0021: family schemas, validator, and ADR-0007
Add rail and reef schemas, derive reef bound_rapps from rapp.bound_reefs, and ship a standalone family-declaration validator with an inventory-fed coverage check. Point the bootstrap contract at the schemas, record the dimension and cardinality decisions in ADR-0007, correct the first-wave candidates document, and release the shape to downstream repos.
This commit is contained in:
parent
d3b3512a60
commit
3cc0dc31d6
20 changed files with 1509 additions and 187 deletions
|
|
@ -1,15 +1,48 @@
|
|||
# First-Wave `rapp-*` Candidates
|
||||
|
||||
Date: 2026-07-25
|
||||
Updated: 2026-08-13 (RAILIANCE-WP-0021-T08)
|
||||
|
||||
## Purpose
|
||||
|
||||
Choose and order the first `rapp-*` candidates for Railiance.
|
||||
Choose and order the first `rapp-*` candidates for Railiance, and record
|
||||
what was actually built against that plan.
|
||||
|
||||
`rapp-*` repos are for managed workload packaging and scaffolding. They are not
|
||||
new ownership homes. The decision here is therefore not "which repos are
|
||||
important?" but "which workloads already have a strong enough package boundary
|
||||
to become first-class managed wrappers without weakening ownership?"
|
||||
`rapp-*` repos are for managed workload packaging and scaffolding. They are
|
||||
not new ownership homes. The decision is not "which repos are important?"
|
||||
but "which workloads already have a strong enough package boundary to become
|
||||
first-class managed wrappers without weakening ownership?"
|
||||
|
||||
## What Was Actually Built
|
||||
|
||||
The 2026-07-25 plan was:
|
||||
|
||||
1. `rapp-openbao`
|
||||
2. `rapp-vergabe-teilnahme`
|
||||
3. `rapp-forgejo` after the forge runtime target stabilized
|
||||
|
||||
What exists on 2026-08-13:
|
||||
|
||||
| Repo | Status | How it arrived |
|
||||
|---|---|---|
|
||||
| `rapp-openbao` | live, declared | as planned |
|
||||
| `rapp-postgres` | live, declared | ad hoc, from the need for a shared platform database |
|
||||
| `rapp-qonto` | live, declared | ad hoc, from the need to run Qonto on `rail-knative` |
|
||||
| `rapp-vergabe-teilnahme` | never built | the user-facing wrapper it existed to prove is unproven |
|
||||
| `rapp-forgejo` | not built | forge placement is now decided (`d151d817`): workload to `rapp-forgejo`, layer to S4 |
|
||||
| `rapp-secrets-engine` | exists, undeclared | family prefix, no `declarations/` |
|
||||
| `rapp-tenant-engine` | exists, undeclared | family prefix, no `declarations/` |
|
||||
| `rapp-user-engine` | exists, undeclared | family prefix, no `declarations/` |
|
||||
|
||||
The platform-service pattern is proven twice (`rapp-openbao`,
|
||||
`rapp-postgres`). The user-facing wrapper pattern is unproven. That is the
|
||||
consequence of building to immediate need instead of to the planned second
|
||||
slot.
|
||||
|
||||
The operator decision that follows is: build `rapp-vergabe-teilnahme` to
|
||||
prove the user-facing shape before mass extraction. Do not treat the three
|
||||
engine repos, or any other live undeclared workload, as a substitute for
|
||||
that proof.
|
||||
|
||||
## Selection Criteria
|
||||
|
||||
|
|
@ -23,147 +56,159 @@ The first-wave candidates should satisfy most of the following:
|
|||
- low ambiguity between packaging ownership and domain ownership
|
||||
- good demonstration value for later `rapp-*` extractions
|
||||
|
||||
## Assessed Candidates
|
||||
## Planned First-Wave Assessment (2026-07-25)
|
||||
|
||||
The original assessment is kept below so the gap between plan and outcome
|
||||
stays visible. It is not the current worklist.
|
||||
|
||||
### 1. OpenBao from `railiance-platform`
|
||||
|
||||
Assessment: **choose first**
|
||||
Assessment: **choose first** — and this one landed.
|
||||
|
||||
Why it fits:
|
||||
Why it fitted:
|
||||
|
||||
- It is a clear third-party upstream product with durable identity.
|
||||
- The workload already has a substantial Railiance packaging surface:
|
||||
`helm/openbao-values.yaml`, middleware, UI overlay assets, deploy/verify
|
||||
scripts, and operator runbooks.
|
||||
- The repo already distinguishes between the OpenBao workload itself and the
|
||||
wider S3 platform policy that consumes it.
|
||||
- It is important enough to prove that `rapp-*` is not only for user-facing
|
||||
apps; platform services can also be managed workloads.
|
||||
- The workload already had a substantial Railiance packaging surface.
|
||||
- The repo already distinguished the OpenBao workload from the wider S3
|
||||
platform policy that consumes it.
|
||||
- It proved that `rapp-*` is not only for user-facing apps.
|
||||
|
||||
What should move into `rapp-openbao`:
|
||||
|
||||
- Helm values and Kubernetes-facing package assets for the OpenBao workload
|
||||
- UI overlay wrapper assets
|
||||
- generic deploy, verify, and workload-health runbooks
|
||||
- workload-specific smoke and recovery expectations
|
||||
|
||||
What should remain in `railiance-platform`:
|
||||
|
||||
- the S3 ownership of secrets custody as a platform capability
|
||||
- workload lane policy, credential approval, and platform-wide access models
|
||||
- cross-workload secret-delivery conventions consumed by many workloads
|
||||
|
||||
Conclusion:
|
||||
|
||||
`rapp-openbao` should be the first `rapp-*` extraction.
|
||||
What stayed in `railiance-platform`: secrets custody as a platform
|
||||
capability, lane policy, credential approval, and cross-workload
|
||||
secret-delivery conventions.
|
||||
|
||||
### 2. Forge workload from `railiance-forge`
|
||||
|
||||
Assessment: **defer from first wave**
|
||||
Assessment then: **defer from first wave**. That deferral still holds as a
|
||||
first-wave fact, but the placement question is now closed. Decision
|
||||
`d151d817` puts the Forgejo workload in `rapp-forgejo` and the layer
|
||||
responsibility (runner placement and labels, registry retention, artifact
|
||||
lifecycle, package credentials) in S4 `railiance-enablement`.
|
||||
`railiance-forge` is placed, not retired. Gitea is confirmed replaced.
|
||||
|
||||
Why it is not first:
|
||||
|
||||
- The current live workload is still Gitea on CoulombCore.
|
||||
- The intended production direction is Forgejo on Railiance01.
|
||||
- Packaging identity is therefore not stable enough yet: extracting now would
|
||||
either enshrine a temporary Gitea compatibility package or pretend the
|
||||
Forgejo cutover is already complete.
|
||||
- The runtime and migration story still spans current Gitea operation, future
|
||||
Forgejo deployment, runner substrate, registries, and cutover sequencing.
|
||||
|
||||
Decision:
|
||||
|
||||
- Do **not** make the forge workload the first `rapp-*` extraction.
|
||||
- Prefer `rapp-forgejo` as the eventual target package once the production
|
||||
direction is the real operating target.
|
||||
- Create `rapp-gitea` only if Railiance discovers it needs a long-lived
|
||||
compatibility wrapper for the current workload rather than a short migration
|
||||
bridge.
|
||||
|
||||
What this means:
|
||||
|
||||
- `railiance-forge` keeps runtime ownership for now.
|
||||
- The forge wrapper should follow after the current Gitea-versus-Forgejo
|
||||
packaging identity stops moving.
|
||||
|
||||
Conclusion:
|
||||
|
||||
The forge workload is packaging-worthy, but it should not be first-wave
|
||||
`rapp-*`.
|
||||
`rapp-forgejo` is therefore a wave-2 package with a decided home, not an
|
||||
open placement debate.
|
||||
|
||||
### 3. User-facing S5 workload from `railiance-apps`
|
||||
|
||||
Assessment: **choose `vergabe-teilnahme` for wave 1**
|
||||
Assessment then: **choose `vergabe-teilnahme` for wave 1**. It was never
|
||||
built. The reasons it was the right user-facing slot remain: one named
|
||||
workload, explicit release surface, secret handling that is not entangled
|
||||
with shared platform semantics. That is why it is still the package that
|
||||
must prove the user-facing shape before mass extraction.
|
||||
|
||||
Why `vergabe-teilnahme` wins the S5 slot:
|
||||
`reuse-surface` remains the strongest follow-on self-built service
|
||||
candidate. `core-hub` should still wait.
|
||||
|
||||
- It is clearly user-facing and already operates as one named workload package.
|
||||
- Its release surface is explicit: chart, values, ingress, deployment targets,
|
||||
migration command, smoke checks, and operator runbook.
|
||||
- Secret handling is clear without being entangled with shared platform
|
||||
semantics: app credentials are consumed from Kubernetes Secrets and the app
|
||||
env secret is locally rebuilt by operator procedure.
|
||||
- It is simpler and more stable than the current Core Hub / Inter-Hub history
|
||||
and more obviously user-facing than service-style workloads such as
|
||||
`reuse-surface`.
|
||||
## Wave-2 Inventory
|
||||
|
||||
What should move into `rapp-vergabe-teilnahme`:
|
||||
Grouped by bounded context, in the composition shape from ADR-0007. These
|
||||
are indicative packages, not created repos. A package is listed only where
|
||||
members share rollout and rollback fate. Names that already exist as
|
||||
undeclared `rapp-*` repos are marked so they are not invented twice.
|
||||
|
||||
- the chart and workload values
|
||||
- the ingress and app-specific release runbook
|
||||
- workload-specific rollout, migration, smoke, and rollback guidance
|
||||
- workload-specific secret consumption contract
|
||||
### `rapp-vergabe-teilnahme` — prove the user-facing wrapper
|
||||
|
||||
What should remain in `railiance-apps`:
|
||||
```yaml
|
||||
composition:
|
||||
purpose: Package the Vergabe Teilnahme application as a managed user-facing workload.
|
||||
member_repos:
|
||||
- repo: vergabe-teilnahme
|
||||
role: application source and chart
|
||||
deployables: [vergabe-teilnahme]
|
||||
```
|
||||
|
||||
- S5 ownership of generic application release patterns
|
||||
- reusable onboarding and operator recipes
|
||||
- cross-app S5 guardrails that should not be duplicated per workload package
|
||||
Build this before any further user-facing extraction.
|
||||
|
||||
Second-wave S5 note:
|
||||
### `rapp-forgejo` — decided placement
|
||||
|
||||
- `reuse-surface` is the strongest follow-on self-built service candidate after
|
||||
`vergabe-teilnahme`, because it already shows explicit OpenBao-backed runtime
|
||||
secret lanes and a tidy single-workload chart surface.
|
||||
- `core-hub` and retired `inter-hub` should wait because their packaging
|
||||
history is still entangled with cutover and legacy service evolution.
|
||||
```yaml
|
||||
composition:
|
||||
purpose: Package Forgejo, its runner, and the package registry as one managed forge.
|
||||
member_repos:
|
||||
- repo: railiance-forge
|
||||
role: operational helm, manifests, runner, and registry assets
|
||||
deployables: [forgejo, forgejo-runner, forgejo-registry]
|
||||
```
|
||||
|
||||
Conclusion:
|
||||
Layer concerns stay in `railiance-enablement`. Do not create `rapp-gitea`.
|
||||
|
||||
`rapp-vergabe-teilnahme` should be the first user-facing S5 `rapp-*`.
|
||||
### `rapp-netkingdom-identity` — identity bounded context
|
||||
|
||||
## First-Wave Order
|
||||
```yaml
|
||||
composition:
|
||||
purpose: Package NetKingdom identity — users, tenants, SSO, MFA, and authorization — as one rollback unit.
|
||||
member_repos:
|
||||
- repo: user-engine
|
||||
role: user identity
|
||||
deployables: [user-engine]
|
||||
- repo: tenant-engine
|
||||
role: tenant identity
|
||||
deployables: [tenant-engine]
|
||||
- repo: key-cape
|
||||
role: SSO and MFA
|
||||
deployables: [keycloak]
|
||||
- repo: flex-auth
|
||||
role: authorization decisions
|
||||
deployables: [flex-auth]
|
||||
```
|
||||
|
||||
The recommended order is:
|
||||
`rapp-user-engine` and `rapp-tenant-engine` already exist as undeclared
|
||||
prefix claims. They are not separate rapps under grouped-by-bounded-context
|
||||
granularity. Their owners should either fold them into this package or
|
||||
justify an independent rollback fate and then declare them. `rapp-secrets-engine`
|
||||
is the same question against `rapp-openbao` / `railiance-platform`, not a
|
||||
fourth identity member.
|
||||
|
||||
1. `rapp-openbao`
|
||||
2. `rapp-vergabe-teilnahme`
|
||||
3. `rapp-forgejo` after the forge runtime target is stable enough to avoid
|
||||
immediate rename or migration churn
|
||||
### `rapp-coulomb-social`
|
||||
|
||||
This order is intentional.
|
||||
```yaml
|
||||
composition:
|
||||
purpose: Package the Coulomb Social application as a managed user-facing workload.
|
||||
member_repos:
|
||||
- repo: coulomb-social
|
||||
role: application
|
||||
deployables: [coulomb-social]
|
||||
```
|
||||
|
||||
- `rapp-openbao` proves the third-party platform-service wrapper model.
|
||||
- `rapp-vergabe-teilnahme` proves the self-built user-facing app wrapper model.
|
||||
- The forge wrapper then follows with a clearer target identity and after the
|
||||
first two wrappers have established the pattern.
|
||||
Do not start this until `rapp-vergabe-teilnahme` has proven the user-facing
|
||||
shape.
|
||||
|
||||
### `rapp-helix-forge`
|
||||
|
||||
```yaml
|
||||
composition:
|
||||
purpose: Package the Helix Forge methodological workspace as a managed workload.
|
||||
member_repos:
|
||||
- repo: helix-forge
|
||||
role: capability-first development ecosystem
|
||||
deployables: [helix-forge]
|
||||
```
|
||||
|
||||
Helix Forge is a different lineage from `railiance-forge`. It is not a
|
||||
rename of `rapp-forgejo`.
|
||||
|
||||
## Risks To Watch
|
||||
|
||||
- If `rapp-openbao` absorbs platform-wide policy and credential-governance
|
||||
logic, the wrapper will become a shadow S3 repo.
|
||||
- If `rapp-vergabe-teilnahme` absorbs generic S5 onboarding or app recipes, it
|
||||
will weaken `railiance-apps` as the shared S5 release home.
|
||||
- If the forge wrapper is extracted too early, Railiance will immediately face
|
||||
a Gitea-versus-Forgejo package rename or parallel-wrapper problem.
|
||||
logic, the wrapper becomes a shadow S3 repo.
|
||||
- If `rapp-postgres` is asked to mint the backup account, key, or bucket, a
|
||||
consumed destination is being mistaken for package ownership. The bucket
|
||||
is `resource-control` (`RESOURCE-WP-0002`); the credential is
|
||||
`railiance-platform` OpenBao custody; purchase is decision `9c21c0e0`.
|
||||
- If `rapp-vergabe-teilnahme` absorbs generic S5 onboarding, it weakens
|
||||
`railiance-apps`.
|
||||
- If the three undeclared engine repos are treated as rapps without a
|
||||
declaration, the coverage check cannot see them and will list their live
|
||||
deployables as uncovered.
|
||||
- If wave-2 extraction starts before the user-facing wrapper is proven,
|
||||
Railiance will mass-produce the platform-service shape and still not know
|
||||
whether the other shape works.
|
||||
|
||||
## Outcome
|
||||
|
||||
Railiance now has a concrete first-wave `rapp-*` sequence:
|
||||
|
||||
- first `rapp-openbao`
|
||||
- then `rapp-vergabe-teilnahme`
|
||||
- then the forge wrapper once the production package identity is stable
|
||||
|
||||
That is enough to start repo-local extraction planning without pretending every
|
||||
workload needs its own `rapp` immediately.
|
||||
Wave 1 proved the platform-service wrapper, twice, and did not prove the
|
||||
user-facing wrapper. The next package that must exist is
|
||||
`rapp-vergabe-teilnahme`. Everything else in the wave-2 inventory waits on
|
||||
that proof, on owner-side declaration of the three undeclared prefix
|
||||
claims, and on the schema migration owned by `RAILIANCE-WP-0015-T02`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue