docs: complete canon alignment housekeeping
This commit is contained in:
parent
490c2d97b1
commit
debbc13b40
14 changed files with 397 additions and 81 deletions
36
workplans/archived/260818-ADHOC-2026-07-30.md
Normal file
36
workplans/archived/260818-ADHOC-2026-07-30.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
id: ADHOC-2026-07-30
|
||||
type: workplan
|
||||
title: "Ad-hoc Railiance framework maintenance on 2026-07-30"
|
||||
domain: financials
|
||||
repo: railiance-master
|
||||
status: archived
|
||||
owner: codex
|
||||
topic_slug: railiance
|
||||
created: "2026-07-30"
|
||||
updated: "2026-08-18"
|
||||
state_hub_workstream_id: "1cc4d75f-9bd8-4843-8b18-5ce9637edd60"
|
||||
---
|
||||
|
||||
# Ad-hoc maintenance - 2026-07-30
|
||||
|
||||
## Restore Forgejo repository descriptions
|
||||
|
||||
```task
|
||||
id: ADHOC-2026-07-30-T01
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "9fad2db0-f596-4548-b1b9-f81bd1736014"
|
||||
```
|
||||
|
||||
Compared both public pages of the retired Gitea `coulomb` organization with
|
||||
both public pages of Forgejo. Gitea retained nonempty descriptions for 79
|
||||
migrated repositories; Forgejo had lost or replaced all 79. Restored the
|
||||
normalized Gitea descriptions through the existing activity-core
|
||||
ExternalSecret-backed Forgejo administrative boundary. Repositories created
|
||||
only in Forgejo were initially left untouched; the four that remained blank
|
||||
(`fin-hub`, `forgejo-actions-probe`, `railiance-bootstrap`, and
|
||||
`railiance-hosts`) then received descriptions derived from their local
|
||||
scope/intent metadata or explicit probe purpose. All 100 Forgejo repositories
|
||||
now have nonempty descriptions. No credential value left the cluster or
|
||||
entered recorded output.
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
---
|
||||
id: RMASTER-WP-0017
|
||||
type: workplan
|
||||
title: "Rail, Rapp, and Reef Repo Separation"
|
||||
domain: financials
|
||||
repo: railiance-master
|
||||
status: archived
|
||||
owner: codex
|
||||
topic_slug: railiance
|
||||
planning_priority: high
|
||||
planning_order: 17
|
||||
created: "2026-07-25"
|
||||
updated: "2026-08-18"
|
||||
related_repos:
|
||||
- railiance-master
|
||||
- railiance-cluster
|
||||
- railiance-platform
|
||||
- railiance-apps
|
||||
- railiance-forge
|
||||
- railiance-fabric
|
||||
- railiance-infra
|
||||
- railiance-hosts
|
||||
state_hub_workstream_id: "dd794e38-6da0-4acd-8ad8-e00bd2aa62bc"
|
||||
---
|
||||
|
||||
# RMASTER-WP-0017 - Rail, Rapp, and Reef Repo Separation
|
||||
|
||||
## Goal
|
||||
|
||||
Turn the newly defined `rail-*`, `rapp-*`, and `reef-*` concepts into an
|
||||
executable migration plan for the current Railiance repo family, so the
|
||||
framework can evolve without leaving workload execution semantics, workload
|
||||
packaging, and substrate realities mixed into the existing ownership repos.
|
||||
|
||||
This workplan is explicitly cross-repo. It belongs in `railiance-master`
|
||||
because no single implementation repo can own the migration end to end.
|
||||
|
||||
## Current Starting Point
|
||||
|
||||
The framework baseline is now recorded in `railiance-master`:
|
||||
|
||||
- `docs/repository-axes.md`
|
||||
- `docs/reef-substrate-model.md`
|
||||
- `docs/adr/ADR-0001-repository-prefix-architecture.md`
|
||||
|
||||
The repo is also now prepared and registered with State Hub as the architecture
|
||||
home for future multi-repo Railiance work.
|
||||
|
||||
The architectural direction is now further clarified:
|
||||
|
||||
- wave 1 is centered on `rail-kubernetes` as the default base rail
|
||||
- new rails are introduced only for concrete workload needs with a sound
|
||||
runtime argument
|
||||
- `rail-knative` is the first expected follow-on rail, driven by the need to
|
||||
support `qonto-assistent`, but only after the Kubernetes rail boundary is
|
||||
clean
|
||||
- `rapp-*` repos are about managed wrapping and scaffolding, not ownership
|
||||
- `reef-*` repos are about compute resources organized for a defined purpose
|
||||
- mixed-rail reefs are acceptable early, but production-grade cases should
|
||||
prefer clearer substrate and primary-rail separation unless deliberately
|
||||
justified
|
||||
|
||||
The remaining problem is implementation reality:
|
||||
|
||||
- `railiance-cluster` still owns Kubernetes-specific workload lifecycle and
|
||||
overlay semantics that should eventually become `rail-kubernetes`
|
||||
- first-class workload wrappers are still spread across `railiance-apps`,
|
||||
`railiance-platform`, and `railiance-forge`
|
||||
- substrate reality is under-described and split between `railiance-infra` and
|
||||
`railiance-hosts`
|
||||
- `railiance-fabric` and State Hub do not yet model rails, `rapp`s, or reefs
|
||||
as first-class entities
|
||||
|
||||
## Target Outcome
|
||||
|
||||
When this workplan is complete:
|
||||
|
||||
1. Railiance has a clear first migration target for `rail-kubernetes`.
|
||||
2. The first set of `rapp-*` candidates is chosen and ordered.
|
||||
3. The first `reef-*` rollout rule is chosen for current named substrates.
|
||||
4. `railiance-fabric` and State Hub have a defined integration path for the new
|
||||
repo families.
|
||||
5. The current repo set has an approved separation plan, not only a naming idea.
|
||||
|
||||
## Boundaries
|
||||
|
||||
This workplan may define, sequence, and coordinate repo splits.
|
||||
|
||||
It must not silently move implementation content between repos without explicit
|
||||
repo-local follow-up workplans or commits in those repos.
|
||||
|
||||
## Tasks
|
||||
|
||||
## T01 - Record the framework repo-family baseline in railiance-master
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0017-T01
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "7cb6769a-5557-46e5-8e20-c492e5049604"
|
||||
```
|
||||
|
||||
Record the first canonical architecture baseline for:
|
||||
|
||||
- `railiance-*` as ownership repos
|
||||
- `rail-*` as execution-contract repos
|
||||
- `rapp-*` as managed workload package repos
|
||||
- `reef-*` as substrate-boundary repos
|
||||
|
||||
Acceptance:
|
||||
|
||||
- `railiance-master` contains the baseline documents and ADR
|
||||
- the `reef-*` model is explicitly defined and bounded against repo explosion
|
||||
|
||||
## T02 - Prepare railiance-master as the cross-repo workplan home
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0017-T02
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "17be5faa-cba2-4838-97af-dc3b79e0511b"
|
||||
```
|
||||
|
||||
Prepare and register `railiance-master` in State Hub so cross-repo architecture
|
||||
work can live here as first-class workplans.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- repo is classification-registered
|
||||
- repo passes `statehub fix-consistency`
|
||||
- workplan and architecture files can now be indexed from this repo
|
||||
|
||||
## T03 - Define the `rail-kubernetes` extraction boundary
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0017-T03
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "e25ea023-e2fe-44b9-96c1-cca19c65053f"
|
||||
```
|
||||
|
||||
Define what moves from `railiance-cluster` into a future `rail-kubernetes`
|
||||
repo, and what must remain owned by `railiance-cluster`.
|
||||
|
||||
This is the wave-1 architecture task. It must treat `rail-kubernetes` as the
|
||||
default base rail for the current ecosystem rather than as one option among
|
||||
many equally urgent rails.
|
||||
|
||||
At minimum, decide the boundary for:
|
||||
|
||||
- `railiance/app.toml`
|
||||
- promotion lifecycle semantics
|
||||
- overlay repo pattern
|
||||
- stage-1/2/3 tooling
|
||||
- cluster-runtime prerequisites versus workload-runtime semantics
|
||||
- the compatibility path future rails such as `rail-knative` will rely on
|
||||
|
||||
Acceptance:
|
||||
|
||||
- one written boundary contract names what `railiance-cluster` keeps
|
||||
- one written boundary contract names what `rail-kubernetes` must own
|
||||
- at least one migration-safe path exists that does not break current users
|
||||
- the boundary leaves a coherent follow-on path for `rail-knative` without
|
||||
forcing knative design decisions into wave 1
|
||||
|
||||
2026-07-25: Added `docs/rail-kubernetes-boundary.md` and
|
||||
`docs/adr/ADR-0002-rail-kubernetes-wave-1-boundary.md`. The boundary now names
|
||||
the retained S2 substrate scope, the extracted Kubernetes rail contract, the
|
||||
rehome-required workload-specific helpers, and a compatibility-preserving split
|
||||
sequence.
|
||||
|
||||
## T04 - Identify and sequence the first `rapp-*` candidates
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0017-T04
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "674b1a4f-2c5b-499c-b26f-9ed4f9f0861c"
|
||||
```
|
||||
|
||||
Choose the first workload packages that should become first-class `rapp-*`
|
||||
repos instead of remaining embedded inside ownership repos.
|
||||
|
||||
This task must treat `rapp-*` as managed workload packaging for third-party or
|
||||
self-built workloads in the Railiance and Net Kingdom context. It must not
|
||||
turn `rapp-*` into an ownership mirror of existing `railiance-*` repos.
|
||||
|
||||
Candidate set to assess:
|
||||
|
||||
- Forgejo or Gitea from `railiance-forge`
|
||||
- OpenBao from `railiance-platform`
|
||||
- one user-facing S5 workload from `railiance-apps`
|
||||
|
||||
Acceptance:
|
||||
|
||||
- first-wave `rapp-*` candidates are named
|
||||
- rationale is recorded for each chosen or deferred candidate
|
||||
- split order is defined so ownership boundaries do not get weaker during migration
|
||||
- each chosen candidate is justified as a managed wrapper and not as a new
|
||||
ownership home
|
||||
|
||||
2026-07-25: Added `docs/rapp-first-wave-candidates.md` and
|
||||
`docs/adr/ADR-0003-rapp-first-wave-selection.md`. The first-wave order is now
|
||||
`rapp-openbao`, then `rapp-vergabe-teilnahme`, with the forge workload
|
||||
explicitly deferred until the Gitea-versus-Forgejo package target is stable
|
||||
enough to avoid immediate wrapper churn.
|
||||
|
||||
## T05 - Decide the first `reef-*` rollout for current substrates
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0017-T05
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "53c63266-fbcb-4644-86f4-042e7b80744e"
|
||||
```
|
||||
|
||||
Apply the new reef model to the current Railiance substrate reality and decide
|
||||
whether the first rollout should be:
|
||||
|
||||
- `reef-coulombcore`
|
||||
- `reef-railiance`
|
||||
- `reef-workstation`
|
||||
- or a grouped substrate such as `reef-ops-workstations`
|
||||
|
||||
This task must also resolve the conceptual overlap between `railiance-infra`
|
||||
and `railiance-hosts`.
|
||||
|
||||
It should treat reefs as compute resources organized for a defined purpose and
|
||||
should explicitly decide how much multi-rail mixing is acceptable in early
|
||||
substrates such as `RAILIANCE01`.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- first-wave reef repo set is chosen
|
||||
- the rule for singleton versus grouped reef repos is applied to current hosts
|
||||
- the `railiance-hosts` versus `railiance-infra` ambiguity has a documented direction
|
||||
- any provisional terminology for transitional substrates is kept provisional
|
||||
unless the pattern is stable enough to canonize
|
||||
|
||||
2026-07-25: Added `docs/reef-first-wave-rollout.md` and
|
||||
`docs/adr/ADR-0004-first-wave-reef-rollout.md`. The first rollout is now
|
||||
`reef-railiance`, `reef-coulombcore`, and `reef-ops-workstations`, with
|
||||
`railiance-infra` chosen as the canonical S1 ownership repo and transitional
|
||||
substrate nicknames intentionally left provisional.
|
||||
|
||||
## T06 - Define `railiance-fabric` and State Hub adaptation for the new repo families
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0017-T06
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "4f47d000-6495-4163-8673-f339dd7ef41f"
|
||||
```
|
||||
|
||||
Define the minimum graph and coordination changes needed so rails, `rapp`s, and
|
||||
reefs are not only naming conventions but visible ecosystem entities.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- `railiance-fabric` adaptation requirements are listed
|
||||
- State Hub registration/indexing implications are listed
|
||||
- the minimum fields or declarations needed in future `rail-*`, `rapp-*`, and
|
||||
`reef-*` repos are recorded
|
||||
|
||||
2026-07-25: Added `docs/fabric-state-hub-adaptation.md`. The minimum
|
||||
adaptation requirements now cover repo-family metadata, Fabric onboarding
|
||||
updates, typed service/relation vocabulary, and the smallest repo-local
|
||||
declaration surface future `rail-*`, `rapp-*`, and `reef-*` repos must expose.
|
||||
|
||||
## T07 - Launch the first migration wave into concrete repo-local follow-up work
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0017-T07
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "e762c05a-c6f1-439e-98e2-bf4d7b312a74"
|
||||
```
|
||||
|
||||
Create the concrete follow-up workplans in the affected implementation repos for
|
||||
the first migration wave.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- at least one repo-local workplan exists for `rail-kubernetes`
|
||||
- at least one repo-local workplan exists for a first `rapp-*` extraction
|
||||
- at least one repo-local workplan exists for a first `reef-*` rollout or substrate cleanup
|
||||
- this master workplan can then govern sequencing rather than holding all implementation detail itself
|
||||
|
||||
2026-07-25: Added the first repo-local follow-up workplans:
|
||||
|
||||
- `railiance-cluster/workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md`
|
||||
- `railiance-platform/workplans/RAILIANCE-WP-0012-rapp-openbao-extraction-boundary.md`
|
||||
- `railiance-infra/workplans/RAIL-HO-WP-0007-first-reef-rollout-and-s1-canonicalization.md`
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
- [x] The architecture baseline is recorded in `railiance-master`
|
||||
- [x] `railiance-master` is registered and synced with State Hub
|
||||
- [x] `rail-kubernetes` boundary is written and approved
|
||||
- [x] first `rapp-*` candidates and split order are written and approved
|
||||
- [x] first `reef-*` rollout decision is written and approved
|
||||
- [x] Fabric and State Hub adaptation requirements are written
|
||||
- [x] first migration-wave follow-up workplans exist in the affected repos
|
||||
|
||||
## Notes
|
||||
|
||||
This workplan is intended to stay small at the framework level. Once a split or
|
||||
migration has a concrete owner, the implementation detail should move into the
|
||||
relevant repo-local workplan rather than expanding this file into a second
|
||||
control plane.
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
---
|
||||
id: RMASTER-WP-0018
|
||||
type: workplan
|
||||
title: "First-Wave Repo Family Materialization"
|
||||
domain: financials
|
||||
repo: railiance-master
|
||||
status: archived
|
||||
owner: codex
|
||||
topic_slug: railiance
|
||||
planning_priority: high
|
||||
planning_order: 18
|
||||
created: "2026-07-25"
|
||||
updated: "2026-08-18"
|
||||
related_repos:
|
||||
- railiance-master
|
||||
- railiance-cluster
|
||||
- railiance-platform
|
||||
- railiance-infra
|
||||
- railiance-fabric
|
||||
state_hub_workstream_id: "054a494c-e430-4164-b2c3-e32e759cc3e0"
|
||||
---
|
||||
|
||||
# RMASTER-WP-0018 - First-Wave Repo Family Materialization
|
||||
|
||||
## Goal
|
||||
|
||||
Turn the completed separation architecture into the first concrete
|
||||
`rail-*`, `rapp-*`, and `reef-*` repo materialization wave.
|
||||
|
||||
This workplan governs the first implementation wave that makes the new repo
|
||||
families real rather than only defined. It stays in `railiance-master` because
|
||||
the sequencing still spans multiple ownership repos and Fabric integration.
|
||||
|
||||
## Why This Exists
|
||||
|
||||
`RMASTER-WP-0017` completed the architecture baseline and launched the first
|
||||
repo-local follow-up workplans.
|
||||
|
||||
What is still missing is the shared control plane for:
|
||||
|
||||
- creating the first concrete repo-family baselines
|
||||
- keeping their boundaries consistent across repos
|
||||
- aligning repo-local declarations with Fabric and State Hub ingestion
|
||||
- preventing the first repo creations from drifting into ad hoc local patterns
|
||||
|
||||
## Current Starting Point
|
||||
|
||||
The architecture baseline already exists in `railiance-master`:
|
||||
|
||||
- `docs/repository-axes.md`
|
||||
- `docs/rail-kubernetes-boundary.md`
|
||||
- `docs/rapp-first-wave-candidates.md`
|
||||
- `docs/reef-first-wave-rollout.md`
|
||||
- `docs/fabric-state-hub-adaptation.md`
|
||||
|
||||
The first implementation follow-up work also already exists:
|
||||
|
||||
- `railiance-cluster/workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md`
|
||||
- `railiance-platform/workplans/RAILIANCE-WP-0012-rapp-openbao-extraction-boundary.md`
|
||||
- `railiance-infra/workplans/RAIL-HO-WP-0007-first-reef-rollout-and-s1-canonicalization.md`
|
||||
- `railiance-fabric/workplans/RAIL-FAB-WP-0025-rail-rapp-reef-fabric-adaptation.md`
|
||||
|
||||
Fabric now has first repo-family-aware repository metadata, but the ecosystem
|
||||
still lacks:
|
||||
|
||||
- the first actual `rail-*` repo
|
||||
- the first actual `rapp-*` repo
|
||||
- the first actual `reef-*` repo
|
||||
- relation projection for rail/rapp/reef topology
|
||||
|
||||
## Target Outcome
|
||||
|
||||
When this workplan is complete:
|
||||
|
||||
1. Railiance has a repeatable bootstrap contract for first-wave `rail-*`,
|
||||
`rapp-*`, and `reef-*` repos.
|
||||
2. The first concrete `rail-kubernetes` repo exists and is registered.
|
||||
3. The first concrete `rapp-openbao` repo exists and is registered.
|
||||
4. The first concrete `reef-railiance` repo exists and is registered.
|
||||
5. Fabric can project the minimum rail/rapp/reef relation topology needed to
|
||||
answer placement questions.
|
||||
|
||||
## Boundaries
|
||||
|
||||
This workplan may coordinate repo creation, repo-family bootstrap, and graph
|
||||
integration across Railiance repos.
|
||||
|
||||
It must not weaken the existing ownership boundaries:
|
||||
|
||||
- `railiance-cluster` remains the S2 ownership home
|
||||
- `railiance-platform` remains the S3 ownership home for OpenBao
|
||||
- `railiance-infra` remains the canonical S1 ownership home for first-wave reefs
|
||||
- `railiance-fabric` remains the implementation home for graph ingestion and
|
||||
projection
|
||||
|
||||
## Tasks
|
||||
|
||||
## T01 - Publish the first-wave repo bootstrap contract
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0018-T01
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "d6ba9286-222d-49d2-83e9-fd251c534dde"
|
||||
```
|
||||
|
||||
Record the minimum bootstrap contract future `rail-*`, `rapp-*`, and
|
||||
`reef-*` repos should follow so the first materialization wave does not invent
|
||||
three incompatible patterns.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- one framework document defines the minimum file baseline
|
||||
- one framework document defines the first declaration path per repo family
|
||||
- the metadata projection rule into Fabric and State Hub is named
|
||||
|
||||
2026-07-25: Added `docs/repo-family-bootstrap-contract.md`.
|
||||
|
||||
## T02 - Launch the first `rail-kubernetes` repo materialization
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0018-T02
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "726a0c5c-2fa5-4bb9-a730-3200abc40ac8"
|
||||
```
|
||||
|
||||
Create the concrete repo bootstrap and extraction path for `rail-kubernetes`
|
||||
using the boundary already defined in `railiance-master` and the repo-local
|
||||
follow-up work already opened in `railiance-cluster`.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- the new repo has the required baseline files
|
||||
- the repo declares the Kubernetes rail contract in source-controlled form
|
||||
- the compatibility path from `railiance-cluster` is preserved
|
||||
- the repo is ready for Fabric and State Hub registration
|
||||
|
||||
2026-07-25: Bootstrapped `/home/worsch/rail-kubernetes` with the baseline
|
||||
repo files, `declarations/rail.yaml`, repo-local docs, and
|
||||
`RAIL-K8S-WP-0001`. The repo is now registered in State Hub and seeded into
|
||||
`railiance-fabric/registry/railiance-repos.yaml`; live Fabric registry sync and
|
||||
had initially not yet been pushed to a remote.
|
||||
|
||||
2026-07-25: Reconciled `rail-kubernetes` with the server-side bootstrap commit
|
||||
on `forgejo-remote:coulomb/rail-kubernetes.git` and pushed `main`. The
|
||||
remaining registration gap is now only live Fabric registry sync.
|
||||
|
||||
2026-07-25: Attempted targeted live Fabric registry sync for `rail-kubernetes`,
|
||||
but the registry endpoint at `http://127.0.0.1:8765` refused the connection.
|
||||
The repo is now remote-backed and source-registered, while live registry
|
||||
ingestion remains blocked on the local Fabric registry service being up.
|
||||
|
||||
2026-07-25: Started the local Fabric registry service and completed the
|
||||
targeted live sync for `rail-kubernetes`. The repo is now State Hub
|
||||
registered, source-registered in the Fabric onboarding manifest, remote-backed
|
||||
in Forgejo, and live-ingested into the Fabric registry. Remaining wave-1
|
||||
`rail-kubernetes` work is now about helper scripts and command
|
||||
implementations rather than registration.
|
||||
|
||||
2026-07-25: Imported the first core generic contract artifacts into
|
||||
`rail-kubernetes`: the canonical deployment lifecycle doc, the canonical
|
||||
`railiance/app.toml` contract doc, the machine-readable schema, and the example
|
||||
`railiance/app.toml`. Remaining helper-command and supporting-doc imports stay
|
||||
repo-local follow-up work.
|
||||
|
||||
2026-07-25: Imported the remaining reviewed generic supporting docs for the
|
||||
Kubernetes rail, including the overlay pattern, canary chart pattern, Stage 2
|
||||
deploy/observe contract, promotion/rollback guide, and Stage 1 run-command
|
||||
contract. Remaining wave-1 import debt is now mainly helper scripts and command
|
||||
implementations rather than core contract documentation.
|
||||
|
||||
2026-07-25: Closed T02 after confirming the first-class repo baseline, source
|
||||
declaration, compatibility path, remote registration, State Hub registration,
|
||||
and live Fabric ingestion are all in place for `rail-kubernetes`.
|
||||
|
||||
## T03 - Launch the first `rapp-openbao` repo materialization
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0018-T03
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "3e46e1bd-c730-4e41-a00a-6aa7a4645023"
|
||||
```
|
||||
|
||||
Create the concrete repo bootstrap and workload-package declaration for
|
||||
`rapp-openbao` without letting the package repo absorb platform ownership.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- the new repo has the required baseline files
|
||||
- the repo declares OpenBao as a managed workload package
|
||||
- the repo declares supported rails and rollout/smoke/rollback contract
|
||||
- the remaining ownership boundary with `railiance-platform` stays explicit
|
||||
|
||||
2026-07-25: Confirmed that `/home/worsch/rapp-openbao` does not yet exist.
|
||||
Bootstrap will start from the boundary and first move set already recorded in
|
||||
`railiance-platform/docs/rapp-openbao-boundary.md`.
|
||||
|
||||
2026-07-25: Bootstrapped `/home/worsch/rapp-openbao` with the first-wave repo
|
||||
baseline, `declarations/rapp.yaml`, a package-local Makefile, repo-local docs,
|
||||
the first imported OpenBao package assets from `railiance-platform`, and
|
||||
`RAPP-OPENBAO-WP-0001`. The repo is now registered in State Hub; Fabric
|
||||
registry onboarding remains open as repo-local follow-up work.
|
||||
|
||||
## T04 - Launch the first `reef-railiance` repo materialization
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0018-T04
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "f6f2ea73-0ff3-4cfa-b7a7-7b71db3afb4a"
|
||||
```
|
||||
|
||||
Create the concrete repo bootstrap and substrate declaration for
|
||||
`reef-railiance` as the first grouped home reef repo.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- the new repo has the required baseline files
|
||||
- the repo declares substrate kind, lifecycle, criticality, hosted rails, and
|
||||
primary rail
|
||||
- the repo stays compatible with the canonical S1 ownership role of
|
||||
`railiance-infra`
|
||||
|
||||
2026-07-26: Corrected the first-wave home reef target from singleton
|
||||
`reef-railiance01` to grouped `reef-railiance`, updated the framework and S1
|
||||
source docs accordingly, and bootstrapped `/home/worsch/reef-railiance` with
|
||||
the baseline repo files, grouped reef declaration, substrate/topology files,
|
||||
repo-local docs, and `REEF-RAILIANCE-WP-0001`. The repo is now remote-backed in
|
||||
Forgejo, registered in State Hub, added to
|
||||
`railiance-fabric/registry/railiance-repos.yaml`, and live-ingested into the
|
||||
Fabric registry as `repo_family: reef` with `primary_rail: rail-kubernetes`
|
||||
and `substrate_kind: server-group`.
|
||||
|
||||
## T05 - Add relation projection for rails, `rapp`s, and reefs in Fabric
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0018-T05
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "ef999db5-e75e-467a-a72a-d45fda2b6fa7"
|
||||
```
|
||||
|
||||
Extend Fabric beyond repo-family-aware metadata so it can project the minimum
|
||||
rail/rapp/reef relation topology.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- Fabric can project `supports_rail`
|
||||
- Fabric can project `hosts_rail`
|
||||
- Fabric can project `binds_rapp`
|
||||
- Fabric can project `governed_by`
|
||||
- the projection path is grounded in repo-local declarations rather than
|
||||
registry-only guesses
|
||||
|
||||
2026-07-26: Completed the Fabric relation-projection slice in
|
||||
`railiance-fabric`. Repository records now retain local checkout paths, the
|
||||
registry combined graph reopens repo-local `rail`, `rapp`, and `reef` files to
|
||||
project `governed_by`, `supports_rail`, `hosts_rail`, and `binds_rapp`, and
|
||||
the graph explorer preserves the declaration evidence on projected repository
|
||||
nodes. Focused Fabric tests passed after the projection update.
|
||||
|
||||
## T06 - Verify first-wave registration and coordination end to end
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0018-T06
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "5834f122-b9e9-41c1-93e9-d5525cd720bf"
|
||||
```
|
||||
|
||||
Verify that the first concrete repos participate cleanly in:
|
||||
|
||||
- State Hub registration and indexing
|
||||
- Fabric registration and graph projection
|
||||
- workplan tracking across ownership repo and repo-family repo boundaries
|
||||
|
||||
Acceptance:
|
||||
|
||||
- the first concrete repos are visible to State Hub
|
||||
- the first concrete repos are visible to Fabric
|
||||
- cross-repo ownership and runtime relations are queryable
|
||||
- the wave can continue to second candidates without redefining the bootstrap model
|
||||
|
||||
2026-07-26: Verified the first-wave coordination path end to end. The live
|
||||
Fabric registry at `http://127.0.0.1:8765` now stores the local paths and
|
||||
repo-family metadata for `rail-kubernetes`, `rapp-openbao`, and
|
||||
`reef-railiance`, and its graph-explorer export emits live `governed_by`,
|
||||
`supports_rail`, and `hosts_rail` edges from repo-local declarations. State
|
||||
Hub consistency sync remains clean for the framework and repo-local workplans,
|
||||
so the first wave can continue without reopening the bootstrap model.
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
- [x] The first-wave bootstrap contract is published
|
||||
- [x] `rail-kubernetes` exists as a first-class repo baseline
|
||||
- [x] `rapp-openbao` exists as a first-class repo baseline
|
||||
- [x] `reef-railiance` exists as a first-class repo baseline
|
||||
- [x] Fabric projects the minimum rail/rapp/reef relation topology
|
||||
- [x] State Hub and Fabric can coordinate the first concrete repo-family wave end to end
|
||||
|
||||
## Notes
|
||||
|
||||
This workplan should stay focused on the first concrete repo-family wave.
|
||||
|
||||
Second-wave candidates such as `rapp-vergabe-teilnahme`, `reef-coulombcore`,
|
||||
or a future `rail-knative` should be launched only after the first wave proves
|
||||
the bootstrap contract, registration path, and relation model.
|
||||
|
|
@ -0,0 +1,472 @@
|
|||
---
|
||||
id: RMASTER-WP-0019
|
||||
type: workplan
|
||||
title: "Knative Qonto Runtime on reef-railiance"
|
||||
domain: financials
|
||||
repo: railiance-master
|
||||
status: archived
|
||||
owner: codex
|
||||
topic_slug: railiance
|
||||
planning_priority: high
|
||||
planning_order: 19
|
||||
created: "2026-07-26"
|
||||
updated: "2026-08-18"
|
||||
related_repos:
|
||||
- railiance-master
|
||||
- qonto-assistant
|
||||
- key-cape
|
||||
- rail-kubernetes
|
||||
- reef-railiance
|
||||
- railiance-platform
|
||||
- railiance-fabric
|
||||
state_hub_workstream_id: "d2b082db-ecc3-4322-8be3-22aa00a2af5c"
|
||||
---
|
||||
|
||||
# RMASTER-WP-0019 - Knative Qonto Runtime on reef-railiance
|
||||
|
||||
## Goal
|
||||
|
||||
Turn the Qonto internet-runtime direction into an explicit second-wave
|
||||
Railiance repo-family plan: `reef-railiance` hosts a new `rail-knative`, and
|
||||
that rail dynamically runs a new `rapp-qonto` package extracted from the
|
||||
current `qonto-assistant` deployment path.
|
||||
|
||||
This workplan exists to replace the remaining "custom activator or maybe
|
||||
Knative" ambiguity with a concrete cross-repo architecture path before new
|
||||
runtime implementation starts.
|
||||
|
||||
The second-wave design also establishes a general rule for reliable and
|
||||
cost-efficient operation: deterministic work should progress from attended
|
||||
human operation, to agent-executable interaction, to idempotent functional
|
||||
automation as its contract stabilizes. Human interaction remains appropriate
|
||||
for irreducible policy acceptance and privileged authority, not for repeated
|
||||
evidence collection or routine reconciliation.
|
||||
|
||||
## Why This Exists
|
||||
|
||||
`RMASTER-WP-0018` finished the first wave:
|
||||
|
||||
- `rail-kubernetes` exists as the default base rail
|
||||
- `reef-railiance` exists as the grouped home reef for the Railiance servers
|
||||
- `rapp-openbao` proved the first managed package split
|
||||
- Fabric can now project `governed_by`, `supports_rail`, `hosts_rail`, and
|
||||
`binds_rapp`
|
||||
|
||||
The next concrete runtime pressure comes from `QONTO-WP-0004`. That workload
|
||||
needs internet reachability, bounded cold-start behavior, strong identity, and
|
||||
strict secret custody. Those are exactly the conditions that justify a second
|
||||
rail instead of extending the direct `rail-kubernetes` path indefinitely.
|
||||
|
||||
At the same time, `KEY-WP-0004` is provisioning the first tenant and workload
|
||||
identity lane for Binky Hedgehog GmbH. That lane should target the future
|
||||
runtime package and not harden a permanent direct deployment shape that the
|
||||
framework now intends to replace.
|
||||
|
||||
## Current Starting Point
|
||||
|
||||
The current ecosystem state is:
|
||||
|
||||
- `reef-railiance` is the grouped reef for the Railiance server fleet
|
||||
- `rail-kubernetes` owns the current baseline deployment and lifecycle contract
|
||||
- `qonto-assistant` already contains the Qonto domain code, hardening work, and
|
||||
an initial direct Kubernetes placement request
|
||||
- `key-cape` has `KEY-WP-0004` open for the Binky tenant and qonto workload
|
||||
identity lane
|
||||
- no `rail-knative` repo exists yet
|
||||
- no `rapp-qonto` repo exists yet
|
||||
|
||||
## Target Outcome
|
||||
|
||||
When this workplan is complete:
|
||||
|
||||
1. The boundary between `rail-kubernetes` and a new derived `rail-knative` is
|
||||
written and approved.
|
||||
2. The boundary between `qonto-assistant` and a future `rapp-qonto` is written
|
||||
and approved.
|
||||
3. `reef-railiance` is confirmed as the first host reef for this runtime path,
|
||||
including the rail/reef binding assumptions.
|
||||
4. Identity, secret, and routing lanes are aligned to the future
|
||||
`rapp-qonto` runtime instead of a permanent direct `qonto-assistant`
|
||||
deployment.
|
||||
5. Repo-local follow-up workplans can launch `rail-knative` and `rapp-qonto`
|
||||
without reopening the architecture question.
|
||||
6. Reef admission, contract compatibility, credential routing, and operational
|
||||
evidence have automation-ready contracts before production implementation.
|
||||
|
||||
## Boundaries
|
||||
|
||||
This workplan may define architecture, sequencing, and repo-boundary contracts
|
||||
across Railiance, `qonto-assistant`, and `key-cape`.
|
||||
|
||||
It must not:
|
||||
|
||||
- bootstrap `rail-knative` yet
|
||||
- bootstrap `rapp-qonto` yet
|
||||
- move code or manifests between repos
|
||||
- implement runtime changes in `reef-railiance`, `rail-kubernetes`,
|
||||
`qonto-assistant`, or `key-cape`
|
||||
|
||||
Implementation starts only after the follow-up workplans opened from this plan
|
||||
are reviewed and accepted.
|
||||
|
||||
## Tasks
|
||||
|
||||
## T01 - Define the `rail-knative` boundary against `rail-kubernetes`
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0019-T01
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "336cb298-9107-4519-ad64-5b23853c84fa"
|
||||
```
|
||||
|
||||
Write the contract for what `rail-knative` must own versus what remains owned
|
||||
by `rail-kubernetes`.
|
||||
|
||||
At minimum this boundary must decide ownership for:
|
||||
|
||||
- scale-to-zero and cold-start semantics
|
||||
- service activation / ingress entry behavior
|
||||
- Knative Serving primitives versus generic Railiance lifecycle semantics
|
||||
- compatibility expectations for `reef-railiance`
|
||||
- what stays reusable from the base Kubernetes rail instead of being forked
|
||||
|
||||
Acceptance:
|
||||
|
||||
- one written boundary contract exists
|
||||
- the contract names explicit non-goals for `rail-knative`
|
||||
- the split does not duplicate the generic lifecycle contract already owned by
|
||||
`rail-kubernetes`
|
||||
|
||||
2026-07-26: Added `docs/rail-composition-contract.md` and
|
||||
`docs/adr/ADR-0005-derived-rail-composition.md`. `rail-knative` is now a
|
||||
derived rail with a versioned `rail-kubernetes` base contract. The contract
|
||||
defines inheritance, overrides, non-goals, readiness states, and a rail-neutral
|
||||
workload/binding model.
|
||||
|
||||
## T02 - Define the `rapp-qonto` extraction boundary from `qonto-assistant`
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0019-T02
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "54fcea7d-3c4e-444f-b184-f18f3c4b3a7c"
|
||||
```
|
||||
|
||||
Write the contract for what moves into `rapp-qonto` and what stays in
|
||||
`qonto-assistant`.
|
||||
|
||||
This task must keep `qonto-assistant` as the ownership home for the Qonto
|
||||
domain logic while using `rapp-qonto` as the managed runtime/package boundary.
|
||||
|
||||
At minimum the contract must decide ownership for:
|
||||
|
||||
- deployment packaging and runtime manifests
|
||||
- runtime configuration and secret references
|
||||
- smoke, rollout, rollback, and promotion expectations
|
||||
- how the current direct Kubernetes material becomes migration input rather
|
||||
than a permanent target shape
|
||||
|
||||
Acceptance:
|
||||
|
||||
- one written boundary contract exists
|
||||
- `qonto-assistant` remains the ownership repo in the contract
|
||||
- `rapp-qonto` is justified as a managed package repo and not as a new
|
||||
ownership mirror
|
||||
|
||||
2026-07-26: Added the ownership and request-flow boundary in
|
||||
`docs/qonto-knative-runtime-contract.md`. `qonto-assistant` retains domain
|
||||
logic, financial policy, authorization integration, and application audit
|
||||
events. `rapp-qonto` owns packaging, rail bindings, runtime configuration,
|
||||
secret references, and workload-specific rollout evidence.
|
||||
|
||||
## T03 - Define the `reef-railiance` hosting model for the qonto runtime
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0019-T03
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "b0233f06-3dee-4cac-bae4-d8add5ac29c8"
|
||||
```
|
||||
|
||||
Confirm how `reef-railiance` hosts the first `rail-knative` runtime slice and
|
||||
what that means for ingress, isolation, and criticality.
|
||||
|
||||
This task must decide:
|
||||
|
||||
- whether the qonto path lives entirely on `reef-railiance` in wave 2
|
||||
- how `rail-knative` is declared as a hosted rail there
|
||||
- whether a primary-rail versus mixed-rail statement needs revision
|
||||
- what existing S1/S2 approvals or substrate notes must be updated before
|
||||
runtime work starts
|
||||
|
||||
Acceptance:
|
||||
|
||||
- the hosting assumption is written
|
||||
- the reef/rail relation update path is named
|
||||
- unresolved substrate risks are listed instead of buried in repo-local work
|
||||
|
||||
2026-07-26: Added `docs/reef-production-readiness-contract.md` and
|
||||
`docs/adr/ADR-0006-reef-production-admission.md`. `reef-railiance` may host
|
||||
`rail-knative` during wave 2 while keeping `rail-kubernetes` primary, but
|
||||
topology no longer implies readiness. Critical Qonto admission requires
|
||||
capacity, ingress, identity, isolation, observability, recovery, and explicit
|
||||
single-server/shared-control-plane risk evidence.
|
||||
|
||||
## T04 - Align identity and secret custody to the future runtime path
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0019-T04
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "0086eb68-a852-4fe7-834c-4a19dd763b77"
|
||||
```
|
||||
|
||||
Align `KEY-WP-0004`, the OpenBao lane, and the ops-warden routing lane so the
|
||||
credential path terminates at the future `rapp-qonto` runtime on
|
||||
`rail-knative`, while still allowing a clearly temporary migration bridge from
|
||||
the current `qonto-assistant` repo.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- the future runtime principal and lane names are defined
|
||||
- the transitional use of any current `qonto-assistant` runtime role is
|
||||
explicitly marked temporary
|
||||
- no workplan still assumes a permanent direct deployment target for the lane
|
||||
|
||||
2026-07-26: `docs/qonto-knative-runtime-contract.md` defines steady identifiers
|
||||
for `rapp-qonto`, its service account, OpenBao role, and caller client while
|
||||
making any `qonto-assistant` role a time-bounded bridge. Credential values must
|
||||
use sanctioned custody and execution transports; only route and conformance
|
||||
metadata may enter workplans, Git, chat, or State Hub.
|
||||
|
||||
## T05 - Define second-wave bootstrap and Fabric registration sequence
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0019-T05
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "8905d447-dee9-460d-bbfe-3f0c8e42c7c6"
|
||||
```
|
||||
|
||||
Define the repo-creation and registration sequence for `rail-knative` and
|
||||
`rapp-qonto`, using the first-wave bootstrap contract already proven by
|
||||
`RMASTER-WP-0018`.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- the bootstrap order is named
|
||||
- the minimum declaration files are named for both future repos
|
||||
- the expected Fabric relations (`supports_rail`, `hosts_rail`, `binds_rapp`,
|
||||
`governed_by`) are named before repo creation starts
|
||||
|
||||
Bootstrap order:
|
||||
|
||||
1. publish the common contract/schema additions in `rail-kubernetes`
|
||||
2. add readiness and compatibility support in Fabric
|
||||
3. open the `reef-railiance` admission work and collect baseline evidence
|
||||
4. bootstrap `rail-knative` with a derived-rail declaration
|
||||
5. bootstrap `rapp-qonto` with common and Knative binding declarations
|
||||
6. register `governed_by`, `base_rail`, `supports_rail`, `hosts_rail`, and
|
||||
`binds_rapp` relations
|
||||
7. promote relations through `declared`, `installed`, `verified`, and
|
||||
`production-approved` only as evidence lands
|
||||
|
||||
The minimum declaration files remain `declarations/rail.yaml`,
|
||||
`declarations/rapp.yaml`, and `declarations/reef.yaml`. Rail-neutral workload
|
||||
and rail-binding schemas must be source-controlled before repo creation is
|
||||
treated as implementation completion.
|
||||
|
||||
## T06 - Open the repo-local follow-up workplans for implementation
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0019-T06
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "18fe6f04-f8c5-451b-8e3f-38c19f05f682"
|
||||
```
|
||||
|
||||
Once the boundary and sequencing documents exist, open or update the concrete
|
||||
repo-local implementation workplans that will execute them.
|
||||
|
||||
At minimum, this should cover:
|
||||
|
||||
- `qonto-assistant`
|
||||
- `key-cape`
|
||||
- `reef-railiance`
|
||||
- the future `rail-knative` repo at bootstrap time
|
||||
- the future `rapp-qonto` repo at bootstrap time
|
||||
|
||||
Acceptance:
|
||||
|
||||
- each implementation-owning repo has a concrete follow-up workplan
|
||||
- no implementation starts from an unwritten architecture assumption
|
||||
- this framework workplan can later close with repo-local execution delegated
|
||||
|
||||
2026-07-26: Architecture is ready for repo-local workplan creation. Workplans
|
||||
must separate source-repo, package, derived-rail, reef admission, Fabric
|
||||
compatibility, identity/custody, and S2 runtime installation responsibilities.
|
||||
|
||||
2026-07-26: Opened and State Hub registered repo-local execution work in
|
||||
`rail-kubernetes`, `rail-knative`, `rapp-qonto`, `reef-railiance`,
|
||||
`railiance-fabric`, `qonto-assistant`, and `key-cape`. The two new repos were
|
||||
reconciled with their existing Forgejo bootstrap commits and pushed.
|
||||
|
||||
## T07 - Version the rail-neutral workload and compatibility contract
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0019-T07
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "5b5f2d41-2860-44ee-a8b6-8b9e1d32854f"
|
||||
```
|
||||
|
||||
Turn the composition decision into source-controlled schemas and conformance
|
||||
checks.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- workload declarations separate common facts from rail bindings
|
||||
- base and derived rails declare contract versions and compatibility
|
||||
- validation rejects missing owners, incompatible base rails, and unsupported
|
||||
substrate capabilities
|
||||
- Kubernetes remains the default binding for platform workloads
|
||||
|
||||
2026-07-26: `rail-kubernetes` now publishes base contract `1.0.0`, common
|
||||
workload, rail-binding, and derived-rail schemas, a Kubernetes-default example,
|
||||
and an offline validator. `rail-knative` and `rapp-qonto` pass that validator.
|
||||
|
||||
## T08 - Establish reef admission evidence and mixed-rail split triggers
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0019-T08
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "663a319e-2a05-4a35-90a2-4f6b7b5afa22"
|
||||
```
|
||||
|
||||
Implement the production-readiness states and evidence model in
|
||||
`reef-railiance` and Fabric.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- topology is distinct from installed, verified, and production-approved state
|
||||
- capacity, ingress, network, identity, observability, recovery, and failure
|
||||
domain evidence have machine-readable locations
|
||||
- Qonto's single-server/shared-control-plane residual risk is explicit
|
||||
- mixed-rail split triggers are represented
|
||||
|
||||
2026-07-26: Added a reusable, secret-free substrate preflight in
|
||||
`railiance-cluster` and recorded the failed API reachability result as reef
|
||||
evidence with `block_installation`. Declared topology was not promoted.
|
||||
|
||||
2026-07-26: After the server upgrade, the server-side preflight and complete
|
||||
Knative lifecycle verification passed. Reef evidence now distinguishes the
|
||||
verified rail from blocked production approval and retains capacity and
|
||||
single-node split triggers.
|
||||
|
||||
## T09 - Establish Qonto SLO, threat, rollback, and fallback evidence
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0019-T09
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "6cc2d3a7-33b6-47a7-b59d-04be9318c861"
|
||||
```
|
||||
|
||||
Turn `docs/qonto-knative-runtime-contract.md` into executable package and
|
||||
source-repo verification.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- cold start, request timeout, buffering, concurrency, and scale-down values
|
||||
are measured before production approval
|
||||
- retry and idempotency behavior is explicit for financial operations
|
||||
- public ingress and raw service exposure boundaries are testable
|
||||
- egress is narrower than unrestricted HTTPS or has an approved exception
|
||||
- rollback prefers a verified Knative revision; direct Kubernetes fallback is
|
||||
time-bounded and exceptional
|
||||
|
||||
2026-07-26: `rapp-qonto` now has offline-validated, cluster-local,
|
||||
digest-pinned, bounded Knative packaging with scale-to-zero, default-deny
|
||||
networking, ExternalSecret references, and an explicit unverified FQDN egress
|
||||
gate. Live SLO, identity, failure, and rollback evidence remains outstanding.
|
||||
|
||||
2026-07-27: Deployed digest-addressed revision `rapp-qonto-00004` on
|
||||
rail-knative. The fail-closed proxy gate and cluster-local health smoke pass.
|
||||
Full cold-start timing, audit/idempotency, revocation, dependency-failure, and
|
||||
previous-revision rollback evidence remains before T09 completion.
|
||||
|
||||
2026-07-29: `rapp-qonto/tools/verify_live.sh` now records reversible,
|
||||
machine-readable live evidence. The successful railiance01 run measured a
|
||||
7.384443-second cold activation from zero and proved bounded repeat requests,
|
||||
metadata-only secret delivery, fail-closed proxy loss, recovery,
|
||||
missing-secret denial and restoration, previous-revision rollback, and return
|
||||
to latest traffic. The owner repository's 80-test suite supplies the
|
||||
domain-level audit, idempotency, authorization, and redaction evidence.
|
||||
|
||||
## T10 - Automate routing, conformance, reconciliation, and evidence
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0019-T10
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "1b75308f-f968-4443-aefe-af37550545a1"
|
||||
```
|
||||
|
||||
Move repeatable operation toward reliable functional automation while
|
||||
preserving least privilege and explicit risk authority.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- `warden plan` and route lookup cover implementation credential needs before
|
||||
any founder interaction is proposed
|
||||
- agents use sanctioned `--exec`, `--out`, or wrapped transports rather than
|
||||
reading secret values
|
||||
- conformance checks are idempotent and suitable for CI or scheduled execution
|
||||
- Fabric/State Hub reconciliation consumes source declarations and evidence
|
||||
- human steps are limited to named authority or residual-risk decisions and
|
||||
have an automation follow-up path
|
||||
|
||||
2026-07-26: Generic Knative and Qonto conformance is executable offline. The
|
||||
cluster preflight is idempotent and read-only. Credential routing was attempted
|
||||
first; its unrelated Forgejo match is tracked as a catalog-quality gap rather
|
||||
than used for Kubernetes access.
|
||||
|
||||
2026-07-26: The cluster now has checksum-locked, idempotent Serving/Kourier
|
||||
installation and live verification automation. The configured SSH lane
|
||||
provides agent execution while direct public API access remains unnecessary.
|
||||
|
||||
2026-07-27: KeyCape client credentials are live, their OpenBao custody and
|
||||
rotation route is published as `rapp-qonto-keycape-client`, and the M3/prod
|
||||
posture manifest passes. Public `kc.coulomb.social` DNS still targets the
|
||||
older CoulombCore endpoint; railiance01 verification currently uses direct
|
||||
TLS-preserving resolution pending routing convergence.
|
||||
|
||||
2026-07-29: Credential needs are routed before access, installation and
|
||||
verification use sanctioned SSH execution without secret output, and the live
|
||||
gate is idempotent, reversible, and emits secret-free JSON suitable for CI or
|
||||
scheduled reconciliation. Source declarations and reef bindings now consume
|
||||
the verified evidence. The only remaining human authority is the explicitly
|
||||
separate production acceptance or mitigation of single-node failure-domain
|
||||
risk.
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
- [x] `rail-knative` has a written boundary against `rail-kubernetes`
|
||||
- [x] `rapp-qonto` has a written boundary against `qonto-assistant`
|
||||
- [x] `reef-railiance` is explicitly named as the first host reef
|
||||
- [x] identity and secret custody point at the future runtime path
|
||||
- [x] derived-rail composition and non-duplication are decided
|
||||
- [x] reef readiness and mixed-rail split rules are decided
|
||||
- [x] Qonto end-to-end failure, rollback, and security boundaries are written
|
||||
- [x] common and rail-binding schemas are implemented
|
||||
- [x] repo-local implementation workplans are registered and active
|
||||
- [x] conformance and credential-routing paths are agent-executable
|
||||
- [x] second-wave repo bootstrap order is defined
|
||||
- [x] repo-local implementation workplans exist before implementation begins
|
||||
|
||||
## Notes
|
||||
|
||||
This is a second-wave framework plan. It should stay at the planning and
|
||||
coordination layer until the relevant repo-local workplans are in place.
|
||||
|
|
@ -0,0 +1,494 @@
|
|||
---
|
||||
id: RMASTER-WP-0021
|
||||
type: workplan
|
||||
title: "Rapp Declaration Schema and Family Declaration Validator"
|
||||
domain: financials
|
||||
repo: railiance-master
|
||||
status: archived
|
||||
owner: codex
|
||||
topic_slug: railiance
|
||||
planning_priority: high
|
||||
planning_order: 21
|
||||
created: "2026-08-11"
|
||||
updated: "2026-08-18"
|
||||
related_repos:
|
||||
- railiance-master
|
||||
- railiance-platform
|
||||
- rapp-openbao
|
||||
- rapp-postgres
|
||||
- rapp-qonto
|
||||
- rail-kubernetes
|
||||
- rail-knative
|
||||
- reef-railiance
|
||||
- the-custodian
|
||||
state_hub_workstream_id: "37667c23-1fa9-430e-8d80-d67d98f90e38"
|
||||
---
|
||||
|
||||
# RMASTER-WP-0021 - Rapp Declaration Schema and Family Declaration Validator
|
||||
|
||||
## Goal
|
||||
|
||||
Give the `rapp-*` family a machine-checkable declaration contract, and stand up
|
||||
a validator over all three family declaration files (`rail.yaml`, `rapp.yaml`,
|
||||
`reef.yaml`) so that architectural drift fails loudly instead of accumulating
|
||||
quietly.
|
||||
|
||||
The deliverable is not more prose. `docs/repo-family-bootstrap-contract.md`
|
||||
already names the required `rapp.yaml` fields; naming them in prose is exactly
|
||||
what failed. The deliverable is a schema plus a check that runs.
|
||||
|
||||
## Why This Exists
|
||||
|
||||
`RMASTER-WP-0017` through `RMASTER-WP-0019` established the four-axis model
|
||||
and materialized the first concrete family repos. The model held up. Its
|
||||
enforcement did not.
|
||||
|
||||
`railiance-platform` surveyed all six family repos and the live Railiance01
|
||||
cluster on 2026-08-11 under its `RAILIANCE-WP-0015` and routed the findings
|
||||
here, on the grounds that `railiance-master` owns the model and an
|
||||
implementation repo should not author it. State Hub messages
|
||||
`04c776c4-52fa-494a-9761-942123f28a6e` (proposal) and
|
||||
`f88f938d-1ebc-4ba0-91ee-9395e44a7cb3` (amendment) carry the detail.
|
||||
|
||||
Reported drift across the three live rapps:
|
||||
|
||||
- rollout, smoke, and rollback contracts are mutually unreadable —
|
||||
`rapp-openbao` and `rapp-postgres` use `supported_commands` lists,
|
||||
`rapp-qonto` uses `default_mode` / `production_gate`, a `required:` smoke
|
||||
list and an `order:` rollback list
|
||||
- `contract_version`, `readiness_state`, `data_classification` and
|
||||
`criticality` appear only in `rapp-qonto`, though both rails carry
|
||||
`contract_version` / `readiness_state` consistently
|
||||
- `consumer_contract` / `consumers` exist only in `rapp-postgres`
|
||||
- `workload_identity.name` is the workload name in two rapps and the repo name
|
||||
in the third
|
||||
- `ownership_repo` points at a layer repo twice and at an app repo once
|
||||
- `reef-railiance` `bound_rapps` lists `rapp-qonto` only, while `rapp-openbao`
|
||||
and `rapp-postgres` are both live on Railiance01 — a hand-maintained registry
|
||||
with nothing checking it
|
||||
- roughly 17 live non-system workloads in-cluster against 3 rapps
|
||||
|
||||
The `rail-*` family received a tighter contract in wave 1 and has stayed clean.
|
||||
That contrast is the argument for schema rather than for more documentation.
|
||||
|
||||
## Current Starting Point
|
||||
|
||||
- no `schemas/` directory exists in this repo
|
||||
- `docs/repo-family-bootstrap-contract.md` lists eight required `rapp.yaml`
|
||||
fields with no shapes, no types, and no cardinality rules
|
||||
- `docs/rapp-first-wave-candidates.md` still reads as though the planned first
|
||||
wave (`rapp-openbao`, `rapp-vergabe-teilnahme`, `rapp-forgejo`) happened; the
|
||||
actual population is `rapp-openbao`, `rapp-postgres`, `rapp-qonto`, the
|
||||
latter two created ad hoc from immediate need
|
||||
- `rapp-vergabe-teilnahme` was never built, so the user-facing wrapper pattern
|
||||
it existed to prove remains unproven while the platform-service pattern has
|
||||
been proven twice
|
||||
- canon does not yet admit the family prefixes, so `fix-consistency` cannot
|
||||
call a family validator until `the-custodian` lands its side
|
||||
- `railiance-platform` is holding `RAILIANCE-WP-0015-T02` (bringing
|
||||
`rapp-openbao` and `rapp-postgres` onto one shape) until this schema exists
|
||||
|
||||
## Target Outcome
|
||||
|
||||
When this workplan is complete:
|
||||
|
||||
1. `schemas/rapp.schema.json` defines every required and optional `rapp.yaml`
|
||||
field with one normative shape per contract.
|
||||
2. A `composition:` block expresses what a grouped rapp actually is: a stated
|
||||
purpose, first-party member repos, and pinned third-party components.
|
||||
3. The two cardinalities are written down and enforced separately — repos are
|
||||
many-to-many with rapps, deployables are one-to-one.
|
||||
4. A validator runs over `rail.yaml`, `rapp.yaml`, and `reef.yaml` and fails on
|
||||
drift.
|
||||
5. Reef `bound_rapps` is derived from rapp declarations rather than
|
||||
hand-listed.
|
||||
6. `docs/rapp-first-wave-candidates.md` records what was actually built versus
|
||||
planned, and carries the grouped wave-2 inventory.
|
||||
7. Downstream repos have a single shape to converge on, and know it.
|
||||
|
||||
## Boundaries
|
||||
|
||||
This workplan owns the schema, the validator, the cardinality rules, and the
|
||||
framework documents that describe them.
|
||||
|
||||
It does not migrate any rapp repo onto the new shape — that stays with each
|
||||
owning repo, coordinated through `railiance-platform` `RAILIANCE-WP-0015-T02`.
|
||||
|
||||
It does not touch canon. Admitting the family prefixes into
|
||||
`repo-classification-standard_v1.0` is `the-custodian`'s call, routed there
|
||||
separately as `cc64764a`.
|
||||
|
||||
It does not address the Forgejo organization split. All repos currently sit
|
||||
under a single `coulomb/` org and a split into stewardship orgs is a
|
||||
URL-breaking change across every remote, CI config and ArgoCD source. It is an
|
||||
independent dimension from rapp grouping and needs its own work record.
|
||||
|
||||
## Tasks
|
||||
|
||||
## T01 - Accept the routed proposal and record the ownership decision
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0021-T01
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "af45d82d-c1e3-47b3-81ae-2974bc65cc5d"
|
||||
```
|
||||
|
||||
Read and acknowledge State Hub messages `04c776c4` and `f88f938d`, mark them
|
||||
read, and reply to `railiance-platform` confirming that `railiance-master`
|
||||
accepts ownership of the schema and that this workplan is the vehicle.
|
||||
|
||||
Record the framework decision that rapp bounded context is a grouping dimension
|
||||
in its own right, derived neither from Forgejo organizations nor from State Hub
|
||||
domains, with the cardinality argument as rationale: a repo lives in exactly
|
||||
one Forgejo org, so `org:repo` is one-to-many, while a repo may legitimately
|
||||
contribute to more than one rapp, so `rapp:repo` is many-to-many — and a
|
||||
many-to-many grouping cannot be derived from a one-to-many one. Domains fail in
|
||||
both directions. The three dimensions also change at different speeds.
|
||||
|
||||
Reference OAS P1 in `canon/standards/orthogonal-architecture_v1.0.md`: separate
|
||||
independent perspectives into orthogonal dimensions.
|
||||
|
||||
**Done 2026-08-11.** Both messages marked read; reply `a9a8109f` sent to
|
||||
`railiance-platform` accepting ownership and confirming this workplan as the
|
||||
vehicle. No decision record was created here: `d07ee5f9` already carries the
|
||||
dimension decision from the `railiance-platform` side, and duplicating it would
|
||||
create two records of one decision. The rationale lands instead in `ADR-0007`
|
||||
under T07. One question was returned to `railiance-platform` — whether they can
|
||||
emit the live deployable inventory that T06 needs, so this repo does not
|
||||
acquire a cluster dependency.
|
||||
|
||||
## T02 - Author schemas/rapp.schema.json
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0021-T02
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "87ae4551-1fac-4613-b258-28c8b22bbb82"
|
||||
```
|
||||
|
||||
Create `schemas/` and write `rapp.schema.json` covering:
|
||||
|
||||
- the eight fields already required by the bootstrap contract: `rapp_id`,
|
||||
`workload_identity`, `ownership_repo`, `supported_rails`,
|
||||
`runtime_dependencies`, `rollout_contract`, `smoke_contract`,
|
||||
`rollback_contract`
|
||||
- `contract_version` and `readiness_state`, matching the shape the rail family
|
||||
already carries
|
||||
- `data_classification` and `criticality`, promoted from `rapp-qonto`-only to
|
||||
required
|
||||
- `consumer_contract`, promoted from `rapp-postgres`-only to optional but
|
||||
schema-defined
|
||||
|
||||
Settle the two definitional questions the survey exposed. `workload_identity.name`
|
||||
is the workload, never the repo. `ownership_repo` names the repo that owns the
|
||||
workload's lifecycle; state explicitly whether a layer repo is a legal value,
|
||||
since current declarations disagree.
|
||||
|
||||
Pick one normative shape for `rollout_contract`, `smoke_contract` and
|
||||
`rollback_contract` rather than admitting all three observed variants. Note in
|
||||
the schema which existing declaration the chosen shape most resembles, so
|
||||
migration cost is visible.
|
||||
|
||||
**Done 2026-08-11.** `schemas/rapp.schema.json` (draft 2020-12) and
|
||||
`schemas/README.md` written from the three live declarations rather than from
|
||||
the survey summary, which turned out to understate the drift — see the extra
|
||||
finding below.
|
||||
|
||||
Normative choices, with who pays:
|
||||
|
||||
- `default_mode` kept; all three declarations already carried it. No cost.
|
||||
- `supported_commands` → `commands` in all three contracts. Mechanical.
|
||||
- `smoke_contract.required` is required, `commands` optional — taken from
|
||||
`rapp-qonto`. This is the one migration with real cost: the platform rapps
|
||||
declare only commands and their owners must now name the outcomes those
|
||||
commands establish. A command list records what was run; a required list
|
||||
records what must be true, and only the second is checkable by anyone other
|
||||
than the person who ran it.
|
||||
- `rollback_contract.order` required, also from `rapp-qonto`, recoverable from
|
||||
the command sequences already documented. `direct_kubernetes_fallback`
|
||||
generalizes to `fallback`.
|
||||
- `workload_identity.name` is the workload, never the repo; the schema forbids
|
||||
the `rapp-` prefix outright.
|
||||
- `contract_version`, `readiness_state`, `data_classification`, `criticality`
|
||||
all promoted to required.
|
||||
- `consumer_contract` schema-defined but optional.
|
||||
|
||||
`ownership_repo` is left permissive — exactly one repo, not the rapp repo
|
||||
itself, layer and application repos both legal — so the schema does not
|
||||
silently invalidate two of three live declarations on a question the survey
|
||||
cannot settle. The tighter alternative and its consequence are written up in
|
||||
`schemas/README.md` for the architecture owner. Treat the permissive rule as
|
||||
provisional.
|
||||
|
||||
Validated against all three live declarations with `jsonschema` 4.10.3. The
|
||||
schema is well-formed and reproduces precisely the drift the survey reported,
|
||||
which is the intended result — it fails on real drift and not on anything else:
|
||||
|
||||
| Declaration | Errors | Character |
|
||||
|---|---|---|
|
||||
| `rapp-openbao` | 10 | four missing metadata fields, no composition, three contracts on the old shape |
|
||||
| `rapp-postgres` | 10 | identical set — the two platform rapps drifted together |
|
||||
| `rapp-qonto` | 4 | composition, `direct_kubernetes_fallback`, missing `package_type`, and `workload_identity.name` = `rapp-qonto` |
|
||||
|
||||
**Extra finding, not in the routed survey.** There are six `rapp-*` repos, not
|
||||
three: `rapp-secrets-engine`, `rapp-tenant-engine` and `rapp-user-engine` exist
|
||||
and carry no `declarations/` directory at all. The survey counted only declared
|
||||
rapps, so the real gap is wider than the roughly 17-workloads-versus-3-rapps
|
||||
figure suggests — three further repos claim the family prefix while declaring
|
||||
nothing. Raised to `railiance-platform`; whether these are stubs, abandoned, or
|
||||
undeclared live workloads should be settled before T06 draws its coverage
|
||||
baseline, since undeclared repos are invisible to a coverage check that reads
|
||||
declarations.
|
||||
|
||||
## T03 - Define the composition block and its cardinality rules
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0021-T03
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "8b130ff8-0601-40bb-8539-d6f5847c2f41"
|
||||
```
|
||||
|
||||
Supersede the flat `members:` list from the original proposal with the
|
||||
composition block from the amendment:
|
||||
|
||||
```yaml
|
||||
composition:
|
||||
purpose: <what this coherent workload does>
|
||||
member_repos: # first-party, each sharing rollout and rollback fate
|
||||
- repo: <slug>
|
||||
role: <what it contributes>
|
||||
deployables: [<names>]
|
||||
upstream_components: # third-party, pinned
|
||||
- name: <chart|image|operator>
|
||||
source: <repo/chart or registry ref>
|
||||
version: <pin>
|
||||
```
|
||||
|
||||
Encode both cardinalities. A repo may appear in the `member_repos` of more than
|
||||
one rapp. A deployable must belong to exactly one rapp — each running
|
||||
deployable has exactly one rapp owning its rollout. Keeping these distinct is
|
||||
what makes the coverage check in T06 well-defined.
|
||||
|
||||
Carry the operator decision of 2026-08-11 into the schema: rapp granularity is
|
||||
grouped-by-bounded-context, one rapp per cohesive group that deploys, versions
|
||||
and rolls back together, not one per deployable. Grouping is legitimate only
|
||||
where members share rollout and rollback fate; make that testable rather than
|
||||
advisory where possible.
|
||||
|
||||
**Done 2026-08-11.** `composition` is required on every rapp, in
|
||||
`schemas/rapp.schema.json` under `$defs/composition`. A single-repo rapp
|
||||
declares exactly one member, so there is no second shape for the ungrouped
|
||||
case — the composition block is the only way to state membership.
|
||||
|
||||
`purpose` carries a `minLength` and is documented as the bounded-context
|
||||
statement: if it cannot be written without "and also", the grouping is probably
|
||||
wrong. That is the closest this schema gets to testing shared rollout fate;
|
||||
the substantive check is structural, in that `deployables` is required on every
|
||||
member, which is what T06 consumes.
|
||||
|
||||
Both cardinalities are encoded where they bite. `member_repos[].repo` is
|
||||
unconstrained across rapps, so a repo may appear in several — many-to-many.
|
||||
`member_repos[].deployables` is documented as one-to-one and enforced by the
|
||||
validator's coverage check rather than by the schema, since no single-file
|
||||
schema can see across declarations. `upstream_components` requires an exact
|
||||
`version` pin, with the schema stating that ranges and floating tags are not
|
||||
pins.
|
||||
|
||||
`workload_identity.package_type` gains a `grouped-composition` value for rapps
|
||||
whose members carry their own package types.
|
||||
|
||||
## T04 - Schematize rail.yaml and reef.yaml, and derive bound_rapps
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0021-T04
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "50ffbff9-f8f0-4085-975a-6c5123d9c2f0"
|
||||
```
|
||||
|
||||
Write `schemas/rail.schema.json` and `schemas/reef.schema.json` from the
|
||||
minimum field sets in `docs/repo-family-bootstrap-contract.md`. The rail family
|
||||
has stayed clean, so this is largely codifying what already works; do not
|
||||
tighten it beyond current practice without cause.
|
||||
|
||||
Change `reef.yaml` `bound_rapps` from a hand-maintained list to a derived
|
||||
projection of the rapp declarations that name the reef, and record the
|
||||
migration path for `reef-railiance`, whose current list is already known stale.
|
||||
|
||||
**Done 2026-08-13.** `schemas/rail.schema.json` and `schemas/reef.schema.json`
|
||||
written from the live declarations and the composition/substrate contracts,
|
||||
not from the bootstrap field lists (those lists used an older
|
||||
`substrate_prerequisites` name the live rails do not carry).
|
||||
|
||||
Both live rails conform. The live reef conforms as a document.
|
||||
`bound_rapps` is optional and derived from a new required `rapp.bound_reefs`
|
||||
field (empty list means declared but not placed). The live
|
||||
`reef-railiance` hand-list `[rapp-qonto]` fails the derivation check, which
|
||||
is the intended result. Migration for that repo: delete the field now, or
|
||||
replace it with the derived set once the three live rapps name the reef.
|
||||
|
||||
Adjacent ownership, recorded so it is not mistaken for a schema hole: the
|
||||
postgres backup object store is a consumed capability (`s3-backup-target`),
|
||||
not a rapp-owned resource. Bucket = `resource-control` / `RESOURCE-WP-0002`.
|
||||
Credential = `railiance-platform` OpenBao `Secret platform-pg-backup-s3`.
|
||||
Purchase = decision `9c21c0e0`. `make postgres-backup-deploy` stays
|
||||
fail-closed until that handoff lands.
|
||||
|
||||
## T05 - Build the family declaration validator
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0021-T05
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "0a212d33-2169-4472-80d0-69ec4edba5cb"
|
||||
```
|
||||
|
||||
Add a validator under `tools/` that walks the family repos, locates each
|
||||
`declarations/*.yaml`, and validates it against the matching schema.
|
||||
|
||||
Checks in priority order, per the routed proposal:
|
||||
|
||||
1. every declaration conforms to its schema
|
||||
2. every declared member repo and upstream pin resolves
|
||||
3. reef `bound_rapps` is derivable from rapp declarations rather than
|
||||
hand-listed
|
||||
4. deployable coverage — deferred to T06, which needs cluster state
|
||||
|
||||
Exit non-zero on any failure and name the offending file and field. Make it
|
||||
runnable standalone now, and callable from `fix-consistency` later; do not
|
||||
block on canon admitting the prefixes, since that is `the-custodian`'s
|
||||
sequencing, not ours.
|
||||
|
||||
**Done 2026-08-13.** `tools/validate-family-declarations.py` walks
|
||||
`rail-*` / `rapp-*` / `reef-*` siblings of `--root` (default: parent of
|
||||
this repo). `--self-test` passes against `tools/testdata/family-declarations`.
|
||||
|
||||
First live scan of `/home/worsch` (no inventory): 6 declarations, 31
|
||||
errors. The two rails are clean. The three declared rapps fail on the
|
||||
already-known shape drift plus the new `bound_reefs` field. The reef fails
|
||||
only on stale `bound_rapps`. The three undeclared engine repos fail as
|
||||
prefix-without-declaration. That is exactly the drift the schema exists to
|
||||
make loud.
|
||||
|
||||
## T06 - Add the deployable coverage check
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0021-T06
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "519c2838-c4af-46e9-81fa-612fb09e91e3"
|
||||
```
|
||||
|
||||
Extend the validator with the standing control-loop question: does every live
|
||||
deployable belong to exactly one rapp?
|
||||
|
||||
This is the check that turns the schema from a one-shot lint into an ongoing
|
||||
control loop. Per the amendment it catches all three drift findings at once —
|
||||
stale reef bindings, unpackaged live workloads, and the roughly
|
||||
17-workloads-versus-3-rapps gap.
|
||||
|
||||
Decide how live cluster state reaches the check without `railiance-master`
|
||||
acquiring a cluster dependency it should not have. Consuming an inventory
|
||||
produced by an implementation repo is preferable to querying Railiance01 from
|
||||
here.
|
||||
|
||||
Expect the first run to report a large uncovered set. That output is the wave-2
|
||||
worklist, not a failure to suppress.
|
||||
|
||||
**Done 2026-08-13.** The validator takes `--inventory PATH`. This repo does
|
||||
not query a cluster. The file is a JSON mapping with `source`,
|
||||
`captured_at`, optional `reef`, and `deployables` as a list of `{name,
|
||||
namespace?, kind?}` (bare name strings also accepted). Live names that no
|
||||
rapp claims are errors labelled as wave-2 worklist items. Declared names
|
||||
missing from the inventory are warnings.
|
||||
|
||||
The first live run is not in this repo: it needs `railiance-platform` to
|
||||
emit the inventory T01 asked for. The check itself is implemented and
|
||||
covered by `--self-test`.
|
||||
|
||||
## T07 - Update the bootstrap contract to point at the schemas
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0021-T07
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "aa71bc2f-7d9e-4351-8130-8b6e23b8ee36"
|
||||
```
|
||||
|
||||
Revise `docs/repo-family-bootstrap-contract.md` so the minimum-field lists cite
|
||||
the schema files as normative rather than restating fields in prose. Prose that
|
||||
duplicates a schema will drift from it.
|
||||
|
||||
Record an ADR (next free number, `ADR-0007`) for the framework decisions this
|
||||
workplan settles: bounded rapp context as an independent dimension, the two
|
||||
cardinalities, and grouped-by-bounded-context granularity.
|
||||
|
||||
**Done 2026-08-13.** Bootstrap contract now points at the three schema files
|
||||
and refuses to restate their fields. `docs/adr/ADR-0007-rapp-declaration-contract.md`
|
||||
records the dimension, the two cardinalities, grouped-by-bounded-context
|
||||
granularity, and that the schemas are normative. Decision `d07ee5f9` remains
|
||||
the platform-side record; this ADR is the framework record, not a second
|
||||
decision.
|
||||
|
||||
## T08 - Refresh rapp-first-wave-candidates.md
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0021-T08
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "28e4ef82-62ea-41d2-a059-05c047292240"
|
||||
```
|
||||
|
||||
Correct the document to record what was actually built against what was
|
||||
planned: `rapp-openbao` as planned, then `rapp-postgres` and `rapp-qonto` ad
|
||||
hoc from need, and `rapp-vergabe-teilnahme` never built.
|
||||
|
||||
State the consequence plainly — the platform-service pattern is proven twice
|
||||
and the user-facing wrapper pattern is unproven — and carry the operator
|
||||
decision to build `rapp-vergabe-teilnahme` to prove the user-facing shape
|
||||
before mass extraction.
|
||||
|
||||
Add the grouped wave-2 inventory in the new composition shape. Indicative
|
||||
candidates: `rapp-netkingdom-identity` (sso, mfa, user-engine, tenant-engine,
|
||||
flex-auth), `rapp-forgejo` (forgejo, runner, registry), `rapp-coulomb-social`,
|
||||
`rapp-helix-forge`.
|
||||
|
||||
**Done 2026-08-13.** The document now leads with the plan-versus-outcome
|
||||
table, states that the user-facing wrapper is unproven, keeps the 2026-07-25
|
||||
assessment as history, and carries the wave-2 inventory in composition
|
||||
shape. The three undeclared engine repos are named so they are not invented
|
||||
again as separate rapps. `rapp-forgejo` placement cites `d151d817`.
|
||||
|
||||
## T09 - Release the schema to downstream repos
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0021-T09
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "b8dc2452-8ec0-4301-98b7-4ec96411f428"
|
||||
```
|
||||
|
||||
Waiting on T02, T03 and T05.
|
||||
|
||||
Notify `railiance-platform` that the shape is settled and
|
||||
`RAILIANCE-WP-0015-T02` is unblocked, and notify `rapp-openbao`,
|
||||
`rapp-postgres`, `rapp-qonto` and `reef-railiance` of the migration they each
|
||||
own. Include the normative shape chosen for the rollout, smoke and rollback
|
||||
contracts and what each repo must change.
|
||||
|
||||
Migration itself belongs to the owning repos. This task ends when they have
|
||||
what they need, not when they are done.
|
||||
|
||||
**Done 2026-08-13.** Release messages sent. Downstream now has the shape and
|
||||
the per-repo change list; migration itself is not this task.
|
||||
|
||||
| To | Message | What they received |
|
||||
|---|---|---|
|
||||
| `railiance-platform` | `072c5820` | WP-0015-T02 unblocked; inventory shape for T06; S3 split restated |
|
||||
| `rapp-openbao` | `093f2f73` | 11-error migration (metadata, composition, `bound_reefs`, contract rename) |
|
||||
| `rapp-postgres` | `7b1cb9b7` | same 11-error set; S3 is a consumed destination, not a hole |
|
||||
| `rapp-qonto` | `16742192` | 5-error migration (`composition`, `bound_reefs`, `package_type`, name, `fallback`) |
|
||||
| `reef-railiance` | `6b395e26` | delete or replace stale `bound_rapps` |
|
||||
| `resource-control` | `aa8393e3` | coordination only: bucket is theirs (`RESOURCE-WP-0002`) |
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
---
|
||||
id: RMASTER-WP-0022
|
||||
type: workplan
|
||||
title: "Establish reef-storage for Scaleway object storage"
|
||||
domain: financials
|
||||
repo: railiance-master
|
||||
status: archived
|
||||
owner: grok
|
||||
topic_slug: railiance
|
||||
created: "2026-08-14"
|
||||
updated: "2026-08-18"
|
||||
related:
|
||||
- RMASTER-WP-0017
|
||||
- RMASTER-WP-0021
|
||||
- RESOURCE-WP-0002
|
||||
- RESOURCE-WP-0006
|
||||
state_hub_workstream_id: "b63b9d6b-deb5-4f13-b6db-12da6f7bd644"
|
||||
---
|
||||
|
||||
# RMASTER-WP-0022 — establish reef-storage
|
||||
|
||||
## Goal
|
||||
|
||||
Create `reef-storage` as the reef that **operates** S3-compatible object
|
||||
storage (first instance: Scaleway, for postgres backup). This is a
|
||||
different substrate from `reef-railiance`. Backup will not be provided on
|
||||
top of the home compute reef.
|
||||
|
||||
`resource-control` procures and costs the bucket. `reef-storage` owns the
|
||||
committed non-secret operating attributes (endpoint, bucket, region,
|
||||
prefix, lifecycle). `railiance-platform` holds the secret.
|
||||
`rapp-postgres` consumes a reviewed destination.
|
||||
|
||||
Join convention: `resource-control/docs/operational-reference-convention.md`
|
||||
(`reef:storage/…#key`).
|
||||
|
||||
## Why a new reef
|
||||
|
||||
`docs/reef-substrate-model.md`: a reef is one durable operational
|
||||
boundary. Scaleway object storage has its own identity, access path,
|
||||
lifecycle, and failure domain (`provider:scaleway` / `region:nl-ams`).
|
||||
Putting a bucket “on” `reef-railiance` would mix a cloud object store into
|
||||
a Host Europe compute substrate and hide the independent failure domain
|
||||
the backup workplan requires.
|
||||
|
||||
## Schema tension
|
||||
|
||||
The current `reef.schema.json` requires `primary_rail` and
|
||||
`hosted_rails`. A storage reef does not host `rail-kubernetes`. This
|
||||
workplan must either:
|
||||
|
||||
- allow a storage substrate with no rail (preferred), or
|
||||
- introduce a storage execution contract later, not as a fake rail.
|
||||
|
||||
Do not list `rail-kubernetes` as hosted just to satisfy the schema.
|
||||
|
||||
## Intended declaration (planned)
|
||||
|
||||
```yaml
|
||||
kind: substrate-reef
|
||||
reef_id: reef-storage
|
||||
repo: reef-storage
|
||||
ownership_repo: railiance-platform
|
||||
substrate_kind: object-storage
|
||||
lifecycle_state: planned
|
||||
criticality: high
|
||||
# primary_rail / hosted_rails: omitted or schema-extended — see T01
|
||||
current_members: [] # fill with Scaleway project/bucket names after purchase
|
||||
```
|
||||
|
||||
Non-secret attributes live under e.g.
|
||||
`substrate/object-stores/<resource-slug>.yaml` so resource-control can cite
|
||||
`reef:storage/substrate/object-stores/platform-audit-storage.yaml#endpoint`.
|
||||
|
||||
## T01 — Extend the reef schema for storage substrates
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0022-T01
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "c222e439-795d-45bb-ba81-b94b2a571a1c"
|
||||
```
|
||||
|
||||
Amend `schemas/reef.schema.json` and
|
||||
`docs/reef-substrate-model.md` so a reef may be an object-storage (or
|
||||
other provider-managed) substrate without hosting a compute rail.
|
||||
Document `substrate_kind: object-storage`. Keep `reef-railiance` valid.
|
||||
|
||||
Done when a planned `reef-storage` declaration validates and
|
||||
`reef-railiance` still validates.
|
||||
|
||||
Completed 2026-08-14: `primary_rail` / `hosted_rails` optional; empty
|
||||
`current_members` allowed; substrate model documents provider-delegated
|
||||
reefs with no rail. Confirmed: no rail — Scaleway operates S3.
|
||||
|
||||
## T02 — Bootstrap the reef-storage repo
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0022-T02
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "61617b38-27b5-4c44-be8a-244a2476f1eb"
|
||||
```
|
||||
|
||||
Materialize `reef-storage` from the first-wave bootstrap contract:
|
||||
classification, INTENT, SCOPE, AGENTS, `declarations/reef.yaml`, empty
|
||||
attribute file layout, workplans. Register the remote. Do not create a
|
||||
Scaleway account in this task.
|
||||
|
||||
Done when the repo exists, declares `lifecycle_state: planned`, and
|
||||
resource-control can name `reef:storage/…` paths that will be filled after
|
||||
purchase.
|
||||
|
||||
Completed 2026-08-14: operator provided the repo; declaration, INTENT,
|
||||
SCOPE, and planned attribute path committed.
|
||||
|
||||
## T03 — Attribute file contract for object stores
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0022-T03
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "6ea318c4-33e5-4177-9f87-433670636304"
|
||||
```
|
||||
|
||||
Define the committed YAML shape for one object-store: endpoint, region,
|
||||
bucket, prefix, versioning/lifecycle flags, provider project ref. No
|
||||
keys. Hand resource-control and `rapp-postgres` the path, not a chat
|
||||
paste.
|
||||
|
||||
Done when a schema or documented example exists and WP-0002 T03 can cite
|
||||
it as the destination of non-secret attributes after buy.
|
||||
|
||||
Completed 2026-08-14:
|
||||
`reef-storage/schemas/object-store-attributes.schema.json` and planned
|
||||
`substrate/object-stores/platform-audit-storage.yaml`.
|
||||
|
|
@ -0,0 +1,353 @@
|
|||
---
|
||||
id: RMASTER-WP-0023
|
||||
type: workplan
|
||||
title: "Private-by-default exposure until production admission"
|
||||
domain: financials
|
||||
repo: railiance-master
|
||||
status: archived
|
||||
owner: grok
|
||||
topic_slug: railiance
|
||||
planning_priority: high
|
||||
planning_order: 23
|
||||
created: "2026-08-15"
|
||||
updated: "2026-08-18"
|
||||
related:
|
||||
- ADR-0006
|
||||
- ADR-0008
|
||||
- RMASTER-WP-0017
|
||||
- RMASTER-WP-0019
|
||||
- RMASTER-WP-0021
|
||||
- RMASTER-WP-0022
|
||||
- RAIL-HO-WP-0009
|
||||
related_repos:
|
||||
- railiance-master
|
||||
- rail-kubernetes
|
||||
- railiance-cluster
|
||||
- reef-railiance
|
||||
- reef-storage
|
||||
- railiance-infra
|
||||
- railiance-enablement
|
||||
- ops-bridge
|
||||
state_hub_workstream_id: "50303bdf-aada-4c38-8782-d4e63b603e65"
|
||||
---
|
||||
|
||||
# RMASTER-WP-0023 — private-by-default exposure until production admission
|
||||
|
||||
## Goal
|
||||
|
||||
Make every new reef, rail, and rapp **unreachable from the public internet
|
||||
until it is production-safe**, by one family rule that the implementation
|
||||
repos can enforce.
|
||||
|
||||
"Production-safe" already has a name: ADR-0006 admission
|
||||
(`declared` → `installed` → `verified` → `production-approved`). What is
|
||||
missing is the **default-private exposure rule** and a field the schemas can
|
||||
check. Topology and a working deploy must not imply a public listener.
|
||||
|
||||
## Why this is here
|
||||
|
||||
`railiance-master` owns framework contracts that span `reef-*`, `rail-*`,
|
||||
and `rapp-*`. Shielding "whatever we spin up" is that kind of rule.
|
||||
|
||||
It does **not** belong as the system owner in:
|
||||
|
||||
- `railiance-infra` — host UFW. Necessary for a new reef with no 80/443;
|
||||
useless for a rapp that shares `railiance01` ingress. RAIL-HO-WP-0009
|
||||
closed the hand-opened k3s API; do not make S1 the admission desk for
|
||||
rapps. Do not use this workplan to re-public `6443`.
|
||||
- `railiance-cluster` / `rail-kubernetes` — Ingress, NetworkPolicy, Service
|
||||
types. This is where most packets will actually be blocked. They cannot
|
||||
define what "production-safe" means for a rapp or for a non-k8s reef
|
||||
(`reef-storage`).
|
||||
- each `rapp-*` — must declare intended exposure; must not punch its own
|
||||
public hole.
|
||||
- `railiance-enablement` — should ship private-by-default templates; does
|
||||
not own the rule.
|
||||
- `reef-railiance` alone — too local; the next reef must inherit the same
|
||||
rule.
|
||||
- `ops-bridge` — the paved path to a shielded thing; not the policy owner.
|
||||
|
||||
## What already exists
|
||||
|
||||
- ADR-0006 and `docs/reef-production-readiness-contract.md` — admission
|
||||
states; network isolation and extra gates for internet-facing or
|
||||
high-value workloads. Admission answers "may this binding run in
|
||||
production?" Exposure answers "who may reach the listener?" Keep them
|
||||
beside each other.
|
||||
- Family schemas (`schemas/{reef,rail,rapp}.schema.json`) — no
|
||||
`exposure` / `network_posture` field. Rapp already uses `public` on
|
||||
`data_classification`; the new field must not reuse that name as a
|
||||
top-level enum collision.
|
||||
- Readiness vocabularies are **deliberately not unified**
|
||||
(`schemas/README.md`):
|
||||
- rail: `declared | installed | verified | production-approved | deprecated`
|
||||
- rapp: `draft | declared | deployed | verified | retired`
|
||||
- reef: `lifecycle_state` `planned | active | retired`
|
||||
- bindings: ADR-0006 states on the reef
|
||||
- RAIL-HO-WP-0009 — operator access to a shielded k3s API is ops-bridge
|
||||
(`k3s-api-railiance01` on `:16444`). That is the intended pattern for
|
||||
anything not yet public.
|
||||
- Live public exceptions already exist on `reef-railiance` (Forgejo,
|
||||
Coulomb Social, Host Europe Nydus on 2224). They must be named as
|
||||
grants, not silently grandfathered.
|
||||
- Provider-delegated reefs (`reef-storage`, Scaleway S3) already expose a
|
||||
provider API on the internet. That is a different category from a
|
||||
listener we open.
|
||||
|
||||
## Decision (T01, accepted 2026-08-15)
|
||||
|
||||
Ratified as written. Recorded in
|
||||
[`docs/adr/ADR-0008-private-by-default-exposure.md`](../../docs/adr/ADR-0008-private-by-default-exposure.md).
|
||||
|
||||
| Posture | Meaning | Who may reach it |
|
||||
| --- | --- | --- |
|
||||
| `private` | No extra listener we control | in-cluster DNS, same-reef services |
|
||||
| `operator` | Same listener as `private`, plus a named ops-bridge / SSH tunnel | operator and approved agents |
|
||||
| `public` | Internet listener we publish | anyone the Ingress / DNS / UFW surface allows |
|
||||
|
||||
`operator` is an **access annotation**, not a different packet posture.
|
||||
It does not open a host port or a public Ingress. A ClusterIP service
|
||||
plus a named tunnel is still `private` at the packet layer.
|
||||
|
||||
Rules:
|
||||
|
||||
1. New reefs, rails, and rapps default to `private`. Use `operator` only
|
||||
when a named admin or API surface must be reachable before admission
|
||||
(k3s API, OpenBao UI). Do not prefer `operator` as the debug default
|
||||
for every new rapp — that grows an ops-bridge catalog by accident.
|
||||
2. `public` requires **both** an ADR-0006 binding of
|
||||
`production-approved` **and** an explicit exposure grant. Do not key
|
||||
`public` off `rapp.yaml` `readiness_state` (it has no
|
||||
`production-approved`) and do not add that value to the rapp enum in
|
||||
this workplan.
|
||||
3. A reef has no `production-approved` lifecycle. A public reef surface
|
||||
(host port, public DNS we publish) is a **substrate grant**, not a
|
||||
binding admission. T01 must name that grant shape separately.
|
||||
4. A working deploy, a `hosts_rail` / `binds_rapp` line, or an Ingress
|
||||
object is not a grant.
|
||||
5. A grant is accepted residual risk (reason, approved_on, residual-risk
|
||||
owner, hostname or port). It is not a self-serve wish in the
|
||||
declaration.
|
||||
6. Ops-bridge is the normal path to a shielded thing. That is the same
|
||||
trade as ADR-005 in `railiance-infra`: convenience depends on the
|
||||
tunnel; the Internet does not see the service.
|
||||
7. `6443` / the k3s API is not a grantable public surface. RAIL-HO-WP-0009
|
||||
already closed it; this contract must not become a way to reopen it.
|
||||
|
||||
Do not unify the three readiness enums in this workplan. Exposure sits
|
||||
beside them. Record the rule as **ADR-0008** (sibling), not as an edit
|
||||
that mixes "is this binding production-safe?" with "who may reach it?"
|
||||
|
||||
The shared vocabulary is one enum. It is **not** one schema shape and
|
||||
not one admission check:
|
||||
|
||||
| Family | What the field means | What makes `public` legal |
|
||||
| --- | --- | --- |
|
||||
| `rapp-*` | intended consumer-facing listener | binding `production-approved` + grant |
|
||||
| `rail-*` | which listener classes the rail may emit | rail may emit public Ingress only when a bound rapp/rail grant exists |
|
||||
| `reef-*` | host ports and public DNS we publish | substrate grant; not reef `lifecycle_state` |
|
||||
|
||||
A rapp cannot be `public` on a reef that has not granted a public
|
||||
surface. Conflicting declarations fail closed.
|
||||
|
||||
## Boundaries
|
||||
|
||||
This workplan may:
|
||||
|
||||
- add ADR-0008 for exposure posture and point ADR-0006 at it
|
||||
- extend family schemas and `tools/validate-family-declarations.py`
|
||||
- write the exposure contract and a dated exception snapshot
|
||||
- **route** implementation work to owning repos (intake notes or State
|
||||
Hub messages). The owning-repo agent files the workplan. This repo
|
||||
does not implement there and does not silently create four sibling
|
||||
workplans as a side effect of registration.
|
||||
|
||||
It must not:
|
||||
|
||||
- implement NetworkPolicy, Ingress classes, UFW rules, or ops-bridge
|
||||
tunnels here
|
||||
- take down live public services as a side effect of the contract
|
||||
- put booked cost, credentials, or customer numbers in declarations
|
||||
- inventory CoulombCore host ports (that stays with RAIL-HO-WP-0009 /
|
||||
`railiance-infra` until CoulombCore is a declared reef)
|
||||
- absorb Q7 / Goss declared-vs-live *reaction* (page a human, open a
|
||||
task, block a rollout). Inbox `ae73593a` handed that to
|
||||
`railiance-master`; it is a separate workplan
|
||||
- treat provider-native internet APIs (Scaleway S3, other
|
||||
provider-delegated endpoints) as the same grant as a listener we open.
|
||||
This contract covers listeners we control: host ports, Ingress,
|
||||
Service types, and public DNS we publish
|
||||
- migrate live family declarations onto the new field (owning repos, via
|
||||
T05)
|
||||
- become a living port inventory. After T04, updates live in the owning
|
||||
declarations
|
||||
|
||||
## Tasks
|
||||
|
||||
### T01 — Ratify the exposure rule
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0023-T01
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "40d50848-d59e-4f7c-98df-a442dce90439"
|
||||
```
|
||||
|
||||
Human review. Accept or amend the recommended table above. Record ADR-0008.
|
||||
Name the default posture for a new reef, a new rail, and a new rapp
|
||||
(recommended: `private` for all three). Confirm that `public` keys off
|
||||
the **binding** admission state and that a reef public surface uses a
|
||||
substrate grant. Confirm `6443` is not grantable as `public`.
|
||||
|
||||
**Done when:** ADR-0008 is accepted, the three readiness enums are left
|
||||
distinct on purpose, and the per-family meaning of `public` is written
|
||||
down.
|
||||
|
||||
Completed 2026-08-15: operator accepted the recommended table as
|
||||
written. ADR-0008 records the postures, the per-family meaning of
|
||||
`public`, the grant shape, and the 6443 exclusion. Readiness enums stay
|
||||
distinct.
|
||||
|
||||
### T02 — Write the exposure contract
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0023-T02
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "96db2a2d-670c-4b98-b6f3-860f9b3009b3"
|
||||
```
|
||||
|
||||
Depends on T01.
|
||||
|
||||
One contract, `docs/exposure-posture-contract.md`, that says what each
|
||||
posture means **per family**:
|
||||
|
||||
| Family | `private` | `operator` | `public` |
|
||||
| --- | --- | --- | --- |
|
||||
| `reef-*` compute | no extra host ports; no public DNS for new members | ops-bridge / SSH only | declared host/DNS surface plus substrate grant |
|
||||
| `reef-*` provider-delegated | we publish no extra name | n/a | out of this enum; provider API is not a listener we open |
|
||||
| `rail-*` | no public Ingress class; default-deny NetworkPolicy | tunnel to the rail's API or admin path | rail may emit public Ingress for a granted binding |
|
||||
| `rapp-*` | ClusterIP / in-cluster DNS only | named tunnel (local port) on the same ClusterIP | named public hostname plus binding grant |
|
||||
|
||||
Include the fail-closed rule: missing field means `private`.
|
||||
Include the conflict rule: rapp `public` + reef without a public
|
||||
substrate grant is invalid.
|
||||
|
||||
**Done when:** implementation repos can implement without inventing
|
||||
vocabulary.
|
||||
|
||||
Completed 2026-08-15: `docs/exposure-posture-contract.md` names the
|
||||
per-family reading, grant shape, fail-closed default, conflict rule,
|
||||
6443 exclusion, and provider-delegated carve-out.
|
||||
|
||||
### T03 — Schema and validator
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0023-T03
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "03070be7-925e-4aee-9938-85b03b8cbe37"
|
||||
```
|
||||
|
||||
Depends on T01.
|
||||
|
||||
Add `exposure` (or the T01 name) to the family schemas. Share the
|
||||
vocabulary; do not pretend one object shape fits all three. Validator
|
||||
must fail when:
|
||||
|
||||
- a rapp or rail posture is `public` and the relevant **binding** is not
|
||||
`production-approved`
|
||||
- posture is `public` and no grant object is present (hostname / port /
|
||||
reason / approved_on / residual-risk owner)
|
||||
- a rapp is `public` and its reef has not granted a public surface
|
||||
|
||||
Keep the field additive so existing declarations do not break the day
|
||||
the schema lands. Requiring the field on live declarations is a T05
|
||||
migration in the owning repos, not a T03 done-when.
|
||||
|
||||
Name the field so it cannot be confused with rapp
|
||||
`data_classification: public`.
|
||||
|
||||
**Done when:** `tools/validate-family-declarations.py` rejects a public
|
||||
rapp that is not production-approved, and the testdata tree has good and
|
||||
bad fixtures. Live sibling repos are unchanged.
|
||||
|
||||
Completed 2026-08-15: additive `exposure` on all three family schemas.
|
||||
Validator rejects unapproved public rapps, missing grants, public rapps
|
||||
on a private reef, port 6443, and public provider-delegated reefs.
|
||||
Fixtures: `good-exposure` and `bad-exposure`. Live declarations omitted
|
||||
the field and still validate.
|
||||
|
||||
### T04 — Exception snapshot for already-public surfaces
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0023-T04
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "6576cc7c-6c85-4d3b-b0cc-dfba4e9b4774"
|
||||
```
|
||||
|
||||
Dated snapshot in this repo so the contract does not pretend
|
||||
`reef-railiance` is already private. Seed from what is already named:
|
||||
Forgejo, Coulomb Social, Host Europe Nydus 2224, then fill anything else
|
||||
found on that reef.
|
||||
|
||||
Each entry: hostname or port, owning rapp or provider, why it is public,
|
||||
residual-risk owner. Same shape T01 names for a grant.
|
||||
|
||||
This snapshot is not the living source of truth. T05 files the grant
|
||||
objects into the owning declarations. Later changes happen there.
|
||||
|
||||
Out of scope: CoulombCore, shutdown plans, provider-native APIs.
|
||||
|
||||
**Done when:** every known public surface on `reef-railiance` is either a
|
||||
snapshot grant or a routed task to close it.
|
||||
|
||||
Completed 2026-08-15:
|
||||
`docs/evidence/reef-railiance-exposure-snapshot-2026-08-15.md`.
|
||||
Grants: Forgejo, Coulomb Social, reuse-surface, Nydus 2224. Routed:
|
||||
`bao.coulomb.social` verify/close; CoulombCore names stay out.
|
||||
|
||||
### T05 — Route enforcement work
|
||||
|
||||
```task
|
||||
id: RMASTER-WP-0023-T05
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "d780df59-c67d-486e-8e8a-15e5043cd513"
|
||||
```
|
||||
|
||||
Depends on T01 and T02.
|
||||
|
||||
Write intake notes here or send State Hub messages to the owning-repo
|
||||
agents. Those agents file the workplan in their repo. Do not implement
|
||||
there from this repo.
|
||||
|
||||
| Owner | What to enforce |
|
||||
| --- | --- |
|
||||
| `rail-kubernetes` (or `railiance-cluster` until the rail owns networking) | default-deny NetworkPolicy; no public Ingress unless the grant exists; ClusterIP as the paved Service |
|
||||
| `reef-railiance` | first live admission: new binds stay `private` (or `operator` only for a named admin path); existing public binds receive the T04 grants |
|
||||
| `railiance-infra` | new reefs do not get 80/443 until a reef substrate grant exists; 6443 stays operator-only; this is not the rapp gate |
|
||||
| `railiance-enablement` | templates emit private Services + tunnel docs, never a public Ingress by default |
|
||||
|
||||
**Done when:** each owning repo has a workplan or an accepted intake,
|
||||
with a back-link to this ID.
|
||||
|
||||
Completed 2026-08-15: intakes in
|
||||
`docs/exposure-enforcement-intakes.md`. Child workplans filed:
|
||||
`RAIL-K8S-WP-0003`, `REEF-RAILIANCE-WP-0004`, `RAIL-HO-WP-0010`,
|
||||
`RAIL-EN-WP-0001`.
|
||||
|
||||
## Suggested review order
|
||||
|
||||
1. T01 (human) — accept or change the recommended table.
|
||||
2. T04 can start now as a census; its grant fields lock after T01.
|
||||
3. T02 after T01.
|
||||
4. T03 after the field names are stable.
|
||||
5. T05 last; it is the only task that creates work in other repos.
|
||||
|
||||
## Outcome
|
||||
|
||||
Finished 2026-08-15. ADR-0008, the exposure contract, additive schemas,
|
||||
validator fixtures, the reef-railiance snapshot, and routed intakes are
|
||||
in this repo. Packet-level enforcement stays with the owning repos.
|
||||
Loading…
Add table
Add a link
Reference in a new issue