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:
codex 2026-08-13 15:29:07 +02:00
parent d3b3512a60
commit 3cc0dc31d6
20 changed files with 1509 additions and 187 deletions

View file

@ -65,54 +65,51 @@ described.
The first wave should standardize one obvious declaration path per repo family.
The field lists below are an index, not a specification. The JSON Schema for
each family is normative. If this document and a schema disagree, the schema
wins. Shapes, types, enums, and cardinality live in the schema files; do not
restate them here.
### `rail-*`
Path:
Path: `declarations/rail.yaml`
`declarations/rail.yaml`
Schema: [`schemas/rail.schema.json`](../schemas/rail.schema.json)
Minimum fields:
- `rail_id`
- `ownership_repo`
- `execution_architecture`
- `substrate_prerequisites`
- `supported_rollout_modes`
- `compatibility_notes`
A rail is either `composition_kind: base` or `composition_kind: derived`.
A derived rail names its base contract rather than copying it. See
[`docs/rail-composition-contract.md`](rail-composition-contract.md) and
ADR-0005. The live name for substrate needs is
`required_substrate_capabilities`; the earlier `substrate_prerequisites`
label is retired.
### `rapp-*`
Path:
Path: `declarations/rapp.yaml`
`declarations/rapp.yaml`
Schema: [`schemas/rapp.schema.json`](../schemas/rapp.schema.json)
Minimum fields:
A rapp is a composition: a stated purpose, first-party member repos, and
pinned third-party components. Repos to rapps is many-to-many; deployables
to rapps is one-to-one. See ADR-0007. `bound_reefs` is how a rapp names the
reefs it is placed on; that field is the source of a reef's `bound_rapps`.
- `rapp_id`
- `workload_identity`
- `ownership_repo`
- `supported_rails`
- `runtime_dependencies`
- `rollout_contract`
- `smoke_contract`
- `rollback_contract`
`runtime_dependencies` names capabilities, not the resources that satisfy
them. Who provisions a capability (for example the postgres backup object
store) is owned outside the rapp: the bucket by `resource-control`, the
credential by `railiance-platform`. The rapp consumes a reviewed destination.
### `reef-*`
Path:
Path: `declarations/reef.yaml`
`declarations/reef.yaml`
Schema: [`schemas/reef.schema.json`](../schemas/reef.schema.json)
Minimum fields:
- `reef_id`
- `substrate_kind`
- `ownership_repo`
- `lifecycle_state`
- `criticality`
- `hosted_rails`
- `bound_rapps`
- `primary_rail`
`bound_rapps` is a derived projection of every rapp whose `bound_reefs`
lists this reef. It is not a hand-maintained registry. A reef may omit the
field; if it keeps the field, the validator requires an exact match against
the projection. `primary_rail` must appear in `hosted_rails`. Hosting a rail
or binding a rapp is topology, not readiness — see ADR-0006.
## Required Boundary Rules
@ -145,20 +142,11 @@ defined in `railiance-master`.
## First-Wave Candidates
The first materialization wave should target:
- `rail-kubernetes`
- `rapp-openbao`
- `reef-railiance`
The follow-on first-wave candidates after those anchors are stable:
- `rapp-vergabe-teilnahme`
- `reef-coulombcore`
- `reef-ops-workstations`
This keeps the first concrete rollout narrow while still covering all three new
repo families.
The planned first materialization wave was `rail-kubernetes`, `rapp-openbao`,
`reef-railiance`, then `rapp-vergabe-teilnahme`. What was actually built, and
the wave-2 inventory, is recorded in
[`docs/rapp-first-wave-candidates.md`](rapp-first-wave-candidates.md). Do not
restate that list here.
## Integration Expectations