railiance-platform/ArchitectureBlueprint.md
codex 28f445fa89
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Reopen the ArgoCD question on corrected evidence
The 2026-08-11 decision to keep ArgoCD rested on a claim that turned out to be
wrong. Verified against both clusters once API access was restored: ArgoCD is
not on railiance01, it runs on CoulombCore, its Applications target CoulombCore
in-cluster, nothing on railiance01 is ArgoCD-managed, and the live S3 workloads
- target-revenue, openbao, external-secrets - deploy outside GitOps. Two
Applications are Degraded and one is OutOfSync/Missing.

The earlier claim that removing ArgoCD documentation would describe a system
that does not exist was backwards: the documentation already describes a
deployment path that is largely not in effect. Restates the question with three
real options - adopt properly on railiance01, retire, or relocate to Helix Forge
- and notes that doing nothing is the option with a cost.

Same defect class as RAIL-HO-WP-0009: declared and live state diverged, and
nothing detected it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 00:05:14 +02:00

417 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Railiance Architecture Blueprint
> The structural backbone of Railiance: the axes along which repositories are
> classified, the layers of the stack, and the rules that keep them from
> collapsing into each other.
>
> **Status:** working blueprint, established 2026-08-11. Structural claims here
> are verified; items marked **OPEN** are undecided and name their deciding
> repo. This file records structure, not runtime state — for what is currently
> deployed, see each repo's `SCOPE.md`.
>
> **Authority note:** `railiance-master` owns the repo-family model and
> `the-custodian` owns canon. This blueprint consolidates and applies them from
> the S3 perspective; where the two disagree, they win.
---
## 1. Four classification axes
Railiance classifies repositories along four **orthogonal** axes. They are
complementary, not competing — a workload has a position on all four.
| Prefix | Axis | Unit | Answers |
| --- | --- | --- | --- |
| `railiance-*` | ownership and responsibility | one architectural responsibility area | who owns this capability or layer? |
| `rail-*` | execution contract | one workload execution architecture | how does a workload run here? |
| `rapp-*` | managed workload package | one Railiance-managed workload | what exactly is packaged and operated? |
| `reef-*` | substrate boundary | one durable substrate reality | where does this run, and what is bound there? |
Source: `railiance-master/docs/repository-axes.md`.
### The separation rule
Independent perspectives stay in separate dimensions. This is **normative**,
not stylistic — OAS P1, `canon/standards/orthogonal-architecture_v1.0.md`:
*"Architecture descriptions MUST separate independent perspectives into
orthogonal dimensions."*
Three groupings are routinely confused and must not be derived from each other:
| Grouping | Answers | Cardinality to repos | Changes |
| --- | --- | --- | --- |
| Forgejo org | who may push; what is discoverable together | 1:many | slowly (renames break clone URLs, CI, GitOps sources) |
| State Hub domain | which strand of work, for attention and priority | 1:many | occasionally |
| **Rapp context** | what deploys, versions and rolls back together | **many:many** | often |
A repo lives in exactly one Forgejo org — it is a path segment in the clone URL.
A repo may contribute to several rapps. **A many:many grouping cannot be derived
from a 1:many one.** Decision `d07ee5f9`.
**The cardinality that makes enforcement possible:** repos are many:many with
rapps, but **deployables are 1:1** — each running deployable has exactly one
rapp owning its rollout. That is what makes the coverage check well-formed:
*does every live deployable belong to exactly one rapp?*
---
## 2. The stack
The OAS Stack dimension defines five levels. Railiance implements them as
responsibility repos, plus cross-cutting and meta concerns that sit beside the
stack rather than inside it.
| Level | Repo | Owns |
| --- | --- | --- |
| S1 | `railiance-infra` | OS provisioning, hardening, server baseline, at-rest bootstrap secrets |
| S2 | `railiance-cluster` | k3s, Helm, ingress, CNI, admission controllers, operators, kubeconfig |
| S3 | `railiance-platform` | shared stateful services: data, cache, secrets, object storage, messaging |
| S4 | `railiance-enablement` | paved paths: CI/CD templates, SDKs, portal, promotion conventions |
| S5 | `railiance-apps` | user-facing application workloads and release operations |
Repos that are not stack levels are **not homeless** — they belong to other OAS
dimensions (§2.1):
| Repo | Dimension | Owns |
| --- | --- | --- |
| `railiance-telemetry` | **Quality / Q2 Observability** | metrics, logs, traces, alerting — the substrate other layers emit into |
| `railiance-bootstrap` | lifecycle (pre-stack) | the ignition sequence: bare VM → working Railiance, then handoff |
| `railiance-master` | the architecture description itself | repo taxonomy, framework ADRs, boundary rules, vocabulary |
| `railiance-fabric` | **Capability** | repo → service → capability → interface → dependency model |
| `railiance-forge` | **being placed** (§5.2) | workload → `rapp-forgejo`; layer responsibility → S4 |
### 2.1 Railiance uses one of six canonical dimensions
**This is the central coherence finding of the 2026-08-11 review.**
OAS defines **six** canonical architecture dimensions, and states that *"Each
architecture description MUST use these dimensions"*
(`canon/standards/orthogonal-architecture_v1.0.md` §4):
| Dimension | Purpose | Railiance use |
| --- | --- | --- |
| Stack | technical hosting substrate | **used** — S1S5, the whole model to date |
| Logic | functional decomposition | unused |
| Plane | operational responsibility | unused |
| Quality | cross-cutting architecture properties | **unused — and this is where the gaps are** |
| Capability | stable capability modeling | partial (`railiance-fabric`, capability registry) |
| Intelligence | degree of intelligent automation | unused |
Railiance has modelled itself almost entirely on the Stack dimension. Anything
that did not fit a stack level was treated as an anomaly — "unplaced", "beside
the stack", "cross-cutting" — and accumulated as exceptions.
They were never anomalies. **They are concerns on dimensions Railiance was not
using.** The Quality dimension's sub-levels map almost one-to-one onto the
capability gaps found independently by this review:
| Quality sub-level | Canon definition | Railiance concern | State |
| --- | --- | --- | --- |
| Q1 Security and Compliance | — | credential custody, OpenBao lanes, CCR approval | **implemented** (S3), never named as Q1 |
| Q2 Observability | "telemetry and monitoring: metrics, logs, traces" | `railiance-telemetry` | **seeded** 2026-08-11 |
| Q3 Operability and Resilience | — | restore drills, rollback proof | split across S1/S3/S5, unowned |
| Q4 Isolation and Tenancy | — | `rapp-postgres` ADR-0001, tenant keying | implemented per-consumer, not modelled |
| Q5 Performance and Scalability | — | — | unaddressed |
| Q6 Cost and Efficiency | — | `resource-control`, `fin-hub`, cost attribution keys | outside the family, boundary undeclared |
| Q7 Governance and Change Management | "policies and architecture governance" | **the conformance loop** | unowned (§5.3) |
Two consequences worth stating plainly:
1. **`railiance-telemetry` is not an exception to the stack model** — it is Q2
Observability, named in canon in exactly those words. Its placement question
(§5.1) is effectively answered; `railiance-master` need only ratify it.
2. **The conformance loop is Q7**, not a missing stack layer. That reframes
§5.3 from "invent a home" to "implement the Quality dimension."
The recurring "self-evidencing" aspiration across five stack layers (§3) is, in
OAS terms, five Stack-dimension repos each independently asking for Q2 and Q7.
That is what a missing dimension looks like from inside the one you are using.
### 2.2 The six dimensions, established
Railiance's position on each canonical dimension, with owners where they exist.
Sub-levels are canon's, not invented here. **Status** is honest about what is
implemented versus merely named.
#### Stack — technical hosting substrate · *in use*
S1 `railiance-infra` · S2 `railiance-cluster` · S3 `railiance-platform` ·
S4 `railiance-enablement` · S5 `railiance-apps`. See §2.
#### Quality — cross-cutting architecture properties · *the priority*
| Sub-level | Railiance concern | Owner | Status |
| --- | --- | --- | --- |
| Q1 Security and Compliance | credential custody, OpenBao lanes, CCR approval, grant catalog | S3 | **implemented**, never named Q1 |
| Q2 Observability | metrics, logs, traces, alerting | `railiance-telemetry` | seeded 2026-08-11, no implementation |
| Q3 Operability and Resilience | restore drills, rollback proof, DR | — | split S1/S3/S5, **unowned** |
| Q4 Isolation and Tenancy | consumer isolation, tenant keying | `rapp-postgres` (per-consumer) | implemented, not modelled fleet-wide |
| Q5 Performance and Scalability | — | — | **unaddressed** |
| Q6 Cost and Efficiency | cost attribution, unit economics | `resource-control`, `fin-hub` | outside the family, boundary undeclared |
| Q7 Governance and Change Management | the conformance loop, policy enforcement | — | **unowned** (§5.3) |
Q1 is worth dwelling on: S3 has been building a mature Q1 practice for months —
approval gates, delegated apply, revocation semantics, front-door readiness —
without ever naming the dimension. That is evidence the dimensions describe real
structure rather than imposing vocabulary.
#### Plane — operational responsibility · *implicit, unnamed*
| Sub-level | Railiance reality |
| --- | --- |
| P1 Workload Plane | `rapp-*` packages and the workloads they run |
| P2 Control Plane | ArgoCD, CNPG operator, External Secrets, cert-manager |
| P3 Management Plane | State Hub, `railiance-master`, workplans, decisions |
Railiance already operates all three; none is declared. This is the dimension
most likely to clarify the `rapp-*` / `rail-*` relationship, since a rail is
essentially a P1 contract.
#### Capability — stable capability modeling · *partial*
C1 Capability Model / C2 Contract / C3 Realization / C4 Shared Platform
Capabilities / C5 Business Capabilities.
`railiance-fabric` models C1C3; the per-repo `registry/capabilities/`
declarations and `reuse-surface` federation cover C4. C5 is unaddressed and is
where the boundary with `resource-control` / `fin-hub` (and Q6) belongs.
**Contradiction C1 lives here**: the hub's capability attributions do not match
repo declarations.
#### Logic — functional decomposition · *unused*
L1 Capability Domain / L2 Service Realization / L3 Composition and Integration /
L4 Solution Layer. No Railiance repo is organised on this axis. Lowest priority:
the Stack and Quality dimensions carry more weight for an operations framework,
and Logic is likely more relevant to Helix Forge's capability-first model.
#### Intelligence — degree of intelligent automation · *emerging, unnamed*
I1 Deterministic Automation / I2 Language Interaction / I3 Knowledge and
Reasoning / I4 Assisted Adaptation / I5 Agentic Delegation.
Already referenced in practice — `qonto-assistant/docs/SecurityPractice.md`
cites an "I1 Reinforced minimum" isolation profile — and the whole agent
operating model (autonomy lanes, Kaizen agents, `/ralph-workplan`) is I4I5
territory. Declared nowhere in Railiance. Given how much of this fleet is
agent-operated, leaving Intelligence unmodelled understates what the system
actually is.
### Establishing order
Recommended sequence, for `railiance-master` to ratify:
1. **Quality first.** It holds the most unowned concerns (Q3, Q7) and the
already-built-but-unnamed ones (Q1, Q4). Q2 has a home as of 2026-08-11.
2. **Plane second.** Cheap — it is descriptive of what already runs, and it
sharpens the `rail-*` contract.
3. **Capability third.** Requires resolving C1 (hub attribution drift) and C4
first, or the model is built on bad data.
4. **Intelligence fourth.** Needs a real decision about how much of the agent
operating model belongs in Railiance versus the-custodian.
5. **Logic last**, or never, if Helix Forge owns functional decomposition.
### The layering contract
Each layer hands the next a **verified** substrate and does not reach past its
neighbours. The handoffs are declared from both sides — S4 names its forge
contract for runner labels and registry endpoints; S5 names backup and
data-ownership handoffs with S3. Preserve this property when editing any
`INTENT.md`: a handoff stated by only one side is a latent boundary dispute.
---
## 3. The self-evidencing thread
Five layers independently declare the same aspiration in their
`Direction of Evolution`:
- S1 — "self-evidencing, auditable provisioning"
- S2 — "self-evidencing, auditable runtime state"
- S3 — "self-healing and observable platform services"
- S5 — "self-evidencing, reviewable application readiness"
- forge — "self-evidencing forge health and readiness checks"
**This is the architectural through-line of Railiance**: the system should prove
its own state rather than be asserted correct. It reached five INTENT files
independently and was never named as a fleet-wide quality dimension.
It has two halves, and they belong to different repos:
| Half | Question | Home |
| --- | --- | --- |
| **Evidence plane** | is the running system behaving as expected? | `railiance-telemetry` |
| **Conformance loop** | do declarations match reality and each other? | **OPEN** (§5.3) |
Both are required. Observability without conformance checking finds outages but
not drift; conformance checking without observability finds drift but not
outages.
---
## 4. Repository status
Not every `railiance-*` directory is a canonical repository. Verified
2026-08-11 by comparing remotes, HEADs, and working trees.
| Repo | Status | Evidence |
| --- | --- | --- |
| `railiance-infra` | **canonical S1** | active; strict content superset of `hosts` |
| `railiance-hosts` | **superseded** | distinct remote, unrelated history, byte-identical `INTENT.md`, **zero unique files**; quiet since 2026-07-30 |
| `railiance-cluster` | **canonical S2** | active; has `install/` and rail-kubernetes extraction docs |
| `railiance-bootstrap` | **superseded as S2; repurpose candidate** | distinct remote, unrelated history, declares itself S2 verbatim; frozen 2026-07-08. Carries `QUICKSTART.md` (newcomer path) — candidate home for *seeding a new Railiance* |
| `railiance-platform` | canonical S3 | active |
| `railiance-enablement` | canonical S4, **aspiration-only** | 25 commits, 0 workplans; widest aspiration-to-reality gap in the family |
| `railiance-apps` | canonical S5 | active |
| `railiance-telemetry` | **seeded** 2026-08-11 | `INTENT.md`/`SCOPE.md` written; no implementation |
| `railiance-master` | canonical meta | active |
| `railiance-fabric` | canonical meta | quiet since 2026-07-30; non-standard `INTENT.md` format |
| `railiance-forge` | canonical, **unplaced** | active workplan; not on any stack level |
### The duplication pattern
`bootstrap`, `cluster`, `hosts`, `infra` have **mutually unrelated git
histories but near-identical content**. They were created by copying working
trees into fresh repos as the S1/S2 layering idea emerged — not by forking.
Two lineages, each with a frozen elder and an active successor.
Consequence for tooling: **fleet inventories built by scanning directories
overcount.** Deduplicate by origin URL, not by directory name.
---
## 5. Open decisions
Each names the repo that decides it. None should be settled in `railiance-platform`.
### 5.1 Where does `railiance-telemetry` sit? → `railiance-master`
Observability is cross-cutting: it draws signal from every level and is consumed
by all of them. Is it an S3 platform capability (it runs stateful services and
is consumed by others), or a Quality-dimension concern outside the Stack
dimension? Stated explicitly at seeding so it does not drift into §5.2's state.
### 5.2 Where does `railiance-forge` sit? → **DECIDED 2026-08-11**
**Place it, do not retire it.** Operator decision:
- the Forgejo **workload** becomes `rapp-forgejo` (a managed workload package)
- the **layer responsibility** — runner placement and labels, registry
retention, artifact lifecycle, package credentials — folds into **S4
`railiance-enablement`**, which already declares the handoff contract for
exactly these concerns
This also gives S4, currently the widest aspiration-to-reality gap in the
family, its first concrete owned responsibility.
Implementation is `railiance-master` and `railiance-forge` territory; this
blueprint records the decision, not the migration.
The retirement hypothesis was **tested and rejected**: `railiance-forge`
and `helix-forge` are different lineages. `helix-forge` is methodological
(capability-first ecosystem, OAS dimensions, VSM vocabulary); `railiance-forge`
is operational (`helm/`, `manifests/`, `releases/`, `runner/`, live workplan on
Forgejo resource economics). Retiring it would orphan runner placement, registry
retention, and artifact lifecycle. **Place it, do not retire it.** The likely
resolution: the Forgejo *workload* becomes `rapp-forgejo`; the *layer*
responsibility folds into S4, which already declares the handoff contract.
### 5.3 Who owns the conformance loop? → `railiance-master`
Candidates: S4 (the paved-path layer), `railiance-master` (the definition home),
or a new responsibility repo. Related: the family declaration validator proposed
to `railiance-master` (`04c776c4`, amended `f88f938d`).
### 5.4 Retirement and repurposing → `railiance-master`, then the repos
- retire `railiance-hosts` (content-safe; **check git history before deletion**,
and move its live hub goal "Secure Single-Server Bootstrap at HostEurope" to
`railiance-infra` first, or it resurfaces as unstarted S1 work)
- repurpose `railiance-bootstrap` as the seed-a-new-Railiance repo, consolidating
the newcomer path that currently exists in both it and `railiance-cluster`
- delete the local `~/railiance-bootstrap` directory, which is a mis-cloned copy
of `railiance-cluster.git`
### 5.6 Does Railiance use ArgoCD? → **REOPENED 2026-08-12 on corrected evidence**
Decided 2026-08-11 as "keep it", on the basis that S3 runs ArgoCD as its live
deployment mechanism. **That basis was wrong.** Verified against both clusters
once API access was restored:
| Fact | Evidence |
| --- | --- |
| ArgoCD does **not** run on railiance01 | namespace `argocd` NotFound |
| ArgoCD runs on **CoulombCore** | `argocd` namespace, Active 344d |
| The Applications target **CoulombCore, not railiance01** | all four declare `server: https://kubernetes.default.svc` — in-cluster |
| Their health is poor | `issue-core` Degraded, `openbao-secretstore` Degraded, `target-revenue` OutOfSync/Missing |
| The real workloads run on **railiance01** | `target-revenue` deploy 1/1 up 6d, `openbao` sts 1/1, `external-secrets` 3 deploys 1/1 |
| Nothing on railiance01 is ArgoCD-managed | no namespace carries an `argocd.argoproj.io/instance` label |
So the live S3 workloads are deployed **outside GitOps**, by Makefile and hand,
while the ArgoCD Applications describe a deployment path into the **frozen**
CoulombCore cluster — where `target-revenue` is registered but Missing, and two
others are Degraded.
The earlier claim that removing ArgoCD documentation would "describe a system
that does not exist" was backwards: **the ArgoCD documentation already describes
a deployment path that is largely not in effect.**
This does not settle the question — it restates it honestly. Three real options:
1. **Adopt properly** — stand up ArgoCD on railiance01 and bring the live
workloads under GitOps. The Applications become true.
2. **Retire** — remove the Applications and `docs/argocd-gitops.md`, and accept
Makefile-driven deployment as the declared method.
3. **Relocate** — GitOps becomes Helix Forge tooling, as originally suspected.
Doing nothing is the one option with a cost: a stale control plane on a frozen
cluster, showing Degraded, that no longer reflects how anything ships. Note this
is the same defect class as `RAIL-HO-WP-0009` — declared state and live state
diverged, and nothing detected it.
### 5.5 Rapp granularity and composition → decided, implementation open
Grouped by bounded context; members declared explicitly; grouping legitimate
only where members share rollout and rollback fate (`7a1f7a7e`). A rapp declares
a **composition**: first-party member repos plus pinned upstream components plus
a stated purpose.
---
## 6. Known gaps, mapped to dimensions
Read with §2.1: most of these are not scattered omissions but **one unbuilt
dimension**.
| Gap | Dimension | State |
| --- | --- | --- |
| Observability | Q2 | home created 2026-08-11; **no implementation**, no monitoring namespace in-cluster |
| Conformance loop | Q7 | **unowned** (§5.3) |
| End-to-end restore proof | Q3 | split across S1, S3, S5; no single owner; backing object-storage decision escalated and unresolved (`9c21c0e0`) |
| Cost and resource attribution | Q6 | `resource-control` and `fin-hub` hold it; no `railiance-*` INTENT declares the boundary |
| Performance and scalability | Q5 | unaddressed |
| Identity dependency declaration | Capability | `net-kingdom` referenced in prose; rarely declared structurally. `railiance-fabric` exists to fix this |
## 6.1 Contradictions to resolve
Found by the 2026-08-11 coherence review. These are places where two parts of
Railiance currently say different things.
| # | Contradiction | Resolution |
| --- | --- | --- |
| C1 | **Capability attribution crosses layer boundaries.** State Hub attributes ~11 capabilities to `railiance-platform`, including Terraform server provisioning and Ansible hardening (S1), k3s provisioning and cluster addons (S2), CI/CD automation (S4), and application workload deployment (S5). `SCOPE.md` declares only four, all correctly S3, and the repo's boundary rule disowns the rest. These are pre-split attributions the hub never dropped. | `SCOPE.md` is source of truth; the hub needs reconciliation. Until then, hub capability data for this repo is not trustworthy for boundary reasoning. |
| C2 | **"Five independent repos per OAS Stack layer"** — stated in `SCOPE.md` — contradicts the four-axis model and the current inventory (§4). | Corrected in `SCOPE.md` 2026-08-11. |
| C3 | **One dimension in use, six required** by ratified canon (§2.1). | Route to `railiance-master` and `the-custodian`; implement Quality first. |
| C4 | **Ecosystem modelling is split four ways**`railiance-fabric` (graph), State Hub (read model), `reuse-surface` (capability federation), `railiance-master` (vocabulary). Fabric draws the boundary crisply in prose but does not mention `reuse-surface`. | Needs an explicit statement of who owns what; `railiance-master` and `railiance-fabric` territory. |
---
## 7. Sources
- `railiance-master/docs/repository-axes.md` — the four families
- `railiance-master/docs/repo-family-bootstrap-contract.md` — required declarations
- `railiance-master/docs/rapp-first-wave-candidates.md` — extraction criteria and sequencing
- `the-custodian/canon/standards/orthogonal-architecture_v1.0.md` — OAS, P1
- `railiance-platform/docs/rapp-platform-service-pattern.md` — S3 platform-service pattern
- `railiance-platform/history/2026-08-11-railiance-architecture-in-aspiration.md` — the INTENT-based assessment behind this blueprint
- decisions `7a1f7a7e` (rapp granularity), `d07ee5f9` (dimensional separation)