diff --git a/.repo-classification.yaml b/.repo-classification.yaml new file mode 100644 index 0000000..f39c68e --- /dev/null +++ b/.repo-classification.yaml @@ -0,0 +1,20 @@ +repo_classification: + standard: Repo Classification Standard + version: "1.0" + classified_at: "2026-07-25" + classified_by: agent + category: project + domain: financials + secondary_domains: + - infotech + capability_tags: + - platform + - governance + - documentation + - coordination + business_stake: + - technology + - operations + business_mechanics: + - coordination + - control diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..5e9c552 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,246 @@ +# railiance-master — Agent Instructions + +## Repo Identity + +**Purpose:** Railiance framework architecture home: repository taxonomy, architectural boundaries, framework-level ADRs, and cross-repo workplans for changes spanning multiple Railiance repositories. + +**Domain:** financials +**Repo slug:** railiance-master +**Topic ID:** `ca369340-a64e-442e-98f1-a4fa7dc74a38` +**Workplan prefix:** `RAILIANCE-WP-` + +--- + +## State Hub Integration + +The Custodian State Hub tracks work across all domains. Interact via HTTP REST — +there is no MCP server for Codex agents. + +| Context | URL | +|---------|-----| +| Local workstation | `http://127.0.0.1:8000` | +| Remote via tunnel | `http://127.0.0.1:18000` | +| Optional local edge relay | `http://127.0.0.1:18080` | + +When an operator has enabled the edge relay, set `API_BASE` to the relay URL. +Queueable writes return an explicit queued receipt if the central hub is +unreachable. Treat that as pending local evidence, then ask the operator to run +`statehub outbox status` or `statehub outbox replay` after connectivity returns. + +### Orient at session start + +```bash +# Offline brief — works without hub connection +cat .custodian-brief.md + +# Active workplans for this domain +python3 - <<'PY' +import json, urllib.request +with urllib.request.urlopen("http://127.0.0.1:8000/workplans/?topic_id=ca369340-a64e-442e-98f1-a4fa7dc74a38&status=active") as r: + print(json.dumps(json.loads(r.read().decode()), indent=2)) +PY + +# Check inbox +python3 - <<'PY' +import json, urllib.request +with urllib.request.urlopen("http://127.0.0.1:8000/messages/?to_agent=railiance-master&unread_only=true") as r: + print(json.dumps(json.loads(r.read().decode()), indent=2)) +PY +``` + +Mark a message read: + +```bash +python3 - <<'PY' +import json, urllib.request +req = urllib.request.Request( + "http://127.0.0.1:8000/messages//read", + data=b"{}", + headers={"Content-Type": "application/json"}, + method="PATCH", +) +with urllib.request.urlopen(req) as r: + print(r.read().decode()) +PY +``` + +### Log progress (required at session close) + +```bash +python3 - <<'PY' +import json, urllib.request +payload = { + "summary": "what was done", + "event_type": "note", + "author": "codex", + "workplan_id": "", + "task_id": "", +} +req = urllib.request.Request( + "http://127.0.0.1:8000/progress/", + data=json.dumps(payload).encode(), + headers={"Content-Type": "application/json"}, + method="POST", +) +with urllib.request.urlopen(req) as r: + print(r.read().decode()) +PY +``` + +Omit `workplan_id` or `task_id` when not applicable. + +### Update task status + +```bash +python3 - <<'PY' +import json, urllib.request +req = urllib.request.Request( + "http://127.0.0.1:8000/tasks/", + data=json.dumps({"status": "progress"}).encode(), + headers={"Content-Type": "application/json"}, + method="PATCH", +) +with urllib.request.urlopen(req) as r: + print(r.read().decode()) +PY +# values: wait | todo | progress | done | cancel +``` + +### Flag a task for human review + +```bash +python3 - <<'PY' +import json, urllib.request +req = urllib.request.Request( + "http://127.0.0.1:8000/tasks/", + data=json.dumps({"needs_human": True, "intervention_note": "reason"}).encode(), + headers={"Content-Type": "application/json"}, + method="PATCH", +) +with urllib.request.urlopen(req) as r: + print(r.read().decode()) +PY +``` + +--- + +## Session Protocol + +**Start:** +1. `cat .custodian-brief.md` — domain goal and open workplans (offline-safe) +2. Check inbox: `GET /messages/?to_agent=railiance-master&unread_only=true`; mark read +3. Scan `workplans/` — note `status: ready`, `active`, or `blocked` files and open tasks +4. Check human-needed tasks: `GET /tasks/?needs_human=true` + +**During work:** +- Update task statuses in workplan files as tasks progress +- Record significant decisions via `POST /decisions/` + +**Close:** +1. Update workplan file task statuses to reflect progress +2. If finishing a workplan: hand off residuals as live work records first +3. Log `POST /progress/` with a summary of what changed +4. After workplan file changes, run: + ```bash + statehub fix-consistency + ``` + Coding agents should run this directly; ask the operator only if the CLI or + State Hub API is unavailable. This syncs task status from files into the hub DB. + +--- + +## Credential and access routing + +**Audience:** Codex, Claude Code, Grok, and custodian agents that call **llm-connect** +for inference. Run this check **before** requesting secrets, API keys, SSH access, +login tokens, or database passwords — in any repo, not only `ops-warden`. + +`ops-warden` **issues SSH certificates only** (`warden sign`, `cert_command`). +Every other credential need belongs to another subsystem. Do not message +`ops-warden` on State Hub expecting a secret value; the reply is a pointer, not a key. + +### Lookup + +```bash +warden route find "" --json +warden route show --json +``` + +Requires the `warden` CLI from `~/ops-warden` (`uv tool install .` or `uv run warden`). + +### Quick routing table + +| I need… | Owner | ops-warden executes? | +| --- | --- | --- | +| SSH cert (`adm`/`agt`/`atm`) | ops-warden | Yes — `warden sign` | +| API key, DB password, provider token | OpenBao (`railiance-platform`) | No — route only | +| Login / OIDC / MFA | key-cape / Keycloak | No — route only | +| Authorization decision | flex-auth | No — route only | +| SSH tunnel | ops-bridge (+ `cert_command` from warden) | No — route only | + +### Anti-patterns + +- `POST /messages/` to `ops-warden` asking for secret values +- inventing unsupported `warden` subcommands +- pasting secrets into Git, State Hub, workplans, logs, or chat + +--- + +## Workplan Convention (ADR-001) + +Work items originate as files in this repo — not in the hub. The hub is a +read/cache/index layer that rebuilds from files. + +**File location:** `workplans/RAILIANCE-WP-NNNN-.md` + +**Archived location:** finished workplans may move to +`workplans/archived/YYMMDD-RAILIANCE-WP-NNNN-.md`. The `YYMMDD` prefix is +the completion/archive date; the frontmatter `id` does not change. + +**Ad Hoc Tasks:** small opportunistic fixes discovered during a session use +`workplans/ADHOC-YYYY-MM-DD.md` with task ids `ADHOC-YYYY-MM-DD-T01`, etc. +Use this only for low-risk work completed directly; create a normal workplan +for anything needing analysis, design, approval, dependencies, or multiple phases. + +**Frontmatter:** + +```yaml +--- +id: RAILIANCE-WP-NNNN +type: workplan +title: "..." +domain: financials +repo: railiance-master +status: proposed | ready | active | blocked | backlog | finished | archived +owner: codex +topic_slug: ... +created: "YYYY-MM-DD" +updated: "YYYY-MM-DD" +state_hub_workstream_id: "" # written by fix-consistency — do not edit +--- +``` + +Use `proposed` for a new draft, `ready` after review against current repo +state, and `finished` after implementation. `stalled` and `needs_review` +are derived health labels, not frontmatter statuses. + +**Task block format** (one per `##` section): + +```task +id: RAILIANCE-WP-NNNN-T01 +status: wait | todo | progress | done | cancel +priority: high | medium | low +state_hub_task_id: "" # written by fix-consistency — do not edit +``` + +Status progression: `todo` → `progress` → `done`; use `wait` for waiting or +blocked work and `cancel` for stopped work. + +### Repo-specific guidance + +Use `railiance-master` workplans for framework changes that span multiple +Railiance repos, especially repository taxonomy changes, architecture boundary +changes, and migrations introducing `rail-*`, `rapp-*`, or `reef-*` concepts. + +Do not use this repo to track implementation work that belongs entirely inside +one concrete ownership repo such as `railiance-platform` or `railiance-apps`. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..1b1b731 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,4 @@ +# railiance-master — Claude Code Instructions + +@SCOPE.md +@AGENTS.md diff --git a/INTENT.md b/INTENT.md new file mode 100644 index 0000000..c7d17b7 --- /dev/null +++ b/INTENT.md @@ -0,0 +1,188 @@ +# INTENT + +> This file captures **why this repository exists**, +> the **direction it is moving toward**, and +> the **kind of system it is meant to become**. +> It is intentionally **aspirational and stable**, not a description of current implementation. + +--- + +## One-liner + +**The Railiance architecture-definition home — turning evolving repo families, workload models, and substrate realities into a coherent framework vocabulary and boundary model.** + +--- + +## Why This Exists + +As Railiance grows, implementation repos naturally solve immediate problems: +infrastructure, cluster runtime, platform services, forge operations, +application releases, and ecosystem modeling. + +What those repos cannot safely do on their own is define the framework's shared +meaning. + +Without a canonical architecture home: + +* the same terms drift across repos, +* new repo families appear without clear boundaries, +* execution models and workload wrappers get mixed into the wrong layers, +* and migrations happen by local habit rather than deliberate framework design. + +This repository exists to define the **shared architectural language** of +Railiance before that language hardens accidentally inside implementation repos. + +--- + +## Operating Context + +Railiance does not exist in isolation. + +It is part of a wider, coevolving ecosystem around **Railiance**, **Net +Kingdom**, and the **Helix Forge** software factory. That ecosystem is +intended to support the full path from: + +* product ideation, +* discovery, +* delivery, +* operation, +* marketing, +* and monetization. + +The architecture therefore has to work across experimental and production-grade +realities at the same time. + +That matters because repo boundaries in Railiance are not only about code +organization. They shape how humans and agents coordinate responsibilities, +reason about workload placement, and evolve operating models without losing the +ability to scale into more mature security and delivery expectations. + +--- + +## The Mission + +> *Where we are going.* + +To become the **canonical home for Railiance framework architecture** — +where repository taxonomy, architectural boundaries, execution-model concepts, +managed workload patterns, substrate concepts, and migration direction are +defined once and referenced everywhere else. + +This means: + +* Railiance vocabulary is defined through **explicit architectural documents** +* New repo families and framework terms are introduced through **clear decisions** +* Ownership, execution mode, workload identity, and substrate identity remain + **separate and composable** +* Explorations mature into **stable decisions** before they spread across the + wider repo landscape +* The framework can support both **early-stage experimentation** and + **production-grade operation** without collapsing those needs into one vague + structure + +--- + +## Core Principles + +### 1. Architecture Before Proliferation + +New repo patterns should be named and bounded deliberately before they multiply +across the ecosystem. + +### 2. Shared Vocabulary Is Infrastructure + +Terms such as `railiance-*`, `rail-*`, `rapp-*`, and `reef-*` are not cosmetic. +They shape ownership, tooling, and operator understanding. + +### 3. Separate Axes Cleanly + +Ownership, execution architecture, workload packaging, and substrate reality +must not collapse into one ambiguous repo type. + +### 4. Decisions Need A Canonical Home + +Framework-level architecture decisions should live in one source-controlled +place rather than being reconstructed from scattered repo-local assumptions. + +### 5. Stable Meaning, Evolvable Model + +The framework vocabulary should stay understandable over time even as specific +rails, workloads, and substrates evolve. + +### 6. Guide Implementation, Do Not Shadow It + +This repo should define structure and direction, not absorb the operational +content that belongs in the implementation repos themselves. + +### 7. Stabilize The Default Path First + +Railiance should not introduce multiple top-level rails speculatively. + +The default path for platform services and managed applications is +`rail-kubernetes` until there is a concrete workload need and a sound argument +for a distinct rail. + +### 8. Managed Packaging Is Not Ownership + +`rapp-*` repos exist to wrap third-party or self-built workloads so they can be +run as fully managed Railiance workloads in the wider Railiance and Net Kingdom +context. + +They do not replace the ownership repos that define why a capability exists. + +### 9. Substrates Need Purpose, Not Just Names + +`reef-*` repos should represent compute resources organized around a defined +purpose and operational boundary. + +They should not be created merely because a named machine exists. + +--- + +## What This Is (Conceptually) + +This repository is: + +* an **architecture-definition home** +* a **repository taxonomy authority** +* a home for **framework-level ADRs and conceptual models** +* a place to define how Railiance repos **compose across multiple axes** +* a **migration map** from current repo reality toward cleaner framework + structure + +--- + +## What This Is Not + +This repository is not: + +* the infrastructure substrate +* the Kubernetes runtime or workload execution layer +* the shared platform-services layer +* the forge runtime +* the application release surface +* the implementation of the ecosystem graph registry +* a dumping ground for operational runbooks that belong elsewhere + +It is the **place where the framework explains itself**. + +--- + +## Direction of Evolution + +This repository is expected to evolve toward: + +* clearer **repository-family definitions** and lifecycle rules +* stable **rail**, **rapp**, and **reef** contracts +* stronger **boundary guidance** for new repos and migrations +* better linkage between architecture decisions and `railiance-fabric` + declarations +* a repeatable path from **exploration -> ADR -> adopted framework pattern** +* a clear model for when experimental multi-rail substrates are acceptable and + when production-grade separation is the better default + +--- + +## Guiding Question + +> **How can Railiance define its own structure clearly enough that every new repo, rail, managed workload, and substrate increases capability without increasing ambiguity, even as the ecosystem grows from exploratory operation into production-grade responsibility?** diff --git a/README.md b/README.md index 83aebae..ada35ea 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,38 @@ # railiance-master -Framework architecture for railiance applications, railiance rails, railiance tooling. This repo explains and evolves the concepts in and around railiance. \ No newline at end of file +Architecture home for the Railiance framework. + +This repository defines how Railiance concepts map to repositories, how the +different repo families compose, and where new architecture decisions should be +recorded before they are spread across implementation repos. + +## Current Architecture Baseline + +- [docs/repository-axes.md](docs/repository-axes.md) +- [docs/reef-substrate-model.md](docs/reef-substrate-model.md) +- [docs/rail-kubernetes-boundary.md](docs/rail-kubernetes-boundary.md) +- [docs/rapp-first-wave-candidates.md](docs/rapp-first-wave-candidates.md) +- [docs/reef-first-wave-rollout.md](docs/reef-first-wave-rollout.md) +- [docs/fabric-state-hub-adaptation.md](docs/fabric-state-hub-adaptation.md) +- [docs/adr/ADR-0001-repository-prefix-architecture.md](docs/adr/ADR-0001-repository-prefix-architecture.md) +- [docs/adr/ADR-0002-rail-kubernetes-wave-1-boundary.md](docs/adr/ADR-0002-rail-kubernetes-wave-1-boundary.md) +- [docs/adr/ADR-0003-rapp-first-wave-selection.md](docs/adr/ADR-0003-rapp-first-wave-selection.md) +- [docs/adr/ADR-0004-first-wave-reef-rollout.md](docs/adr/ADR-0004-first-wave-reef-rollout.md) + +## Current Explorations + +- [history/260724-InitialExplorationOfOperationModels.md](history/260724-InitialExplorationOfOperationModels.md) +- [history/260724-InitialExplorationOfWrapperConcepts.md](history/260724-InitialExplorationOfWrapperConcepts.md) + +## Purpose + +`railiance-master` is the canonical place to define: + +- repo-family vocabulary such as `railiance-*`, `rail-*`, `rapp-*`, and `reef-*` +- cross-repo architectural boundaries +- the relationship between ownership, execution mode, workload packaging, and + substrate realities +- the migration direction when current repos must be split or renamed + +Implementation repos should follow the architecture recorded here rather than +each inventing local meanings for the same terms. diff --git a/SCOPE.md b/SCOPE.md new file mode 100644 index 0000000..dd42b3a --- /dev/null +++ b/SCOPE.md @@ -0,0 +1,133 @@ +# SCOPE + +> This file helps you quickly understand what this repository is about, +> when it is relevant, and when it is not. +> It is intentionally lightweight and may be incomplete. + +--- + +## One-liner + +Architecture-definition home for Railiance: repository taxonomy, framework ADRs, +cross-repo boundary rules, and cross-repo workplans for architecture changes. + +--- + +## Core Idea + +`railiance-master` is the framework-level architecture repo for Railiance. +It exists so shared concepts such as `railiance-*`, `rail-*`, `rapp-*`, and +`reef-*` are defined once, with explicit boundaries, before they spread across +implementation repos. + +It also serves as the natural workplan home for changes that span multiple +Railiance repos and cannot be owned cleanly by only one of them. + +--- + +## In Scope + +- Framework-level architecture documents for Railiance +- Repository taxonomy and naming conventions +- Architectural boundaries between ownership repos, rails, `rapp`s, and reefs +- Architecture decision records affecting multiple Railiance repos +- Cross-repo Railiance workplans whose implementation spans multiple sibling repos + +--- + +## Out of Scope + +- OS provisioning and host hardening work owned by `railiance-infra` +- Kubernetes runtime implementation owned by `railiance-cluster` +- Platform-service implementation owned by `railiance-platform` +- Application release implementation owned by `railiance-apps` +- Forge runtime implementation owned by `railiance-forge` +- Fabric graph implementation owned by `railiance-fabric` + +--- + +## Relevant When + +- Defining a new Railiance repo family or framework term +- Clarifying boundaries between existing Railiance repos +- Planning migrations that touch multiple Railiance repos +- Recording a framework-level architecture decision + +--- + +## Not Relevant When + +- The work belongs entirely inside one implementation repo +- The work is operational rather than architectural +- The work is workload-specific rather than framework-wide + +--- + +## Current State + +- Status: maintained / evolving +- Implementation: architecture baseline documents are present and the first cross-repo separation workplan has been completed and handed off to sibling repos +- Stability: evolving +- Usage: internal Railiance framework architecture home and handoff point for cross-repo planning + +The repo now holds the canonical framework decisions and boundary documents for +separating `rail-*`, `rapp-*`, and `reef-*` concerns out of the existing +Railiance repos. Active implementation follow-up continues in the sibling +ownership repos. + +--- + +## How It Fits + +- Upstream dependencies: `the-custodian` canon and State Hub conventions +- Downstream consumers: all `railiance-*`, future `rail-*`, future `rapp-*`, and future `reef-*` repos +- Often used with: `railiance-fabric`, `railiance-platform`, `railiance-cluster`, `state-hub` + +--- + +## Terminology + +- Preferred terms: architecture home, repository axis, rail, `rapp`, reef, ownership repo +- Also known as: framework architecture repo +- Potentially confusing terms: this repo defines framework structure; it does not implement the lower-layer systems it describes + +--- + +## Related / Overlapping Repositories + +- `railiance-fabric` — models the ecosystem graph; `railiance-master` defines framework taxonomy and boundaries +- `state-hub` — indexes and coordinates work; `railiance-master` provides the framework architecture to be coordinated +- `repo-scoping` — explains what repos are useful for; `railiance-master` defines how Railiance repo families fit together + +--- + +## Getting Oriented + +- Start with: `README.md`, `INTENT.md` +- Key files / directories: `docs/`, `history/`, `workplans/` +- Entry points: `docs/repository-axes.md`, `docs/reef-substrate-model.md`, `docs/adr/` + +--- + +## Provided Capabilities + +```capability +type: documentation +title: Railiance repository taxonomy +description: Defines the canonical Railiance repo families and how ownership repos, rails, managed workloads, and substrate boundaries compose. +keywords: [railiance, architecture, taxonomy, rail, rapp, reef] +``` + +```capability +type: governance +title: Railiance framework architecture decisions +description: Records framework-level architecture decisions and boundary guidance for changes spanning multiple Railiance repos. +keywords: [architecture, adr, governance, boundaries, framework] +``` + +--- + +## Notes + +Use this repo for architecture that must stay shared. Push concrete +implementation outward into the ownership repos once the framework boundary is clear. diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md new file mode 100644 index 0000000..c62f478 --- /dev/null +++ b/WORK-RECORDS.md @@ -0,0 +1,18 @@ +# Work Records — railiance-master + +> Generated by `statehub fix-consistency` (CUST-WP-0061-T04, work-record +> stage 3). Do not edit by hand — edit the source file/block listed for +> each record and re-run fix-consistency to refresh this index. Archived +> workplans are omitted; closed decisions/intakes/engagements stay listed +> so recently-resolved work is still visible. [auto] + +| Kind | ID | Status | Lane | Source | +| --- | --- | --- | --- | --- | +| workplan | RAILIANCE-WP-0017 | finished | — | workplans/RAILIANCE-WP-0017-rail-rapp-reef-repo-separation.md | +| task | RAILIANCE-WP-0017-T01 | done | — | workplans/RAILIANCE-WP-0017-rail-rapp-reef-repo-separation.md | +| task | RAILIANCE-WP-0017-T02 | done | — | workplans/RAILIANCE-WP-0017-rail-rapp-reef-repo-separation.md | +| task | RAILIANCE-WP-0017-T03 | done | — | workplans/RAILIANCE-WP-0017-rail-rapp-reef-repo-separation.md | +| task | RAILIANCE-WP-0017-T04 | done | — | workplans/RAILIANCE-WP-0017-rail-rapp-reef-repo-separation.md | +| task | RAILIANCE-WP-0017-T05 | done | — | workplans/RAILIANCE-WP-0017-rail-rapp-reef-repo-separation.md | +| task | RAILIANCE-WP-0017-T06 | done | — | workplans/RAILIANCE-WP-0017-rail-rapp-reef-repo-separation.md | +| task | RAILIANCE-WP-0017-T07 | done | — | workplans/RAILIANCE-WP-0017-rail-rapp-reef-repo-separation.md | diff --git a/docs/adr/ADR-0001-repository-prefix-architecture.md b/docs/adr/ADR-0001-repository-prefix-architecture.md new file mode 100644 index 0000000..384b70a --- /dev/null +++ b/docs/adr/ADR-0001-repository-prefix-architecture.md @@ -0,0 +1,133 @@ +# ADR-0001: Repository Prefix Architecture + +Date: 2026-07-25 +Status: Accepted + +## Context + +Railiance already has a meaningful set of ownership repos such as +`railiance-infra`, `railiance-cluster`, `railiance-platform`, +`railiance-enablement`, `railiance-apps`, `railiance-forge`, and +`railiance-fabric`. + +That structure is useful, but it does not by itself capture all of the +dimensions Railiance now needs. + +In particular, the architecture needs clear source-controlled homes for: + +- workload execution contracts across different operations architectures, +- managed workload packages as first-class repos, +- and concrete substrate boundaries such as named servers, workstations, or + grouped environments. + +Without that separation, Kubernetes-specific workload semantics remain mixed +into `railiance-cluster`, workload wrappers remain mixed into ownership repos, +and concrete substrates remain under-described. + +Railiance also operates inside a wider ecosystem around Railiance, Net Kingdom, +and the Helix Forge software factory. That wider context needs architecture +that can support both exploratory operation and production-grade evolution +without leaving key responsibilities ambiguous. + +## Decision + +Railiance adopts four canonical repository families: + +1. `railiance-*` for ownership and responsibility areas +2. `rail-*` for workload execution contracts +3. `rapp-*` for Railiance-managed workload packages +4. `reef-*` for durable substrate boundaries + +The current implementation wave is explicitly centered on `rail-kubernetes` as +the default base rail. Additional rails are introduced only when a concrete +workload has a sound reason to run on a distinct execution architecture. + +`rail-knative` is the first expected follow-on rail, motivated by the need to +support `qonto-assistent`, but it should follow the `rail-kubernetes` boundary +cleanup rather than bypass it. + +## Meaning Of Each Family + +### `railiance-*` + +Owns major architectural responsibilities, shared policies, and durable layer +boundaries. + +### `rail-*` + +Owns how workloads run on a specific execution architecture such as Kubernetes, +Knative, KEDA, Fission, or Nuclio. + +In the current phase, `rail-kubernetes` is the default path for platform +services and managed applications. + +### `rapp-*` + +Owns the managed workload package for one service or application, whether it is +an internal workload or a wrapped upstream product. + +Its role is to provide the managed wrapper and scaffolding needed to run that +workload in the Railiance and Net Kingdom context. It does not replace +responsibility ownership. + +### `reef-*` + +Owns the concrete substrate reality where rails and `rapp`s are bound, such as +a named server, cluster, workstation, or grouped substrate class. + +A reef is about purpose-bound compute resources, not merely about individual +machines. + +## Consequences + +### Positive + +- Ownership, execution, workload identity, and substrate identity become + separate concerns. +- Railiance can support multiple execution architectures without forcing all + workload semantics into `railiance-cluster`. +- Platform services and applications can both become first-class managed + workload packages where appropriate. +- Concrete substrates gain a clear architectural home without overloading the + ownership repos. +- The framework gains a disciplined default path for introducing new rails + instead of proliferating them speculatively. + +### Required Follow-On Work + +- Define the initial `rail-*` contracts, starting with `rail-kubernetes`. +- Evolve the current `railiance/app.toml` and overlay pattern into a + rail-aware, eventually rail-neutral workload packaging contract. +- Identify which current workloads should become `rapp-*` repos. +- Extend `railiance-fabric` so rails, `rapp`s, and reefs become graph-native. +- Define when mixed-rail reefs are acceptable and when clearer substrate + separation should be preferred. + +### Constraints + +- `reef-*` must not become a default one-repo-per-machine pattern. +- Generic logic stays in the appropriate ownership repo. +- A named machine gets its own reef only when that machine is itself a durable + substrate boundary. +- `rapp-*` repos must not become shadow ownership repos. +- Transitional substrate labels should not be canonized before the pattern is + operationally stable. + +## Current Interpretation For Existing Repos + +- `railiance-*` repos remain the primary ownership axis. +- Current workload-execution logic in `railiance-cluster` is a candidate to + migrate into `rail-kubernetes`. +- Current workload wrappers inside `railiance-apps`, `railiance-platform`, or + `railiance-forge` may evolve into `rapp-*` repos over time. +- Current named substrates such as COULOMBCORE, RAILIANCE01, and WORKSTATION + may justify `reef-*` repos when they represent real operational boundaries. +- A reef may host more than one rail in early or mixed environments, but + production-critical substrates should prefer clearer purpose and primary-rail + boundaries unless a mixed design is justified. + +## Notes + +This ADR defines the repository taxonomy. It does not yet mandate a full +migration or rename of existing repos. Migration should happen when it produces +clearer ownership and lower ambiguity, not merely for naming purity. diff --git a/docs/adr/ADR-0002-rail-kubernetes-wave-1-boundary.md b/docs/adr/ADR-0002-rail-kubernetes-wave-1-boundary.md new file mode 100644 index 0000000..341a8a2 --- /dev/null +++ b/docs/adr/ADR-0002-rail-kubernetes-wave-1-boundary.md @@ -0,0 +1,64 @@ +# ADR-0002: Wave 1 `rail-kubernetes` Boundary + +Date: 2026-07-25 +Status: Accepted + +## Context + +Railiance wants `rail-*` repos to represent workload execution contracts rather +than abstract naming ideas. + +Today, the concrete Kubernetes workload contract already exists, but it is +embedded in `railiance-cluster`. That repo currently owns both: + +- the S2 Kubernetes substrate +- and the generic workload lifecycle and tooling that run on top of it + +That mixed ownership is the main blocker to introducing the first real rail. + +## Decision + +Railiance will treat `rail-kubernetes` as the wave-1 base rail. + +The boundary is: + +- `railiance-cluster` owns the Kubernetes substrate and its prerequisites +- `rail-kubernetes` owns the generic workload-on-Kubernetes execution contract + +Workload-specific helper flows currently living in `railiance-cluster` are +temporary exceptions and must be rehomed rather than carried forward as part of +the generic rail. + +## Consequences + +### Positive + +- The first real rail gains a concrete ownership boundary. +- `railiance-cluster` can return to a clean S2 substrate identity. +- Future rails such as `rail-knative` get a stable base boundary to extend from. +- `rapp-*` repos gain a clearer execution-contract home for Kubernetes-managed + workloads. + +### Required Follow-On Work + +- Create the detailed `rail-kubernetes` boundary contract and migration map. +- Split generic lifecycle docs, schema, examples, and Stage 1-3 tooling out of + `railiance-cluster`. +- Leave a compatibility path so current users of the cluster repo are not + broken during the migration. +- Rehome workload-specific helpers that do not belong in either boundary. + +### Constraints + +- `rail-kubernetes` must not take ownership of cluster bootstrap, operators, or + kubeconfig management. +- `railiance-cluster` must not continue as the owner of generic workload + promotion semantics after the split. +- `rail-knative` should follow this cleanup, not bypass it. + +## Notes + +This ADR does not require all current files to move immediately. + +It requires the ownership line to be explicit now, so practical repo separation +can proceed without ambiguity. diff --git a/docs/adr/ADR-0003-rapp-first-wave-selection.md b/docs/adr/ADR-0003-rapp-first-wave-selection.md new file mode 100644 index 0000000..6f5dcd9 --- /dev/null +++ b/docs/adr/ADR-0003-rapp-first-wave-selection.md @@ -0,0 +1,57 @@ +# ADR-0003: First-Wave `rapp-*` Selection + +Date: 2026-07-25 +Status: Accepted + +## Context + +Railiance wants `rapp-*` repos to represent managed workload packages rather +than new ownership layers. + +The current workload surfaces already suggest several candidates: + +- OpenBao in `railiance-platform` +- the forge workload in `railiance-forge` +- multiple S5 workloads in `railiance-apps` + +But they are not equally ready for first extraction. + +## Decision + +The first-wave `rapp-*` order is: + +1. `rapp-openbao` +2. `rapp-vergabe-teilnahme` +3. later `rapp-forgejo` after the forge runtime target stabilizes + +The forge workload is explicitly deferred from the first wave because current +Gitea operation and future Forgejo direction are both active realities. + +## Consequences + +### Positive + +- The first `rapp-*` extraction proves the third-party platform-service wrapper + model. +- The second proves the user-facing self-built app wrapper model. +- The deferred forge wrapper avoids immediate rename churn and packaging + ambiguity. + +### Required Follow-On Work + +- Write repo-local extraction work for `rapp-openbao`. +- Write repo-local extraction work for `rapp-vergabe-teilnahme`. +- Reassess the forge wrapper when the production package target is no longer + split between current Gitea and future Forgejo. + +### Constraints + +- `rapp-*` repos must stay packaging-focused and must not become shadow + ownership repos. +- Shared S3 policy stays in `railiance-platform`. +- Shared S5 release patterns stay in `railiance-apps`. + +## Notes + +This ADR chooses sequence, not a mandatory destination for every workload in the +ecosystem. diff --git a/docs/adr/ADR-0004-first-wave-reef-rollout.md b/docs/adr/ADR-0004-first-wave-reef-rollout.md new file mode 100644 index 0000000..fca4c9d --- /dev/null +++ b/docs/adr/ADR-0004-first-wave-reef-rollout.md @@ -0,0 +1,61 @@ +# ADR-0004: First-Wave `reef-*` Rollout + +Date: 2026-07-25 +Status: Accepted + +## Context + +Railiance now has a reef model, but it needs a concrete first rollout. + +The current substrate reality is not uniform: + +- Railiance01 is the clearest new-workload home +- CoulombCore is still active but transitional +- the workstation role is operator edge compute rather than server substrate + +At the same time, S1 ownership is ambiguous because `railiance-hosts` and +`railiance-infra` duplicate each other. + +## Decision + +The first-wave reef rollout is: + +1. `reef-railiance01` +2. `reef-coulombcore` +3. `reef-ops-workstations` + +`railiance-infra` is the canonical S1 ownership repo going forward. + +`railiance-hosts` is treated as predecessor or duplicate state to be retired, +frozen, or reduced later rather than as a second canonical S1 architecture home. + +## Consequences + +### Positive + +- Railiance gets a primary home-reef seed without waiting for a multi-node + future. +- Transitional CoulombCore reality is acknowledged without being treated as the + long-term preferred production pattern. +- Operator edge compute is modeled without defaulting to one repo per machine. +- Reef planning now rests on one canonical S1 ownership line. + +### Required Follow-On Work + +- Create repo-local rollout work for the first reef repos. +- Decide whether Railiance01 later remains a singleton reef or becomes part of + a grouped home reef. +- Plan the `railiance-hosts` cleanup direction relative to `railiance-infra`. + +### Constraints + +- Multi-rail reefs are acceptable early, especially on transitional substrates. +- Production-grade separation should still prefer clearer purpose and primary + rail boundaries as criticality rises. +- Transitional substrate nicknames should remain provisional until the pattern + is stable enough to canonize. + +## Notes + +This ADR chooses the first rollout set. It does not require that every future +substrate be modeled the same way. diff --git a/docs/fabric-state-hub-adaptation.md b/docs/fabric-state-hub-adaptation.md new file mode 100644 index 0000000..fd0620e --- /dev/null +++ b/docs/fabric-state-hub-adaptation.md @@ -0,0 +1,187 @@ +# Fabric And State Hub Adaptation For `rail-*`, `rapp-*`, And `reef-*` + +Date: 2026-07-25 + +## Purpose + +List the minimum adaptation requirements so rails, `rapp`s, and reefs become +visible ecosystem entities rather than only naming conventions. + +This is a requirements document, not an implementation plan for one repo. + +## Current Gaps + +The current ecosystem tooling still reflects the older repo shape. + +Observed gaps: + +- `railiance-fabric/registry/railiance-repos.yaml` does not yet onboard + `railiance-master` or `railiance-forge`. +- Fabric has a `kubernetes-runtime` capability type, but no first-class + vocabulary for execution rails, managed workload packages, or substrate + boundaries. +- `railiance-apps` is modeled as one aggregate S5 release surface rather than a + future set of `rapp-*` package repos. +- State Hub registration and generated repo summaries do not expose repo family + or rail/rapp/reef-specific metadata. + +If left unchanged, Git will know the new taxonomy before the coordination and +graph systems do. + +## Minimum Questions The Systems Must Answer + +After adaptation, the systems should be able to answer at least: + +- which `rail-*` repos exist? +- which rail is the default base rail? +- which `rapp-*` packages support which rails? +- which reefs host which rails? +- which reefs bind or approve which `rapp`s? +- which ownership repo remains responsible for a given rail, `rapp`, or reef? + +## Minimal State Hub Requirements + +State Hub does not need a second work-tracking model, but it does need better +repo metadata. + +### Required repo metadata + +Add or derive the following repo-level concepts: + +- `repo_family`: `ownership` | `rail` | `rapp` | `reef` +- `ownership_repo`: canonical owning `railiance-*` repo when the repo family is + not `ownership` +- `primary_rail`: for reefs or workloads where one rail is the declared default +- `supported_rails`: for `rapp-*` repos +- `substrate_kind`: for `reef-*` repos, such as `server`, `cluster`, + `workstation-group`, or `edge` + +These fields may start in `.repo-classification.yaml` or a repo-local +companion metadata file if the classification schema should stay smaller. + +### Required indexing behavior + +- State Hub should index `rail-*`, `rapp-*`, and `reef-*` repos like any other + repo for workplans, tasks, and progress. +- Generated repo briefs should display repo family and any declared ownership + repo or primary rail when available. +- Repo search and inventory views should be filterable by repo family. + +### Not required + +- no separate workplan model for rails, `rapp`s, or reefs +- no special task state machine +- no custom approval workflow just because a repo uses one of the new prefixes + +## Minimum Fabric Requirements + +Fabric needs enough typed vocabulary to model the new repo families without +waiting for a perfect new object taxonomy. + +### Immediate onboarding requirements + +- add `railiance-master` to `registry/railiance-repos.yaml` +- add `railiance-forge` to `registry/railiance-repos.yaml` +- be ready to add future `rail-*`, `rapp-*`, and `reef-*` repos as first-class + registered repositories + +### Immediate modeling requirements + +Fabric should add typed representation for: + +- execution rails +- managed workload packages +- substrate boundaries + +The minimum viable way to do that is: + +- add repo-family-aware metadata in registration and graph export +- add new `service_type` values: + - `execution-rail` + - `managed-workload-package` + - `substrate-boundary` +- add one new capability type for rails: + - `workload-execution-contract` + +This keeps the first rail queryable as a provider-like ecosystem object without +forcing `rapp`s and reefs into the wrong provider/consumer semantics. + +### Relation requirements + +Fabric needs explicit relations for: + +- `supports_rail`: `rapp` -> `rail` +- `hosts_rail`: reef -> `rail` +- `binds_rapp`: reef -> `rapp` +- `governed_by`: rail/`rapp`/reef -> ownership repo + +These relations may begin as projected registry edges even if the declaration +schema evolves later. + +The important part is that the graph can answer the topology questions above. + +## Minimum Repo-Local Declaration Requirements + +Every future repo family needs a small, obvious declaration surface. + +### `rail-*` + +Minimum declaration concepts: + +- rail id +- owning repo +- execution architecture +- substrate prerequisites +- supported rollout modes +- compatibility notes for participating `rapp`s + +### `rapp-*` + +Minimum declaration concepts: + +- workload package id +- upstream or source workload identity +- owning repo +- supported rails +- runtime dependencies +- rollout, smoke, and rollback contract + +### `reef-*` + +Minimum declaration concepts: + +- substrate id +- substrate kind +- lifecycle and criticality +- hosted rails +- bound or approved `rapp`s +- primary rail, if one exists + +These declarations may begin as repo-local YAML files or be projected from +existing source files. The key requirement is that they are source-controlled +and ingestible. + +## Compatibility Guidance + +Do not block the repo-family rollout on a perfect Fabric redesign. + +Recommended compatibility-first path: + +1. register the repos and family metadata +2. add the minimum new service and relation vocabulary +3. let the first `rail-*`, `rapp-*`, and `reef-*` repos publish small + declaration files +4. ingest those declarations into Fabric and State Hub projections +5. only then decide whether stronger first-class schema kinds are needed + +This avoids waiting for a large graph refactor before the architecture can move. + +## Outcome + +The minimal adaptation target is: + +- State Hub understands which repo family a repo belongs to +- Fabric can show rails, `rapp`s, and reefs as typed ecosystem entities +- the graph can answer rail/package/substrate placement questions +- new repo families are coordinated by the same workplan and progress system as + the existing Railiance repos diff --git a/docs/rail-kubernetes-boundary.md b/docs/rail-kubernetes-boundary.md new file mode 100644 index 0000000..d8ee104 --- /dev/null +++ b/docs/rail-kubernetes-boundary.md @@ -0,0 +1,200 @@ +# Wave 1 `rail-kubernetes` Boundary + +Date: 2026-07-25 + +## Purpose + +Define the wave-1 extraction boundary between `railiance-cluster` and a future +`rail-kubernetes` repo. + +This document exists to make `rail-kubernetes` real rather than rhetorical. +Today, `railiance-cluster` already contains the practical contract for running +managed workloads on Kubernetes: + +- `docs/deployment-lifecycle.md` +- `docs/app-toml-contract.md` +- `docs/overlay-repo-pattern.md` +- `schemas/railiance-app.schema.json` +- `examples/railiance/app.toml` +- `bin/railiance` +- `tools/cmd/railiance-run` +- `tools/cmd/railiance-stage2` +- `tools/cmd/railiance-stage3` +- `tools/create_railiance_overlay_repo.sh` + +That is already a rail in substance. The problem is that it currently lives +inside the S2 cluster-runtime repo. + +## Decision Summary + +- `rail-kubernetes` is the default base rail for wave 1. +- `railiance-cluster` remains the S2 owner of the Kubernetes substrate. +- `rail-kubernetes` owns the generic workload-on-Kubernetes execution contract. +- Workload-specific helpers currently living in `railiance-cluster` are not + part of the long-term boundary for either repo. They are migration debt that + must be rehomed. + +## What `railiance-cluster` Keeps + +`railiance-cluster` remains responsible for the Kubernetes substrate itself. + +It keeps ownership of: + +- k3s installation, upgrade, and baseline configuration +- cluster networking, ingress controllers, DNS, and certificate plumbing +- cluster operators and addons such as cert-manager, CloudNative PG operator, + ArgoCD, admission controllers, and similar cluster-scoped services +- kubeconfig management, runtime access patterns, and cluster backup/restore + posture +- cluster smoke tests that prove substrate readiness +- cluster-level runbooks for substrate recovery, upgrade, access, and failure + handling +- cluster capability declarations that tell higher layers what the substrate + actually supports + +`railiance-cluster` may describe the prerequisites a rail needs from the +substrate, but it should not own the workload lifecycle semantics that run on +top of those prerequisites. + +## What `rail-kubernetes` Must Own + +`rail-kubernetes` owns the generic contract for Railiance-managed workloads +that run on Kubernetes. + +It should own: + +- the three-stage lifecycle semantics for Kubernetes-backed workloads +- the canonical `railiance/app.toml` contract for the Kubernetes rail +- the machine-readable schema and reference example for that contract +- the generic Stage 1, Stage 2, and Stage 3 CLI/tooling +- Kubernetes-specific check types, rollout modes, and rollback expectations +- the generic packaging pattern for Kubernetes-managed `rapp`s +- the generic repo scaffold for Kubernetes-targeting wrappers +- compatibility guidance for how a `rapp` declares Kubernetes namespaces, + releases, probes, ingress, routing, and rollback +- the documented compatibility path from today's overlay pattern into future + `rapp-*` repos + +In short: + +- `railiance-cluster` answers "is the Kubernetes substrate present and healthy?" +- `rail-kubernetes` answers "how does a Railiance-managed workload run on that + substrate?" + +## What Should Not Stay In Either Boundary + +Some items currently inside `railiance-cluster` are not good long-term +residents of either `railiance-cluster` or the future `rail-kubernetes`. + +Examples include workload-specific helpers such as: + +- `deploy-triage-robustness` +- `admin-sync-smoke` +- workload-specific runtime reconcile flows tied to `activity-core` or similar + single-workload concerns + +These belong with the owning workload or ownership repo unless they are +refactored into clearly generic rail behavior. + +`rail-kubernetes` must not become a second junk drawer after the split. + +## File And Artifact Migration Map + +| Current location in `railiance-cluster` | Target owner | Notes | +| --- | --- | --- | +| `docs/deployment-lifecycle.md` | `rail-kubernetes` | Generic workload lifecycle, no longer S2-owned | +| `docs/app-toml-contract.md` | `rail-kubernetes` | Base rail contract for Kubernetes-managed workloads | +| `schemas/railiance-app.schema.json` | `rail-kubernetes` | Versioned workload declaration schema | +| `examples/railiance/app.toml` | `rail-kubernetes` | Reference contract example | +| `docs/overlay-repo-pattern.md` | `rail-kubernetes` | Keep as compatibility doc, evolve toward `rapp-*` language | +| `tools/create_railiance_overlay_repo.sh` | `rail-kubernetes` | Keep behavior initially, then retarget toward `rapp-*` scaffolding | +| `docs/railiance-run-command.md` | `rail-kubernetes` | Stage 1 command reference | +| `docs/stage2-deploy-observe.md` | `rail-kubernetes` | Stage 2 command reference | +| `tools/cmd/railiance-run` | `rail-kubernetes` | Generic Stage 1 tooling | +| `tools/cmd/railiance-stage2` | `rail-kubernetes` | Generic Stage 2 tooling | +| `tools/cmd/railiance-stage3` | `rail-kubernetes` | Generic Stage 3 tooling | +| `bin/railiance` generic lifecycle commands | `rail-kubernetes` | `run`, `deploy`, `observe`, `promote`, `rollback`, `create-overlay` | +| `bin/railiance` substrate/bootstrap commands | `railiance-cluster` | `doctor`, `plan-host`, `cloudinit`, `backup`, `preflight`, similar substrate helpers | +| `tests/smoke_kube.sh`, cluster bootstrap tests | `railiance-cluster` | Substrate health proof | +| workload-specific reconcile helpers | rehome later | Move to owner repo or rewrite as generic rail helpers | + +## The Interface Between The Two Repos + +The clean split depends on a narrow interface. + +`railiance-cluster` should publish a Kubernetes substrate profile that +`rail-kubernetes` can consume. At minimum, that profile should declare: + +- cluster distro and supported Kubernetes version range +- ingress controller and ingress classes +- supported canary modes, such as `isolated` and optional `weighted` +- certificate management path +- default storage classes and stateful-workload constraints +- required or optional operators available to workloads +- namespace and RBAC expectations for managed workloads +- observability surfaces available for health, logs, and metrics +- approved secret-delivery patterns available on this substrate + +`rail-kubernetes` should not assume a capability the substrate profile does not +declare. + +This keeps the substrate owner and the rail owner separate while still letting +them compose. + +## Migration-Safe Path + +The split should happen in six steps. + +1. Create `rail-kubernetes` with the copied contract docs, schema, examples, + and generic Stage 1-3 tooling now living in `railiance-cluster`. +2. Leave compatibility shims in `railiance-cluster` for one migration window. + The cluster repo may keep a thin `bin/railiance` wrapper that delegates the + generic lifecycle commands to `rail-kubernetes`. +3. Update the moved docs in `railiance-cluster` to become short boundary notes + that point to `rail-kubernetes` as the owning source. +4. Keep accepting the current `-railiance-overlay` pattern during the + migration window, even though the long-term direction is toward `rapp-*`. +5. Rehome or delete workload-specific helpers that do not belong in either the + substrate repo or the generic Kubernetes rail. +6. Only after `rail-kubernetes` is stable should Railiance add `rail-knative`. + +This path avoids breaking current users while making the new boundary real. + +## Follow-On Path For `rail-knative` + +`rail-knative` is the first expected follow-on rail, motivated by the need to +run `qonto-assistent`. + +That follow-on rail should: + +- depend on the Kubernetes substrate being described cleanly first +- reuse the top-level Railiance workload and promotion model where that remains + sensible +- own Knative-specific runtime semantics such as revisions, scale-to-zero, + traffic splitting, activator behavior, and event-driven behavior +- avoid forcing Knative-specific design choices back into the wave-1 + `rail-kubernetes` boundary + +The test for wave 1 is not "can Railiance describe all future rails now?" + +The test is "can Railiance separate the Kubernetes base rail cleanly enough +that `rail-knative` can be added later without another taxonomy rewrite?" + +## Risks To Watch + +- If `railiance-cluster` keeps generic workload lifecycle ownership, + `rail-kubernetes` will be nominal only. +- If `rail-kubernetes` absorbs substrate bootstrap and operator ownership, it + stops being a rail and becomes a second cluster repo. +- If workload-specific helpers are moved unchanged into `rail-kubernetes`, the + split will preserve the current ambiguity instead of reducing it. +- If `rapp-*` migration is delayed too long, the old overlay naming and the new + workload-package model will drift apart. + +## Outcome + +Wave 1 should produce a base Kubernetes rail with a clean contract and a +backward-compatible migration path. + +That is enough to start practical repo separation without pretending the rest +of the rail family already exists. diff --git a/docs/rapp-first-wave-candidates.md b/docs/rapp-first-wave-candidates.md new file mode 100644 index 0000000..37a9f17 --- /dev/null +++ b/docs/rapp-first-wave-candidates.md @@ -0,0 +1,169 @@ +# First-Wave `rapp-*` Candidates + +Date: 2026-07-25 + +## Purpose + +Choose and order the first `rapp-*` candidates for Railiance. + +`rapp-*` repos are for managed workload packaging and scaffolding. They are not +new ownership homes. The decision here is therefore not "which repos are +important?" but "which workloads already have a strong enough package boundary +to become first-class managed wrappers without weakening ownership?" + +## Selection Criteria + +The first-wave candidates should satisfy most of the following: + +- stable workload identity +- clear upstream or source workload boundary +- clear Kubernetes package surface already visible in Git +- explicit runtime-secret and dependency handling +- deploy, verify, and recover behavior already described +- low ambiguity between packaging ownership and domain ownership +- good demonstration value for later `rapp-*` extractions + +## Assessed Candidates + +### 1. OpenBao from `railiance-platform` + +Assessment: **choose first** + +Why it fits: + +- It is a clear third-party upstream product with durable identity. +- The workload already has a substantial Railiance packaging surface: + `helm/openbao-values.yaml`, middleware, UI overlay assets, deploy/verify + scripts, and operator runbooks. +- The repo already distinguishes between the OpenBao workload itself and the + wider S3 platform policy that consumes it. +- It is important enough to prove that `rapp-*` is not only for user-facing + apps; platform services can also be managed workloads. + +What should move into `rapp-openbao`: + +- Helm values and Kubernetes-facing package assets for the OpenBao workload +- UI overlay wrapper assets +- generic deploy, verify, and workload-health runbooks +- workload-specific smoke and recovery expectations + +What should remain in `railiance-platform`: + +- the S3 ownership of secrets custody as a platform capability +- workload lane policy, credential approval, and platform-wide access models +- cross-workload secret-delivery conventions consumed by many workloads + +Conclusion: + +`rapp-openbao` should be the first `rapp-*` extraction. + +### 2. Forge workload from `railiance-forge` + +Assessment: **defer from first wave** + +Why it is not first: + +- The current live workload is still Gitea on CoulombCore. +- The intended production direction is Forgejo on Railiance01. +- Packaging identity is therefore not stable enough yet: extracting now would + either enshrine a temporary Gitea compatibility package or pretend the + Forgejo cutover is already complete. +- The runtime and migration story still spans current Gitea operation, future + Forgejo deployment, runner substrate, registries, and cutover sequencing. + +Decision: + +- Do **not** make the forge workload the first `rapp-*` extraction. +- Prefer `rapp-forgejo` as the eventual target package once the production + direction is the real operating target. +- Create `rapp-gitea` only if Railiance discovers it needs a long-lived + compatibility wrapper for the current workload rather than a short migration + bridge. + +What this means: + +- `railiance-forge` keeps runtime ownership for now. +- The forge wrapper should follow after the current Gitea-versus-Forgejo + packaging identity stops moving. + +Conclusion: + +The forge workload is packaging-worthy, but it should not be first-wave +`rapp-*`. + +### 3. User-facing S5 workload from `railiance-apps` + +Assessment: **choose `vergabe-teilnahme` for wave 1** + +Why `vergabe-teilnahme` wins the S5 slot: + +- It is clearly user-facing and already operates as one named workload package. +- Its release surface is explicit: chart, values, ingress, deployment targets, + migration command, smoke checks, and operator runbook. +- Secret handling is clear without being entangled with shared platform + semantics: app credentials are consumed from Kubernetes Secrets and the app + env secret is locally rebuilt by operator procedure. +- It is simpler and more stable than the current Core Hub / Inter-Hub history + and more obviously user-facing than service-style workloads such as + `reuse-surface`. + +What should move into `rapp-vergabe-teilnahme`: + +- the chart and workload values +- the ingress and app-specific release runbook +- workload-specific rollout, migration, smoke, and rollback guidance +- workload-specific secret consumption contract + +What should remain in `railiance-apps`: + +- S5 ownership of generic application release patterns +- reusable onboarding and operator recipes +- cross-app S5 guardrails that should not be duplicated per workload package + +Second-wave S5 note: + +- `reuse-surface` is the strongest follow-on self-built service candidate after + `vergabe-teilnahme`, because it already shows explicit OpenBao-backed runtime + secret lanes and a tidy single-workload chart surface. +- `core-hub` and retired `inter-hub` should wait because their packaging + history is still entangled with cutover and legacy service evolution. + +Conclusion: + +`rapp-vergabe-teilnahme` should be the first user-facing S5 `rapp-*`. + +## First-Wave Order + +The recommended order is: + +1. `rapp-openbao` +2. `rapp-vergabe-teilnahme` +3. `rapp-forgejo` after the forge runtime target is stable enough to avoid + immediate rename or migration churn + +This order is intentional. + +- `rapp-openbao` proves the third-party platform-service wrapper model. +- `rapp-vergabe-teilnahme` proves the self-built user-facing app wrapper model. +- The forge wrapper then follows with a clearer target identity and after the + first two wrappers have established the pattern. + +## Risks To Watch + +- If `rapp-openbao` absorbs platform-wide policy and credential-governance + logic, the wrapper will become a shadow S3 repo. +- If `rapp-vergabe-teilnahme` absorbs generic S5 onboarding or app recipes, it + will weaken `railiance-apps` as the shared S5 release home. +- If the forge wrapper is extracted too early, Railiance will immediately face + a Gitea-versus-Forgejo package rename or parallel-wrapper problem. + +## Outcome + +Railiance now has a concrete first-wave `rapp-*` sequence: + +- first `rapp-openbao` +- then `rapp-vergabe-teilnahme` +- then the forge wrapper once the production package identity is stable + +That is enough to start repo-local extraction planning without pretending every +workload needs its own `rapp` immediately. diff --git a/docs/reef-first-wave-rollout.md b/docs/reef-first-wave-rollout.md new file mode 100644 index 0000000..ca652cc --- /dev/null +++ b/docs/reef-first-wave-rollout.md @@ -0,0 +1,183 @@ +# First-Wave `reef-*` Rollout + +Date: 2026-07-25 + +## Purpose + +Apply the `reef-*` model to the current Railiance substrate reality and choose +the first actual reef rollout. + +This document intentionally decides both: + +- which reefs should exist first +- and which current repo should remain the canonical S1 ownership home while + reefs are introduced + +## Current Substrate Reality + +Railiance currently has three clearly different substrate realities: + +### `RAILIANCE01` + +- HostEurope server at `92.205.62.239` +- the most mature current home for new Kubernetes-first workloads +- already hosts Forgejo and overlapping platform services +- likely seed of a future multi-server Railiance home substrate + +### `COULOMBCORE` + +- HostEurope server at `92.205.130.254` +- older, mixed-purpose, still actively used +- retains current Gitea fallback and other legacy or transitional runtime + realities +- not yet fully integrated into the newer operating model + +### operator workstation + +- edge/operator compute, not the same kind of substrate as the servers +- hosts operator tools, local keys, bridges, kubeconfig usage, and attended + control-plane work +- likely to become a class of substrates rather than a forever-singleton machine + +## Decision + +The first-wave reef rollout is: + +1. `reef-railiance01` +2. `reef-coulombcore` +3. `reef-ops-workstations` + +Do **not** create `reef-workstation` as a singleton first-wave repo. + +## Why These Three + +### `reef-railiance01` + +This should be the first canonical reef. + +Why: + +- it is already the clearest purpose-bound substrate +- it is the default home for new Kubernetes-oriented Railiance workloads +- it is the likely seed of the future Railiance home reef +- its lifecycle, access path, and workload-placement decisions are already + distinct enough to justify a dedicated reef + +Primary rail stance: + +- primary rail: `rail-kubernetes` +- temporary multi-rail reality is acceptable here during early growth +- later `rail-knative` may coexist on this reef if that is the most pragmatic + path for early workloads such as `qonto-assistent` +- if criticality or security pressure grows, reassess whether a broader grouped + home reef or a rail-specific separation is required + +### `reef-coulombcore` + +This should exist, but explicitly as a transitional reef. + +Why: + +- COULOMBCORE is still a real operational boundary +- it has its own access path, operational evidence, fallback responsibilities, + and recovery decisions +- it is exactly the kind of substrate that should be described honestly even if + its long-term role is not yet clean + +Interpretation: + +- treat it as a mixed-purpose, legacy, or transition reef +- allow multi-rail and compatibility realities here without pretending they are + the preferred long-term production pattern +- use the reef to make drain, cleanup, fallback, and migration decisions visible + +Do not force a permanent taxonomy label such as "associate", "sidecar", or +"comet" yet. Those labels may become useful later, but the operational pattern +is not stable enough to canonize. + +### `reef-ops-workstations` + +Use a grouped reef for operator workstations. + +Why: + +- the workstation role is clearly a different substrate class from the servers +- the machine count is likely to grow or vary over time +- one repo per laptop would create exactly the duplication the reef model is + supposed to prevent + +Interpretation: + +- treat current workstation reality as the first member of an operator/edge + compute reef class +- keep machine-specific details inside the reef topology, not in separate repos + +## Singleton Versus Grouped Rule Applied + +Applying the reef rules to the current hosts yields: + +- `RAILIANCE01`: singleton reef now, because the machine itself is the current + durable substrate boundary +- `COULOMBCORE`: singleton reef now, because it remains an independent + operational and fallback boundary +- workstation: grouped reef, because the substrate concept is "operator edge + compute" rather than one permanently special laptop + +If Railiance01 later becomes one node in a clearly unified multi-node home +substrate with shared lifecycle and placement policy, reassess whether the +right target becomes a grouped reef such as `reef-railiance-home`. + +Until then, `reef-railiance01` is the cleaner decision. + +## `railiance-hosts` Versus `railiance-infra` + +Current reality: + +- `railiance-hosts` and `railiance-infra` are functionally duplicate S1 repos +- both describe the same S1 provisioning and baseline responsibility +- both contain the same authoritative-looking server inventory path +- Fabric onboarding already uses `railiance-infra` + +Decision: + +- `railiance-infra` is the canonical S1 ownership repo going forward +- `railiance-hosts` should be treated as a predecessor or migration duplicate, + not as the long-term authority for new architecture work + +What this means: + +- new framework architecture should anchor on `railiance-infra` +- reef introduction should not preserve the `hosts` naming line as a second S1 + authority +- later cleanup should either retire `railiance-hosts` or reduce it to an + explicit compatibility/archive role + +## Practical Rollout Sequence + +The reef rollout should happen in this order: + +1. create `reef-railiance01` as the first canonical home reef seed +2. create `reef-coulombcore` as the transitional legacy/fallback reef +3. create `reef-ops-workstations` as the grouped operator-edge reef +4. document `railiance-infra` as canonical S1 and plan the `railiance-hosts` + retirement or freeze direction + +## Risks To Watch + +- If `reef-coulombcore` is described as if it were the preferred long-term + production substrate, the reef model will normalize transitional mess instead + of making it visible. +- If `reef-workstation` is created first, the framework will drift toward + one-repo-per-machine duplication. +- If `railiance-hosts` and `railiance-infra` remain equally canonical, reef + ownership will rest on an unstable S1 base. + +## Outcome + +Railiance now has a concrete first reef rollout: + +- `reef-railiance01` as the primary home-reef seed +- `reef-coulombcore` as the transitional legacy/fallback reef +- `reef-ops-workstations` as the grouped operator-edge reef + +That is enough to move from reef theory into practical repo planning. diff --git a/docs/reef-substrate-model.md b/docs/reef-substrate-model.md new file mode 100644 index 0000000..f1e0a3e --- /dev/null +++ b/docs/reef-substrate-model.md @@ -0,0 +1,262 @@ +# Reef Substrate Model + +Date: 2026-07-25 + +## Definition + +A `reef-*` repo is the conceptual home for one durable Railiance substrate +boundary. + +A reef is the place where: + +- infrastructure becomes a named operational reality, +- rails are installed or made available, +- managed workloads are bound, +- and operators interact with a concrete environment. + +More concretely, a reef represents **compute resources organized for a defined +purpose**. + +The substrate may be: + +- a single named server, +- a cluster, +- a workstation, +- an edge site, +- a lab substrate, +- or a small fleet treated as one unit. + +The important point is not the shape of the hardware. The important point is +that the compute resources form one recognizable operational boundary. + +## Why `reef-*` Instead Of `host-*` + +`host-*` is too narrow for the intended concept. + +Railiance substrates are not always just hosts. They may also be: + +- operator workstations, +- Kubernetes substrates, +- serverless-capable execution surfaces, +- grouped node fleets, +- or mixed environments with both machines and control surfaces. + +`reef-*` is useful because it names the substrate reality that rails attach to, +not merely the hardware object underneath it. + +## Core Responsibility Of A Reef + +A reef repo should answer: + +- What is this substrate called? +- What components belong to it? +- What access paths and operator assumptions apply? +- Which rails exist here? +- Which `rapp`s are allowed or deployed here? +- Which overlays, exceptions, and evidence are specific to this substrate? + +It should also make the substrate purpose explicit, so the existence of the +reef is justified by its role rather than by a hostname alone. + +It is therefore an environment or substrate boundary repo, not a generic +infrastructure logic repo. + +## What A Reef Owns + +A reef repo may own: + +- substrate identity and metadata +- topology and membership description +- rail bindings for this substrate +- `rapp` bindings for this substrate +- substrate-specific overlays and values +- substrate-specific runbooks +- substrate-specific evidence and readiness notes +- access-path descriptions such as bridges, kubeconfig routes, or workstation + assumptions + +## What A Reef Does Not Own + +A reef repo should not become the place for: + +- generic OS provisioning logic that belongs in `railiance-infra` +- generic cluster runtime logic that belongs in `railiance-cluster` +- generic platform-service logic that belongs in `railiance-platform` +- generic workload packaging that belongs in a `rapp-*` repo +- generic rail semantics that belong in a `rail-*` repo + +Reefs compose those concerns into a concrete substrate. They do not replace +their owning repos. + +## Granularity Rules + +The main risk with reefs is repo explosion through near-duplicate per-machine +repos. The default rules below are intended to prevent that. + +### Rule 1: One Reef Per Substrate Boundary, Not Per Node By Default + +If multiple machines form one operational substrate with the same lifecycle, +access path, and overlays, prefer one reef. + +Example: + +- Prefer `reef-ops-workstations` over one repo per laptop if they are managed as + one operator substrate class. + +### Rule 2: A Single Machine Gets Its Own Reef Only When It Is The Boundary + +A single named machine can justify its own reef when it is itself a durable +substrate boundary. + +This is reasonable when the machine has: + +- unique operational identity, +- unique overlays or access paths, +- unique binding decisions, +- or independent migration and recovery decisions. + +### Rule 3: Group Fungible Fleets + +Do not create one reef per fungible worker, node, or ephemeral instance. + +Represent those inside one reef's topology instead. + +### Rule 4: Prefer Stable Operational Names + +A reef name should follow the durable substrate identity used by operators. + +Good examples: + +- `reef-coulombcore` +- `reef-railiance01` +- `reef-workstation` +- `reef-ops-workstations` + +Avoid names tied only to transient VM ids, cloud instance ids, or incidental +hardware details. + +### Rule 5: Allow Multi-Rail Reefs Early, Prefer Clearer Separation Later + +It is acceptable for one reef to host multiple rails when the substrate is +experimental, preproduction, prototyping, or otherwise intentionally mixed. + +For production-grade, enterprise-grade, or premium-security situations, the +better default is clearer separation by substrate purpose and a more explicit +primary rail per reef unless there is a reviewed reason to mix rails. + +This is guidance, not a hard prohibition. The point is to keep the substrate +model operationally legible as criticality increases. + +### Rule 6: Do Not Canonize Transitional Substrate Labels Too Early + +Railiance may observe loosely planned or historically accumulated compute +resources that are still in use but do not yet fit a clean substrate class. + +Those realities should be described plainly in architecture notes or reef-local +documents, but the taxonomy should avoid locking in catchy names before the +operational pattern is mature enough to deserve a stable term. + +## Guidance For Current Railiance Substrates + +### `COULOMBCORE` + +`reef-coulombcore` is reasonable if COULOMBCORE remains a durable singleton +substrate with its own: + +- access paths, +- operational evidence, +- rail availability, +- and workload binding decisions. + +It may also serve as the temporary home for older or transitional workloads +that have not yet been integrated into newer operating patterns. + +What should not be decided too early is a permanent taxonomy term for that +kind of substrate. Terms such as "associate", "sidecar", or "comet" may be +useful exploration language, but they should stay provisional until the pattern +repeats and earns a stable place in the framework vocabulary. + +### `RAILIANCE01` + +`reef-railiance01` is reasonable if Railiance01 is separately managed, migrated, +or recovered, rather than being just another fungible node in a larger +substrate. + +At the current maturity level, it is acceptable for `reef-railiance01` to host +`rail-kubernetes` and later also `rail-knative` if that is the most pragmatic +way to support early workloads. + +If that substrate becomes production-critical or security-sensitive, reassess +whether a clearer reef separation is warranted. + +### `WORKSTATION` + +If there is effectively one operator workstation with unique responsibility, +`reef-workstation` is acceptable. + +If Railiance expects multiple equivalent operator machines, prefer a grouped +reef such as `reef-ops-workstations` and model individual machines inside that +repo instead of multiplying repos. + +This class of reef is best understood as edge or operator compute, not as part +of the same substrate category as a home server reef. + +## Suggested Reef Repo Layout + +The exact layout can evolve, but a reef repo should have an obvious substrate +home structure. + +```text +reef-/ + README.md + INTENT.md + SCOPE.md + substrate/ + identity.yaml + topology.yaml + bindings/ + rails.yaml + rapps.yaml + overlays/ + runbooks/ + evidence/ +``` + +Suggested file responsibilities: + +- `substrate/identity.yaml`: substrate id, type, owner, lifecycle, criticality +- `substrate/topology.yaml`: members, providers, network zones, access surfaces +- `bindings/rails.yaml`: rails available on this substrate +- `bindings/rapps.yaml`: `rapp`s bound or approved for this substrate +- `overlays/`: substrate-specific values or adapter overlays +- `runbooks/`: substrate-local operations and recovery +- `evidence/`: substrate readiness, migration, or recovery evidence + +## Relationship To Railiance Fabric + +Reefs should become first-class graph objects in `railiance-fabric`. + +At minimum, Fabric should eventually be able to answer: + +- Which reefs provide `rail-kubernetes`? +- Which reefs bind `rapp-openbao`? +- Which reefs are production-critical? +- Which rails are available on `reef-coulombcore`? +- Which `rapp`s depend on a given reef? + +Until Fabric gains first-class reef vocabulary, reef repos should still use +clear file-backed declarations so later ingestion is straightforward. + +## Recommended Decision + +Adopt `reef-*` as the substrate-boundary prefix for Railiance. + +Use it carefully: + +- yes for real substrate boundaries, +- no for arbitrary one-repo-per-machine duplication, +- and yes for grouped substrate classes when that better matches operational + reality. + +Treat a reef as purpose-bound compute first. The exact machine count is +secondary. diff --git a/docs/repository-axes.md b/docs/repository-axes.md new file mode 100644 index 0000000..b1503e4 --- /dev/null +++ b/docs/repository-axes.md @@ -0,0 +1,254 @@ +# Repository Axes In Railiance + +Date: 2026-07-25 + +## Purpose + +Railiance needs more than one way to classify repositories. + +The existing stack already expresses ownership and responsibility well, but it +does not yet cleanly express: + +- how workloads are executed on different operations architectures, +- how a managed workload package is represented as its own repo, +- and how a concrete substrate or deployment reality is represented. + +This document defines the canonical repository axes for Railiance. + +## Current Architectural Stance + +The taxonomy is intentionally broader than the current implementation wave. + +For the current phase of Railiance: + +- `rail-kubernetes` is the default and first-class base rail for platform + services and managed applications. +- Additional rails should be introduced only when a concrete workload has a + sound reason to run better on a different execution architecture. +- `rail-knative` is the first expected follow-on rail, driven by the need to + run `qonto-assistent`, but it should follow the `rail-kubernetes` boundary + cleanup rather than bypass it. + +This means the repo model is intentionally ahead of the repo count. + +## The Four Repo Families + +| Prefix | Axis | Unit | Primary question answered | +| --- | --- | --- | --- | +| `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 being packaged and operated? | +| `reef-*` | substrate boundary | one durable substrate reality | where does this run and what is bound there? | + +These families are complementary, not competing. + +## 1. `railiance-*`: Responsibility Repos + +`railiance-*` repos are the long-lived architectural homes for major +responsibility areas. + +Examples: + +- `railiance-infra` +- `railiance-cluster` +- `railiance-platform` +- `railiance-enablement` +- `railiance-apps` +- `railiance-forge` +- `railiance-fabric` +- `railiance-master` + +They answer questions such as: + +- Which layer owns this concern? +- Where do the shared rules, runbooks, and contracts live? +- Which team or operator domain is responsible for correctness? + +They should not be multiplied per host, per workload, or per execution mode. + +## 2. `rail-*`: Execution-Contract Repos + +`rail-*` repos define how Railiance-managed workloads run on a specific +operations architecture. + +Examples: + +- `rail-kubernetes` +- `rail-knative` +- `rail-keda` +- `rail-fission` +- `rail-nuclio` + +A rail owns the execution semantics for workloads on that architecture: + +- packaging expectations +- deployment adapters +- autoscaling and traffic behavior +- health and observability contract +- promotion and rollback behavior +- rail-specific templates and compatibility rules + +A rail is not the workload itself and not the substrate it runs on. + +In the current Railiance model, `rail-kubernetes` is the default base rail. +Other rails should be introduced only when their runtime semantics justify a +distinct lifecycle, contract, or operator model. + +That makes the first question for a new rail: + +- does this workload truly need a different rail, +- or does it only need an adapter or profile on the current Kubernetes path? + +## 3. `rapp-*`: Managed Workload Package Repos + +`rapp-*` repos represent Railiance-managed workloads as first-class packages. + +Examples: + +- `rapp-openbao` +- `rapp-forgejo` +- `rapp-vergabe-teilnahme` + +A `rapp` may wrap: + +- an upstream third-party product, +- an internal service, +- a user-facing application, +- or a platform service operated as a workload. + +Its purpose is to provide the scaffolding needed to run that workload as a +fully managed component in the Railiance and Net Kingdom operating context, +including the Helix Forge software-factory environment that produces and runs +parts of that ecosystem. + +A `rapp` owns: + +- the Railiance packaging of the workload +- rail compatibility declarations +- workload-specific health checks and smoke checks +- workload-specific rollout and rollback expectations +- secret references, dependency declarations, and data handoff expectations + +A `rapp` does not replace the responsibility repo that owns the broader domain. +It is explicitly about managed wrapping, not ownership. + +For example: + +- `railiance-platform` may own why OpenBao exists as an S3 platform capability +- `rapp-openbao` may own how OpenBao is packaged and operated as a managed workload + +## 4. `reef-*`: Substrate-Boundary Repos + +`reef-*` repos represent concrete substrate realities where rails and `rapp`s +are bound. + +Examples: + +- `reef-coulombcore` +- `reef-railiance01` +- `reef-workstation` +- `reef-ops-workstations` + +A reef answers questions such as: + +- What is this substrate? +- Which hosts, clusters, namespaces, or operator machines compose it? +- Which rails are installed or allowed here? +- Which `rapp`s are bound to it? +- Which access paths, overlays, and local runbooks apply here? + +A reef does not replace `railiance-infra`, `railiance-cluster`, or +`railiance-platform`. It composes them into a named operational reality. + +In practice, a reef represents compute resources organized for a defined +purpose. + +One reef may host multiple rails in early-stage, experimental, prototyping, or +preproduction situations. For production-grade or premium-security use, the +better default is clearer substrate separation and an explicit primary rail per +reef unless a mixed-rail design is deliberately justified. + +## How The Axes Compose + +The same deployed reality may appear across all four axes for different reasons. + +Example: OpenBao on COULOMBCORE + +- `railiance-platform` owns the platform-service responsibility and policy +- `rail-kubernetes` defines the Kubernetes execution contract +- `rapp-openbao` defines the managed workload package +- `reef-coulombcore` records that this substrate offers that rail and binds that + `rapp` + +This separation reduces confusion between: + +- ownership +- execution mode +- workload identity +- deployment location + +## Creation Rules + +Use the following default rules. + +### Create or extend a `railiance-*` repo when: + +- the concern is a stable responsibility area, +- multiple workloads share the same owner and policy boundary, +- or the repo must remain the canonical home for a layer or cross-cutting + capability. + +### Create a `rail-*` repo when: + +- a workload execution architecture has distinct runtime semantics, +- workloads need architecture-specific templates or promotion behavior, +- or the current `railiance-cluster` contract would become too Kubernetes-only. + +Default bias: + +- first stabilize `rail-kubernetes` +- then add another rail only when a concrete workload needs it + +### Create a `rapp-*` repo when: + +- a workload should be managed as a first-class package, +- the workload has its own compatibility, rollout, or recovery contract, +- or wrapping logic should be kept separate from both the upstream source and + the generic ownership repo. + +Do not create a `rapp` merely to duplicate a responsibility home that already +belongs in a `railiance-*` repo. + +### Create a `reef-*` repo when: + +- there is a durable substrate boundary with its own lifecycle, +- rails and `rapp`s need to be bound to a named operational reality, +- substrate-specific overlays or evidence must be tracked, +- or operators need a source-controlled home for that environment. + +Do not create a reef only because a single machine happens to exist. The +substrate needs a durable purpose. + +## Migration Direction From The Current Repo Set + +The current Railiance repos already provide the ownership axis. + +The likely next architecture moves are: + +1. Move Kubernetes-specific workload execution contracts out of + `railiance-cluster` into `rail-kubernetes`. +2. Split first-class workload wrappers out of `railiance-apps`, + `railiance-platform`, and `railiance-forge` into `rapp-*` repos where the + workload deserves an independent lifecycle. +3. Introduce `reef-*` repos only for real substrate boundaries, not as a + default per-machine pattern. +4. Extend `railiance-fabric` so rails, `rapp`s, and reefs become first-class + graph objects rather than implicit naming conventions. + +## Open Discipline + +Railiance should resist naming every observed pattern too early. + +This especially applies to loosely associated or transitional compute +resources. Terms for such substrates should stay descriptive until there is a +stable operational pattern worth canonizing in the taxonomy. diff --git a/history/260724-InitialExplorationOfOperationModels.md b/history/260724-InitialExplorationOfOperationModels.md new file mode 100644 index 0000000..14580de --- /dev/null +++ b/history/260724-InitialExplorationOfOperationModels.md @@ -0,0 +1,397 @@ +Exploration of railiance modes to operate managed workloads +=========================================================== +--worsch, 24.7.26 r1 + +# Intro + +We need to consistently run workloads and there are tradeoffs depending on which operations architecture aka "rail" one uses for a specific workload. +This is an exploration how we can do that, with knative as the first example. + +This is about how and which rails might be relevant. + + +# Knative in one sentence + +**Knative adds a serverless application platform on top of Kubernetes.** Instead of developers managing `Deployment`, `Service`, autoscaling, ingress, revisions, and traffic splitting separately, they deploy a Knative service or function and let Knative construct and operate those resources. + +Knative is now a **CNCF Graduated project** and consists of three related parts: + +* **Knative Serving** — request-driven container deployment, revisions, traffic routing, autoscaling, and scale-to-zero. +* **Knative Eventing** — CloudEvents-based routing from sources through brokers and triggers to event consumers. +* **Knative Functions** — a developer-oriented function framework built on Serving and Eventing. ([CNCF][1]) + +## Conceptual architecture + +```text +Developer / GitOps / CI + │ + ▼ + Knative Service + │ + Configuration + │ + immutable Revisions + │ + Route + │ + Gateway / Ingress + │ + ┌───┴─────────────────┐ + │ │ +Activator Running revision +cold-start path │ + │ queue-proxy + └───────────────────────│ + ▼ + application container + + +Event producer + │ + Source + │ + Broker / Channel + │ + Trigger filter + │ + ▼ + Sink: Knative Service, Kubernetes Service, etc. +``` + +Each change creates an immutable **Revision**, and traffic can be distributed between revisions for canary, blue-green, or rollback scenarios. When a service is at zero replicas, the Activator can hold incoming requests while the autoscaler starts a revision. Requests reaching an active revision normally pass through Knative’s `queue-proxy` sidecar before reaching the application container. ([knative.dev][2]) + +--- + +# What Knative changes in your infrastructure + +## 1. Kubernetes becomes an application platform + +Without Knative, your application platform typically exposes: + +```text +Deployment + Service + Gateway/Ingress + HPA + rollout tooling +``` + +With Knative, the primary developer abstraction becomes: + +```text +Knative Service + optional Eventing resources +``` + +This is a meaningful architectural improvement when you want HelixForge-style repositories to publish applications through a consistent platform contract. It is less attractive when infrastructure teams want applications to remain completely explicit and close to native Kubernetes resources. + +The benefit is **platform standardization**. The cost is that Knative becomes another reconciliation layer whose behaviour must be understood during incidents. + +## 2. The network architecture changes + +Knative Serving needs a compatible networking layer. Current installation options include Kourier, Contour, Istio, and a Gateway API integration. The Knative project currently tests Gateway API implementations based on Istio, Contour, and Envoy Gateway. ([knative.dev][3]) + +This has practical consequences: + +* Your existing ingress controller might not be reusable. +* Knative may introduce a second gateway or service-mesh data plane. +* DNS and wildcard domains become part of the platform contract. +* External TLS, internal routing, Activator routing, and ordinary Kubernetes service routing need to be observed separately. + +For a k3s installation using its typical Traefik setup, for example, you should expect either an additional supported Knative gateway or a deliberate migration to a supported Gateway API implementation. That conclusion follows from the supported and tested networking options rather than from a general inability of Traefik to route HTTP traffic. + +## 3. Autoscaling becomes request-aware + +Knative’s default KPA autoscaler can scale based on request concurrency and supports scale-to-zero. The ordinary HPA option supports CPU-based scaling but does not provide Knative’s scale-to-zero behaviour. ([knative.dev][4]) + +That works particularly well for: + +* Bursty APIs. +* Webhook receivers. +* Infrequently used tenant-specific services. +* Preview environments. +* Internal tools with long idle periods. +* Lightweight event handlers. + +It is less suitable for services requiring: + +* Predictable sub-second latency at all times. +* Persistent in-memory state. +* Sticky sessions. +* Long-lived connections that cannot tolerate revision replacement. +* Large runtimes or models with expensive initialization. + +Scale-to-zero reduces idle consumption, but converts part of your capacity problem into a **cold-start engineering problem**. Container pull time, application initialization, secrets retrieval, database connection setup, readiness checks, and node capacity all become part of request latency. + +## 4. Every application pod gains platform behaviour + +Knative normally adds a `queue-proxy` sidecar to revision pods. The Activator may additionally enter the request path during scale-from-zero or capacity transitions. ([knative.dev][5]) + +This affects: + +* Pod resource requests and limits. +* Service-mesh sidecar combinations. +* Network policy. +* Request tracing. +* Graceful termination. +* Per-request metrics. +* Failure analysis. +* Capacity calculations. + +For a large number of small services, platform sidecars and control-plane objects can become a significant portion of total resource consumption. + +## 5. The control plane becomes larger + +A basic Serving installation introduces CRDs, controllers, admission webhooks, an autoscaler, Activator components, networking integration, and configuration objects. Eventing adds its own controllers, brokers, dispatchers, sources, channels, and potentially Kafka infrastructure. + +The official single-node installation guidance currently begins at 6 CPUs, 6 GB RAM, and 30 GB disk, although real production sizing depends heavily on the number of revisions, services, requests, and Eventing resources. ([knative.dev][3]) + +Knative also follows a relatively fast Kubernetes compatibility schedule. As of July 24, 2026, the supported Knative release lines are 1.21 and 1.22, requiring Kubernetes 1.33 and 1.34 respectively; Knative 1.23 is scheduled for July 28, 2026. ([GitHub][6]) + +That means Knative can influence when your k3s or Kubernetes platform must be upgraded. + +## 6. Observability becomes more important + +Scale-to-zero means pods and their local logs disappear regularly. Knative explicitly recommends centralized log collection because Serving deletes pods as they are no longer needed. Its control plane and request path expose metrics and support OpenTelemetry-based integration. ([knative.dev][7]) + +Your OpsCatalog should distinguish at least: + +```text +Gateway → Knative Route → Activator → queue-proxy → application +``` + +Otherwise, an apparent application outage may really be: + +* A gateway routing problem. +* A Knative Route or Revision condition. +* Failed scale-from-zero. +* Unschedulable pods. +* Image pull delay. +* A queue-proxy readiness issue. +* Application initialization failure. + +## 7. Knative is not a hard multitenancy boundary + +Knative’s own threat model describes a **Namespace-as-a-Service** model for teams within a common organization sharing a cluster, control plane, and nodes. ([knative.dev][8]) + +That aligns well with trusted internal platform teams. It does not by itself establish strong isolation between mutually hostile customers. + +For your multi-vendor and government/corporate security ambitions, Knative should therefore sit inside a broader tenancy architecture involving: + +* RBAC and admission policy. +* Resource quotas and limit ranges. +* Default-deny network policy. +* Workload identity. +* Secret isolation. +* Separate node pools where appropriate. +* Separate clusters or control planes for high-assurance tenant boundaries. + +Kubernetes itself distinguishes trusted multi-team sharing from multi-customer tenancy and requires additional controls around resource and security isolation. ([Kubernetes][9]) + +There is also an important current security qualification: Knative documents its cluster-local and system-internal TLS features as experimental, and states that not all control-plane traffic is encrypted. ([knative.dev][10]) + +--- + +# SWOT assessment + +| | Positive | Negative | +| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Internal** | **Strengths:** Strong Kubernetes-native serverless abstraction; container rather than language lock-in; scale-to-zero; immutable revisions; built-in traffic splitting; CloudEvents integration; pluggable networking; compatible with GitOps; mature CNCF governance. | **Weaknesses:** Significant CRD and controller footprint; additional network data path; cold-start latency; queue-proxy overhead; more difficult troubleshooting; assumes largely stateless and fungible instances; Kubernetes-version coupling; Eventing can add another messaging abstraction. | +| **External** | **Opportunities:** A standard application-runtime surface for HelixForge; tenant- or project-specific services that consume no resources while idle; disposable environments; webhook and adapter execution; KServe-based AI inference; consistent rollout and rollback; a common event vocabulary across projects. | **Threats:** Duplication with Gateway API, service mesh, Argo Rollouts, KEDA, Dapr, Temporal, and existing brokers; platform lock-in at the Kubernetes-CRD level; accidental use for stateful or latency-critical workloads; insufficient isolation for hostile tenants; uncontrolled creation of revisions and services; upgrade burden becoming larger than saved application effort. | + +## Overall SWOT verdict + +Knative’s greatest strength is not merely scale-to-zero. It is the creation of a **coherent application execution contract**. + +Its greatest weakness is also that contract: once adopted broadly, networking, rollout, autoscaling, observability, security, and deployment semantics become tied to Knative. + +--- + +# Alternative open-source approaches + +There is no universally “more advanced” alternative. Several tools are more advanced for a **narrower problem**. + +## KEDA plus ordinary Kubernetes workloads + +KEDA is the strongest alternative when you primarily want event-driven scaling rather than a serverless application platform. + +It works alongside the Kubernetes HPA, can scale deployments and other resources to zero based on queues, databases, APIs, or other external metrics, and can create Kubernetes Jobs for event-driven batch processing. KEDA is CNCF Graduated. ([KEDA][11]) + +**Prefer KEDA when:** + +* You want to retain standard `Deployment`, `StatefulSet`, and `Job` objects. +* Workers pull from Kafka, RabbitMQ, NATS, Redis, or another queue. +* You do not need revision-aware HTTP routing. +* You want incremental, low-impact adoption. +* Different workloads require different scaling models. + +KEDA’s HTTP add-on remains beta, so Knative is currently the more established choice for transparent HTTP scale-from-zero routing. ([KEDA][12]) + +**For your infrastructure, KEDA is likely the better default autoscaling component, with Knative reserved for services that specifically benefit from request-driven scale-to-zero and revision routing.** + +## Fission + +Fission is a function-oriented serverless platform. Developers can submit source code against language environments without constructing container images themselves. It maintains warm runtime pools and emphasizes fast function startup and developer productivity. The project remains Apache-2.0 licensed and released version 1.27.0 on June 22, 2026. ([Fission][13]) + +**Prefer Fission when:** + +* The primary product is a FaaS developer experience. +* Developers should submit small Python, JavaScript, Go, or similar functions. +* Building and managing OCI images should be hidden. +* Warm runtime pools are acceptable. +* Functions are the primary unit, rather than arbitrary containerized applications. + +Fission is more specialized and potentially more convenient for function developers, but Knative is the broader and more composable application platform. + +## Nuclio + +Nuclio concentrates on high-performance event and data processing, including CPU- and GPU-intensive execution and integration with streaming and data-science environments. It is Apache-2.0 licensed and released version 1.17.1 on July 7, 2026. ([GitHub][14]) + +**Prefer Nuclio when:** + +* Functions consume high-volume streams. +* Processing is data-, I/O-, or compute-intensive. +* GPU execution matters. +* Jupyter, Kubeflow, or data-science integration is central. +* Function processor performance is more important than a generic application-platform abstraction. + +Nuclio may be “more advanced” for high-performance data functions, but not for general microservice platform governance. + +## Dapr + +Dapr is not a Knative replacement at the deployment level. It is a distributed application runtime exposing building blocks for service invocation, pub/sub, state, actors, jobs, secrets, configuration, and workflows. It normally adds a Dapr runtime process or sidecar to each participating service and is CNCF Graduated. ([Dapr Docs][15]) + +**Prefer or add Dapr when:** + +* Applications need portable infrastructure APIs. +* You want to swap brokers or state stores without rewriting application integration. +* Service-to-service resiliency is more important than scale-to-zero. +* Actors, pub/sub, or application-level workflows are required. + +Knative answers **“how is this container deployed and activated?”** + +Dapr answers **“how does this distributed application use infrastructure capabilities?”** + +They can be combined, but combining their sidecars and control planes should be justified by concrete use cases. + +## Temporal + +Temporal is paramount when events initiate **durable, stateful, multi-step coordination**. + +A Knative event handler can receive an event and execute code, but it does not replace durable workflow state, replay, long-lived waiting, activity retries, compensation, or workflow versioning. Temporal provides those capabilities and supports self-hosted production operation. ([Temporal Docs][16]) + +Given your existing Temporal-centered event-backbone direction, I would preserve this separation: + +```text +Knative Serving → bursty request-driven execution +KEDA → queue- and metric-driven worker scaling +Temporal → durable coordination and control loops +Kafka/NATS/etc. → durable event transport +``` + +Knative Eventing can then act as a CloudEvents routing and adaptation surface rather than becoming the authoritative workflow or event-history system. + +## SpinKube or wasmCloud + +SpinKube and wasmCloud represent a more radical WebAssembly-based architecture. + +SpinKube runs Spin-based Wasm applications through Kubernetes and is currently a CNCF Sandbox project. wasmCloud provides a distributed Wasm component platform spanning Kubernetes, cloud, datacenter, and edge, and is a CNCF Incubating project. ([SpinKube][17]) + +**Prefer evaluating Wasm when:** + +* Very high workload density is important. +* Edge or intermittently connected environments matter. +* Applications are small, portable components. +* Fast startup and low runtime overhead outweigh ecosystem maturity. +* You want stronger capability-oriented sandboxing for extension code. +* Polyglot components must run consistently across Kubernetes and non-Kubernetes environments. + +This is potentially more forward-looking than Knative, but it imposes a more substantial programming and runtime model change. I would currently treat it as an experimental runtime class, not the default foundation for all services. + +## KServe + +For model inference, KServe is more appropriate than building a generic Knative function platform yourself. KServe’s default deployment mode currently uses Knative for request-driven serverless inference; its Standard mode can optionally use KEDA, although Standard mode does not currently support HTTP scale-from-zero. ([kserve.github.io][18]) + +Thus, Knative may become an **underlying dependency of an AI inference platform**, rather than the user-facing AI platform itself. + +## OpenFaaS caveat + +OpenFaaS remains technically capable, but it is no longer a straightforward fully open-source production alternative for a business platform. Its Community Edition is limited to personal exploration and short commercial proofs of concept; production features and commercial use require a paid edition, and scale-from-zero is not included in CE. ([openfaas.com][19]) + +That licensing model appears poorly aligned with your preference for sovereign, commercially usable open-source infrastructure. + +--- + +# When a different architecture should take precedence + +| Dominant requirement | Prefer | +| ---------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| Stateless HTTP services with scale-to-zero and traffic splitting | **Knative Serving** | +| Queue workers and event-driven batch jobs | **KEDA + Deployments/Jobs** | +| Source-code-oriented FaaS developer experience | **Fission** | +| High-performance stream, data, CPU, or GPU functions | **Nuclio** | +| Portable distributed-application APIs | **Dapr** | +| Durable processes, retries, waiting, compensation, control loops | **Temporal** | +| ML model serving | **KServe**, possibly backed by Knative | +| Edge and high-density component execution | **wasmCloud or SpinKube** | +| Stateful, latency-critical, always-on services | **Standard Kubernetes Deployments/StatefulSets** | +| Mutually untrusted customers or high-assurance isolation | **Separate clusters/control planes**, possibly with Knative inside each boundary | + +--- + +# Recommendation for your platform + +I would introduce Knative as an **optional execution capability**, not as the universal deployment model. + +A sensible initial architecture would be: + +```text + Platform deployment classes + │ + ┌──────────────────────┼──────────────────────┐ + │ │ │ +Standard Kubernetes Knative Serving KEDA workers +long-lived/stateful bursty HTTP/events queues and jobs + │ │ │ + └──────────────────────┴──────────────────────┘ + │ + Temporal coordination + │ + Kafka/NATS/RabbitMQ events +``` + +Start with **Knative Serving only**. Reuse a supported Gateway API implementation where possible, keep Eventing out of the first deployment, and evaluate three representative workloads: + +1. A bursty webhook or adapter service. +2. An infrequently used internal API. +3. A tenant- or project-specific disposable service. + +Measure: + +* Idle control-plane and sidecar consumption. +* Cold-start median and tail latency. +* Time from request to ready revision. +* Behaviour under node exhaustion. +* Revision rollout and rollback. +* Log and trace completeness. +* Network-policy compatibility. +* Upgrade effort. +* Failure isolation between namespaces. + +Add Knative Eventing later only where its Source–Broker–Trigger model demonstrably simplifies CloudEvents routing. For your architecture, **Temporal should remain the durable coordination layer and KEDA the default event-driven scaler**. Knative then becomes a valuable, bounded runtime for stateless, bursty services rather than an additional universal control plane competing with the systems you already intend to establish. + +[1]: https://www.cncf.io/projects/knative/?utm_source=chatgpt.com "Knative | CNCF" +[2]: https://knative.dev/docs/serving/?utm_source=chatgpt.com "Knative Serving" +[3]: https://knative.dev/docs/install/yaml-install/serving/install-serving-with-yaml/?utm_source=chatgpt.com "Install Serving with YAML" +[4]: https://knative.dev/docs/serving/autoscaling/autoscaler-types/?utm_source=chatgpt.com "Supported autoscaler types" +[5]: https://knative.dev/docs/serving/request-flow/?utm_source=chatgpt.com "HTTP Request Flows" +[6]: https://github.com/knative/community/blob/main/mechanics/RELEASE-SCHEDULE.md?utm_source=chatgpt.com "community/mechanics/RELEASE-SCHEDULE.md at main" +[7]: https://knative.dev/docs/serving/observability/logging/collecting-logs/?utm_source=chatgpt.com "Collecting Serving logs" +[8]: https://knative.dev/docs/reference/security/threat-model/?utm_source=chatgpt.com "Threat Model" +[9]: https://kubernetes.io/docs/concepts/security/multi-tenancy/?utm_source=chatgpt.com "Multi-tenancy" +[10]: https://knative.dev/docs/serving/encryption/encryption-overview/?utm_source=chatgpt.com "Serving Encryption Overview" +[11]: https://keda.sh/docs/2.20/concepts/?utm_source=chatgpt.com "KEDA Concepts" +[12]: https://keda.sh/docs/2.20/setupscaler/?utm_source=chatgpt.com "Setup Autoscaling with KEDA" +[13]: https://fission.io/docs/?utm_source=chatgpt.com "Serverless Functions for Kubernetes - Fission" +[14]: https://github.com/nuclio/nuclio/releases?utm_source=chatgpt.com "Releases · nuclio/nuclio" +[15]: https://docs.dapr.io/concepts/overview/?utm_source=chatgpt.com "Overview" +[16]: https://docs.temporal.io/self-hosted-guide?utm_source=chatgpt.com "Self-hosted Temporal Service guide" +[17]: https://www.spinkube.dev/?utm_source=chatgpt.com "SpinKube" +[18]: https://kserve.github.io/website/docs/admin-guide/kubernetes-deployment?utm_source=chatgpt.com "Kubernetes Deployment Installation Guide" +[19]: https://www.openfaas.com/pricing/?utm_source=chatgpt.com "Plans & Pricing" + diff --git a/history/260724-InitialExplorationOfWrapperConcepts.md b/history/260724-InitialExplorationOfWrapperConcepts.md new file mode 100644 index 0000000..5dbbc5b --- /dev/null +++ b/history/260724-InitialExplorationOfWrapperConcepts.md @@ -0,0 +1 @@ +This shall become an exploration about how to wrap apps and services to run them as a railiance managed workloads. diff --git a/workplans/.gitkeep b/workplans/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/workplans/.gitkeep @@ -0,0 +1 @@ + diff --git a/workplans/RAILIANCE-WP-0017-rail-rapp-reef-repo-separation.md b/workplans/RAILIANCE-WP-0017-rail-rapp-reef-repo-separation.md new file mode 100644 index 0000000..e7ea203 --- /dev/null +++ b/workplans/RAILIANCE-WP-0017-rail-rapp-reef-repo-separation.md @@ -0,0 +1,310 @@ +--- +id: RAILIANCE-WP-0017 +type: workplan +title: "Rail, Rapp, and Reef Repo Separation" +domain: financials +repo: railiance-master +status: finished +owner: codex +topic_slug: railiance +planning_priority: high +planning_order: 17 +created: "2026-07-25" +updated: "2026-07-25" +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" +--- + +# RAILIANCE-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: RAILIANCE-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: RAILIANCE-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: RAILIANCE-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: RAILIANCE-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: RAILIANCE-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-railiance01` +- `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-railiance01`, `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: RAILIANCE-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: RAILIANCE-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. diff --git a/workplans/archived/.gitkeep b/workplans/archived/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/workplans/archived/.gitkeep @@ -0,0 +1 @@ +