feat: implement RMASTER-WP-0023 private-by-default exposure

Add the exposure contract, additive family schema fields, validator
checks and fixtures, the reef-railiance exception snapshot, and
routed intakes. Enforcement stays in the owning repos.
This commit is contained in:
codex 2026-08-15 20:08:37 +02:00
parent 6301798fab
commit 4a664533d3
24 changed files with 998 additions and 13 deletions

View file

@ -0,0 +1,58 @@
# reef-railiance exposure snapshot
Date: 2026-08-15
Status: Dated snapshot under RMASTER-WP-0023-T04. Not the living source
of truth. T05 files grants into owning declarations.
Scope: public listeners on `reef-railiance` (current member
`Railiance01`). CoulombCore is out. Provider-native APIs are out.
This is not a shutdown plan.
Grant shape matches ADR-0008: hostname or port, reason, `approved_on`,
residual-risk owner.
## Snapshot grants
These surfaces are already published. They stay up. Each row is a grant
the owning declaration should carry.
| hostname or port | Owning rapp or provider | Why it is public | Residual-risk owner |
| --- | --- | --- | --- |
| `forgejo.coulomb.social` | `rapp-forgejo` (decided, not yet materialized; today `railiance-apps` / `railiance-infra`) | Canonical git forge, OCI, and npm registry for the estate | `railiance-infra` |
| `app.coulomb.social` | Coulomb Social (`coulomb-social` / `railiance-apps`; no `rapp-*` yet) | Public web app on Railiance01 | `railiance-apps` |
| `reuse.coulomb.social` | reuse-surface (`railiance-apps`; no `rapp-*` yet) | Public federation / reuse landing | `railiance-apps` |
| port `2224` | HostEurope Nydus (`nydus-ex-api`) | Provider VPS agent; required by the platform | `railiance-infra` |
Reef-level substrate reading: `80/443` are the host ports those
hostnames need. `reef-railiance` should carry a public substrate grant
for that DNS/Ingress surface when the declaration grows `exposure`.
Host UFW on Railiance01 currently declares OpenSSH and Nydus `2224`
only (RAIL-HO-WP-0009). The names above are still published DNS; the
host-port grant is what makes 80/443 legal under this contract.
## Not grants
| Surface | Why it is not a grant here |
| --- | --- |
| `22/tcp` SSH | Operator path, not a published application listener |
| `6443/tcp` k3s API | Closed by RAIL-HO-WP-0009; not grantable as `public` |
| `bao.coulomb.social` | OpenBao public name. Target on Railiance01 is private (`public_ingress: false`). If the name still answers on this reef, that is a routed close, not a grant |
| `kc.coulomb.social` | Keycloak; last recorded DNS still targeted CoulombCore |
| `gitea.coulomb.social` | Archived Gitea on CoulombCore |
| `coulomb.social` apex | Still Bubble.io until an explicit apex cutover |
| Scaleway S3 / `reef-storage` | Provider-native API; out of this enum |
## Routed follow-ups (not shutdowns)
| Item | Route |
| --- | --- |
| File the four snapshot grants into owning declarations once `exposure` exists | T05 → `reef-railiance`, `rapp-forgejo` (or `railiance-apps` until that rapp exists) |
| Confirm `bao.coulomb.social` does not still publish on Railiance01; close DNS or keep it private | `railiance-platform` / RMASTER-WP-0020 |
| Materialize `rapp-forgejo` so the forge grant has a family home | already decided in ADR-0003 / `docs/rapp-first-wave-candidates.md` |
| Name rapps for Coulomb Social and reuse-surface, or accept layer-repo ownership until then | `railiance-apps` |
## Done-when
Every known public surface on `reef-railiance` is either a snapshot
grant above or a routed follow-up. Living updates happen in the owning
declarations, not by editing this date-stamped file.