feat: allow provider-delegated reefs with no rail

Object-storage reefs omit primary_rail and hosted_rails. Scaleway
operates S3; reef-storage only names the boundary. Finish
RMASTER-WP-0022.
This commit is contained in:
codex 2026-08-14 15:53:30 +02:00
parent 82b7b7295d
commit 654bbe891b
8 changed files with 67 additions and 32 deletions

View file

@ -93,7 +93,7 @@ owner. Until it is made, treat the permissive rule as provisional.
JSON Schema cannot express these; `tools/validate-family-declarations.py` does:
- `primary_rail` must appear in `supported_rails` (rapp) or `hosted_rails` (reef)
- `primary_rail` must appear in `supported_rails` (rapp) or, when set, in `hosted_rails` (reef). A reef may omit both when it hosts no rail.
- reef `bound_rapps`, if present, must match the projection of `rapp.bound_reefs`
- a rapp `ownership_repo` must not be the rapp repo itself
- declared member repos, named rails, and named reefs must resolve on disk
@ -128,8 +128,10 @@ conform. That is the intended contrast with the rapp family.
normative change: `bound_rapps` is no longer a hand-maintained required field.
Required on every reef: `kind`, `reef_id`, `repo`, `ownership_repo`,
`substrate_kind`, `lifecycle_state`, `criticality`, `primary_rail`,
`hosted_rails`, `current_members`.
`substrate_kind`, `lifecycle_state`, `criticality`, `current_members`.
`primary_rail` and `hosted_rails` are required only when the reef hosts
rails. `current_members` may be empty on a planned provider-delegated
reef.
`bound_rapps` is optional. Its source of truth is `rapp.bound_reefs`. The
validator inverts that field. If a reef still lists `bound_rapps`, the list