railiance-master/docs/repo-family-bootstrap-contract.md
codex 654bbe891b 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.
2026-08-14 15:53:30 +02:00

176 lines
6.1 KiB
Markdown

# First-Wave Repo Family Bootstrap Contract
Date: 2026-07-25
## Purpose
Define the minimum bootstrap contract for the first concrete `rail-*`,
`rapp-*`, and `reef-*` repos.
This document exists to keep the first repo-materialization wave coherent.
Without a shared bootstrap contract, each new repo would improvise its own file
layout, declaration shape, and metadata vocabulary, which would weaken the
architecture as soon as the new repo families become real.
## Design Goal
The first concrete repos should be:
- small enough to create quickly
- explicit enough to be queryable by Fabric and State Hub
- narrow enough to avoid reintroducing ownership ambiguity
The goal is not to design a perfect final schema before the first repo exists.
The goal is to establish a minimal, repeatable repo baseline that can evolve
without fragmenting.
## Required Repo Baseline
Every first-wave `rail-*`, `rapp-*`, and `reef-*` repo should start with:
- `.repo-classification.yaml`
- `README.md`
- `INTENT.md`
- `SCOPE.md`
- `AGENTS.md`
- `CLAUDE.md`
- `workplans/`
- `workplans/archived/`
- one repo-family declaration file under `declarations/`
If a repo needs implementation code, manifests, charts, or automation, those
can be added after the bootstrap baseline is in place.
## Required Classification Metadata
The following metadata should be present either directly in
`.repo-classification.yaml` or in the first declaration file and projected from
there into Fabric and State Hub:
- `repo_family`
- `ownership_repo`
- `primary_rail` when applicable
- `supported_rails` when applicable
- `substrate_kind` when applicable
The source-of-truth rule is:
- repo-local declarations define the domain facts
- registry metadata reflects the smallest useful projection of those facts
Do not let registry-only metadata become the only place where a repo family is
described.
## Required Declaration Files
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: `declarations/rail.yaml`
Schema: [`schemas/rail.schema.json`](../schemas/rail.schema.json)
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: `declarations/rapp.yaml`
Schema: [`schemas/rapp.schema.json`](../schemas/rapp.schema.json)
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`.
`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: procurement and cost by
`resource-control`, operation and non-secret attributes by the reef
(`reef-storage` for S3, not `reef-railiance`), the credential by
`railiance-platform`. The rapp consumes a reviewed destination.
### `reef-*`
Path: `declarations/reef.yaml`
Schema: [`schemas/reef.schema.json`](../schemas/reef.schema.json)
`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. A compute reef that hosts rails must set `primary_rail`
and list it in `hosted_rails`. A provider-delegated reef (for example
`reef-storage`, `substrate_kind: object-storage`) omits both: there is no
execution contract to host. Hosting a rail or binding a rapp is topology,
not readiness — see ADR-0006.
## Required Boundary Rules
The first concrete repos must respect the architecture boundaries already
defined in `railiance-master`.
### `rail-*`
- A rail repo owns an execution contract, not substrate bootstrap.
- `rail-kubernetes` must not absorb S2 cluster provisioning, admission
controller ownership, or generic substrate hardening from
`railiance-cluster`.
- A rail repo may own generic workload-on-that-rail semantics, compatibility
guidance, and rail-local helper tooling.
### `rapp-*`
- A `rapp-*` repo owns managed workload packaging and scaffolding.
- A `rapp-*` repo must not become the long-term ownership home of the platform
or application domain around that workload.
- Shared policy, tenant governance, or platform-wide credential semantics stay
in the owning `railiance-*` repo.
### `reef-*`
- A reef repo owns one durable substrate boundary.
- A reef repo must not be created automatically for every machine.
- Grouped reefs remain preferred when the machines are managed as one class,
such as workstation fleets.
## First-Wave Candidates
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
The first-wave repos should be able to participate in:
- State Hub workplan indexing
- Fabric repository registration
- repo-family metadata projection
- later relation projection such as `supports_rail`, `hosts_rail`,
`binds_rapp`, and `governed_by`
They do not need a fully mature graph model on day one, but they do need enough
structured metadata to avoid becoming opaque one-off repos.
## Outcome
The bootstrap contract for the first repo-family wave is:
- one repeatable baseline file set
- one obvious declaration path per repo family
- one clear metadata projection path into Fabric and State Hub
- one narrow initial rollout set covering `rail-*`, `rapp-*`, and `reef-*`