diff --git a/README.md b/README.md index 30ed4c8..ac81c8b 100644 --- a/README.md +++ b/README.md @@ -1,60 +1,54 @@ -# Railiance Cluster +# railiance-cluster [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) -Opinionated Infrastructure-as-Code framework for reproducible, self-reliant systems. +S2 cluster runtime home for Railiance: Kubernetes substrate ownership, cluster +operators, kubeconfig delivery, backup/preflight safety rails, and published +cluster facts that downstream workload rails depend on. -Railiance is an opinionated **Infrastructure-as-Code framework** β€” -think *Rails for Ops*: convention over configuration, reproducibility first. +This repo is the Kubernetes substrate owner, not the long-term home for the +generic workload-on-Kubernetes contract. The staged workload lifecycle, +`railiance/app.toml`, and overlay/wrapper scaffolding still live here as a +compatibility layer and are being prepared for extraction to a future +`rail-kubernetes` repo. -This repo (`railiance-cluster`) is the **cluster runtime entry point**: -from two bare Linux servers, a Git repo, and credentials, you can rebuild -a fully automated Kubernetes-based environment. +## Current Boundary ---- +- S2-owned here: k3s bootstrap, Helm and kubeconfig access, cluster-level + backup/preflight, smoke checks, and published substrate expectations. +- Transitional here only: generic Stage 1/2/3 workload lifecycle semantics, + `railiance/app.toml`, canary/promotion CLI commands, and overlay scaffolding. +- Reviewed move map: + [docs/rail-kubernetes-extraction-map.md](docs/rail-kubernetes-extraction-map.md) +- Published substrate profile: + [docs/rail-kubernetes-substrate-profile.md](docs/rail-kubernetes-substrate-profile.md) -## πŸš€ Quick Start +## Quick Start -1. **Clone this repo** +1. Clone this repo. ```bash git clone /railiance-cluster.git cd railiance-cluster ``` +2. Configure Gitea access in `~/.railiance_gitea.conf`. +3. Bootstrap a host with the Ansible playbooks in `ansible/`. +4. Validate the cluster substrate with the documented smoke/preflight targets. -2. **Configure Gitea access** - Edit `~/.railiance_gitea.conf` with your server URL, username, and token. - *(Never commit this file!)* +## Repo Structure -3. **Bootstrap a host** - Run the Ansible playbooks in `ansible/` to set up k3s, Helm, kubectl. +- `ansible/` - S2 bootstrap playbooks +- `helm/` - retained cluster-side helper manifests +- `tests/` - cluster validation and HA smoke checks +- `docs/` - S2 substrate docs plus transitional rail-kubernetes specs +- `tools/` - S2 operations plus compatibility tooling that is being split out +- `workplans/` - repo-local cluster work records -4. **Deploy baseline services** - Use `helm/` charts to roll out essential services (GitOps, monitoring, etc.). +## Key Docs -5. **Validate** - Check the automated tests in `tests/` to confirm infra health. +- [SCOPE.md](SCOPE.md) +- [docs/README.md](docs/README.md) +- [docs/rail-kubernetes-extraction-map.md](docs/rail-kubernetes-extraction-map.md) +- [docs/rail-kubernetes-substrate-profile.md](docs/rail-kubernetes-substrate-profile.md) ---- +## Contributing -## πŸ“‚ Repo Structure - -- `ansible/` β€” Playbooks for provisioning -- `helm/` β€” Opinionated Helm charts -- `k8s/` β€” Kubernetes manifests -- `tests/` β€” Automated validation -- `docs/` β€” Documentation (see [docs/README.md](./docs/README.md)) -- `tools/` β€” Helper scripts (e.g. `create_railiance_repo.sh`) - ---- - -## 🀝 Contributing - -See [docs/CONTRIBUTING.md](./docs/CONTRIBUTING.md). - ---- - -## 🌍 Vision - -Railiance aims for **self-reliant infrastructure**: -automation you can rebuild from scratch, with calmness and clarity. - -> *From bare metal to resilient clusters β€” in one repo.* +See [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md). diff --git a/SCOPE.md b/SCOPE.md index 15d7933..4716c1d 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -8,13 +8,23 @@ ## One-liner -S2 Cluster Runtime layer of the Railiance OAS Stack β€” owns k3s installation, Helm, ingress, CNI, admission controllers, operators, and kubeconfig management. +S2 Cluster Runtime layer of the Railiance OAS Stack - owns k3s installation, +Helm, ingress, CNI, admission controllers, operators, kubeconfig management, +and the substrate facts published to downstream workload rails. --- ## Core Idea -Railiance is structured as five independent repos per OAS Stack layer. This repo is S2. It installs and configures the Kubernetes cluster runtime: k3s, Helm, ingress controller, CNI plugin, cluster addons and operators. S1 (OS) must be converged before S2 can run. S2 explicitly does not own platform services (PostgreSQL, caches) β€” those are S3. +Railiance is structured as five independent repos per OAS Stack layer. This repo +is S2. It installs and configures the Kubernetes cluster runtime: k3s, Helm, +ingress controller, CNI plugin, cluster addons and operators. S1 (OS) must be +converged before S2 can run. S2 explicitly does not own platform services +(PostgreSQL, caches) - those are S3. + +Some generic workload lifecycle docs and commands still live here as a temporary +compatibility layer. That material is transition debt pending extraction to a +future `rail-kubernetes` repo and must not be treated as long-term S2 scope. --- @@ -27,15 +37,17 @@ Railiance is structured as five independent repos per OAS Stack layer. This repo - Cluster addons (cert-manager, etc.) - kubeconfig management and access - Smoke tests to validate cluster health +- Published substrate facts and safety expectations for downstream workload rails --- ## Out of Scope -- OS security hardening, SSH, firewall β†’ railiance-infra (S1) -- Platform services (PostgreSQL HA, Valkey, object storage) β†’ railiance-platform (S3) -- CI/CD and developer tooling β†’ railiance-enablement (S4) -- Application deployments β†’ railiance-apps (S5) +- OS security hardening, SSH, firewall -> railiance-infra (S1) +- Platform services (PostgreSQL HA, Valkey, object storage) -> railiance-platform (S3) +- CI/CD and developer tooling -> railiance-enablement (S4) +- Application deployments -> railiance-apps (S5) +- Generic workload lifecycle semantics, `railiance/app.toml`, and wrapper scaffolding as long-term ownership concerns -> future `rail-kubernetes` / `rapp-*` - No re-configuration of S1 concerns from this repo --- @@ -46,6 +58,7 @@ Railiance is structured as five independent repos per OAS Stack layer. This repo - Installing or updating cluster-level operators and addons - Diagnosing cluster health (smoke tests) - k3s upgrades or kubeconfig rotation +- Defining what the current Kubernetes substrate guarantees to downstream workload rails --- @@ -60,8 +73,8 @@ Railiance is structured as five independent repos per OAS Stack layer. This repo ## Current State - Status: active / stable -- Implementation: k3s baseline, pgpool HA failover fix, age-encrypted backup, kubeconfig delivery, staged promotion lifecycle, and activity-core/llm-connect reconcile gates all finished (RAIL-BS-WP-0002…0006, RAILIANCE-WP-0012…0014) -- Open work: RAIL-BS-WP-0007 ThreePhoenix HA cluster (active, 0/7); RAIL-BS-WP-0008 activity-core WP-0016 deploy (ready); RAIL-BS-WP-0009 admin-sync smoke (ready) +- Implementation: k3s baseline, age-encrypted backup, kubeconfig delivery, and cluster operator/addon management are established; generic workload lifecycle docs/tooling remain here as transition debt pending `rail-kubernetes` extraction +- Open work: RAIL-BS-WP-0007 ThreePhoenix HA cluster (active, 0/7); RAIL-BS-WP-0008 activity-core WP-0016 deploy (ready); RAIL-BS-WP-0009 admin-sync smoke (ready); RAIL-BS-WP-0012 rail-kubernetes extraction (active) - Usage: core Kubernetes runtime for all Railiance deployments; runs on COULOMBCORE (92.205.130.254) - Also deployed at cluster level: cert-manager, ArgoCD, CloudNative PG operator (cnpg), nginx ingress, SSO stack (mfa + sso namespaces via net-kingdom) @@ -69,7 +82,7 @@ Railiance is structured as five independent repos per OAS Stack layer. This repo ## How It Fits -- Upstream dependencies: railiance-infra (S1) β€” OS must be converged and verified +- Upstream dependencies: railiance-infra (S1) - OS must be converged and verified - Downstream consumers: railiance-platform (S3), railiance-enablement (S4), railiance-apps (S5) - Often used with: railiance-platform (next layer to configure after cluster is up) @@ -78,21 +91,21 @@ Railiance is structured as five independent repos per OAS Stack layer. This repo ## Terminology - Preferred terms: OAS Stack Level S2, smoke test, pre-condition chain, boundary rule -- Potentially confusing terms: cluster runtime β‰  platform services; Gitea and databases are NOT S2 concerns +- Potentially confusing terms: cluster runtime != platform services; cluster runtime != generic workload rail; Gitea and databases are not S2 concerns --- ## Related / Overlapping -- `railiance-infra` (S1) β€” must be converged before this layer runs -- `railiance-platform` (S3) β€” consumes the cluster runtime provided by S2 +- `railiance-infra` (S1) - must be converged before this layer runs +- `railiance-platform` (S3) - consumes the cluster runtime provided by S2 --- ## Getting Oriented -- Start with: `CLAUDE.md` (session protocol, remote execution via SSH tunnel), `README.md` -- Key files / directories: `workplans/` (4 active), `.sops.yaml` (secret encryption) +- Start with: `CLAUDE.md`, `README.md` +- Key files / directories: `workplans/`, `.sops.yaml`, `docs/rail-kubernetes-extraction-map.md`, `docs/rail-kubernetes-substrate-profile.md` - Entry points: `Makefile` targets; remote work requires SSH tunnel to State Hub --- @@ -124,4 +137,11 @@ keywords: [backup, restore, age, encryption, k3s, state, helm, kubeconfig, disas ## Notes -Runs on COULOMBCORE (92.205.130.254). State Hub access via ops-bridge reverse tunnel β€” `bridge up state-hub-coulombcore` from the workstation (see ADR-004). Gitea Helm values were migrated to S5 (railiance-apps) in RAIL-HO-WP-0004-T06 β€” boundary violation resolved. +Runs on COULOMBCORE (92.205.130.254). State Hub access via ops-bridge reverse +tunnel - `bridge up state-hub-coulombcore` from the workstation (see ADR-004). +Gitea Helm values were migrated to S5 (railiance-apps) in RAIL-HO-WP-0004-T06 - +boundary violation resolved. + +`bin/railiance` lifecycle subcommands, `railiance/app.toml`, and overlay/wrapper +scaffolding stay in this repo only as a migration bridge. They are not the +steady-state S2 identity. diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index dddf5b1..9db6547 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -13,7 +13,7 @@ | workplan | RAIL-BS-WP-0009 | finished | β€” | workplans/RAIL-BS-WP-0009-activity-core-admin-sync-smoke.md | | workplan | RAIL-BS-WP-0010 | finished | β€” | workplans/RAIL-BS-WP-0010-weekly-legacy-meter-review-rollout.md | | workplan | RAIL-BS-WP-0011 | finished | β€” | workplans/RAIL-BS-WP-0011-legacy-meter-8h-capture-image-reconcile.md | -| workplan | RAIL-BS-WP-0012 | ready | β€” | workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md | +| workplan | RAIL-BS-WP-0012 | active | β€” | workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md | | task | RAIL-BS-WP-0007-T01 | todo | β€” | workplans/RAIL-BS-WP-0007-threephoenix-ha-cluster.md | | task | RAIL-BS-WP-0007-T02 | todo | β€” | workplans/RAIL-BS-WP-0007-threephoenix-ha-cluster.md | | task | RAIL-BS-WP-0007-T03 | todo | β€” | workplans/RAIL-BS-WP-0007-threephoenix-ha-cluster.md | @@ -36,7 +36,7 @@ | task | RAIL-BS-WP-0011-T02 | done | β€” | workplans/RAIL-BS-WP-0011-legacy-meter-8h-capture-image-reconcile.md | | task | RAIL-BS-WP-0011-T03 | done | β€” | workplans/RAIL-BS-WP-0011-legacy-meter-8h-capture-image-reconcile.md | | task | RAIL-BS-WP-0011-T04 | done | β€” | workplans/RAIL-BS-WP-0011-legacy-meter-8h-capture-image-reconcile.md | -| task | RAIL-BS-WP-0012-T01 | todo | β€” | workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md | -| task | RAIL-BS-WP-0012-T02 | todo | β€” | workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md | -| task | RAIL-BS-WP-0012-T03 | todo | β€” | workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md | +| task | RAIL-BS-WP-0012-T01 | done | β€” | workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md | +| task | RAIL-BS-WP-0012-T02 | done | β€” | workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md | +| task | RAIL-BS-WP-0012-T03 | done | β€” | workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md | | task | RAIL-BS-WP-0012-T04 | wait | β€” | workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md | diff --git a/docs/README.md b/docs/README.md index c8fb424..6172bd8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,77 +1,30 @@ -# Railiance Documentation +# railiance-cluster Docs -Welcome to **Railiance** β€” an opinionated framework for Infrastructure-as-Code. -Think of it as *Rails for Ops*: convention over configuration, productivity first, reproducible everywhere. +This directory mixes two kinds of material: ---- +- stable S2 cluster-substrate docs that belong in `railiance-cluster` +- transitional workload-contract docs that are temporarily hosted here until + `rail-kubernetes` exists -## πŸš€ What is Railiance? +Use the sections below to keep those concerns separate. -Railiance is the **self-reliant infrastructure bootstrap** for Coulomb and beyond. -From two bare Linux servers, a Git repo, and valid credentials, you can rebuild a full Kubernetes-based environment with: +## S2 Substrate Docs -- **Automated provisioning** (Ansible, Helm, k3s) -- **Git-driven state** (ArgoCD / Flux) -- **AI-ready automation** with OODA loop (Observe, Orient, Decide, Act) -- **End-to-end reproducibility** β€” no hidden steps, no snowflake servers +- [Operator runbook](operator-runbook.md) +- [Backup and restore](backup-restore.md) +- [Kubeconfig](kubeconfig.md) +- [First host](first_host.md) ---- +## Published Boundary Docs -## 🌱 Core Principles +- [rail-kubernetes extraction map](rail-kubernetes-extraction-map.md) +- [rail-kubernetes substrate profile](rail-kubernetes-substrate-profile.md) -1. **Convention over configuration** - Opinionated defaults remove friction. +## Transitional Workload-Contract Docs -2. **Don’t repeat yourself (DRY)** - Single source of truth in Git, reused everywhere. - -3. **Automated OODA** - - *Observe*: collect telemetry. - - *Orient*: AI interprets state. - - *Decide*: human reviews & authorizes. - - *Act*: automation applies changes. - -4. **Self-Reliance** - Everything can be rebuilt from scratch, with no external dependencies beyond Git + credentials. - -5. **Calm Ops** - Systems should be simple, resilient, and predictable. - ---- - -## πŸ“‚ Repo Layout - -- `ansible/` β€” bootstrap playbooks (OS setup, k3s install, etc.) -- `helm/` β€” Helm charts for services -- `k8s/` β€” raw manifests & overlays -- `tests/` β€” automated validation of infra steps -- `docs/` β€” documentation & contributor guides -- `tools/` β€” helper scripts (e.g. repo bootstrap) - ---- - -## πŸ›  Getting Started - -1. **Clone the repo** - ```bash - git clone /railiance-cluster.git - cd railiance-cluster - -2. **Prepare your config** - Edit ~/.railiance_gitea.conf with your Gitea URL, user, and token. - (Never commit this file!) - -3. **Run bootstrap** - Use the playbooks in ansible/ to turn a bare Ubuntu server into a Kubernetes host. - -4. **Deploy services** - Install baseline services via Helm from the helm/ directory. - -## Incidents - -- [2026-03-10 β€” pgpool CrashLoopBackOff on PostgreSQL HA failover](incidents/2026-03-10-pgpool-missing-secret.md) - -## Operations +These docs describe the generic workload-on-Kubernetes contract. They are still +hosted in this repo for compatibility, but they are targeted for extraction to +future `rail-kubernetes`. - [Deployment lifecycle](deployment-lifecycle.md) - [Railiance app.toml contract](app-toml-contract.md) @@ -81,13 +34,6 @@ From two bare Linux servers, a Git repo, and valid credentials, you can rebuild - [Promote, rollback, and onboarding](promote-rollback-onboarding.md) - [Railiance run command](railiance-run-command.md) -## πŸ‘₯ Contributing +## Incidents -See CONTRIBUTING.md for rules, coding style, and workflow. - -## 🌍 Vision - -Railiance is more than infra scripts: it’s the foundation of self-empowering infrastructure, -where humans and AI agents collaborate to manage systems with trust, clarity, and calmness. - -From bare metal to resilient clusters, in one repo. +- [2026-03-10 - pgpool CrashLoopBackOff on PostgreSQL HA failover](incidents/2026-03-10-pgpool-missing-secret.md) diff --git a/docs/app-toml-contract.md b/docs/app-toml-contract.md index ca7f0c1..cbd2d28 100644 --- a/docs/app-toml-contract.md +++ b/docs/app-toml-contract.md @@ -10,6 +10,11 @@ dependencies, and secret references are described by stable names. Plaintext secrets, bearer tokens, kubeconfigs, and private key material must never appear in `railiance/app.toml`. +Ownership note: this contract is temporarily hosted in `railiance-cluster` +while the wave-1 split prepares a future `rail-kubernetes` repo. Long-term +ownership belongs with the generic workload-on-Kubernetes contract, not with S2 +cluster substrate ownership. + The machine-readable schema lives at `schemas/railiance-app.schema.json`. A minimal example lives at `examples/railiance/app.toml`. diff --git a/docs/deployment-lifecycle.md b/docs/deployment-lifecycle.md index b7bcaad..2dcdf5d 100644 --- a/docs/deployment-lifecycle.md +++ b/docs/deployment-lifecycle.md @@ -9,16 +9,24 @@ stage must leave evidence, every promotion must have a rollback path, and critical workloads require explicit human approval before production traffic is changed. +Ownership note: this specification is temporarily hosted in +`railiance-cluster` during the wave-1 split. Its long-term home is future +`rail-kubernetes`; `railiance-cluster` should retain only substrate +prerequisites and compatibility shims once that repo exists. + ## Scope -This specification is owned by `railiance-cluster` because it defines the -cluster runtime contract for promotion gates, canary validation, production -routing, and rollback expectations. +This specification currently lives beside the cluster substrate because the +compatibility tooling still lives here. Long-term ownership is not S2. Repo boundaries: -- `railiance-cluster` owns the lifecycle semantics, cluster prerequisites, - ingress/routing expectations, and acceptance gates. +- future `rail-kubernetes` owns lifecycle semantics, generic promotion gates, + canary validation, production routing expectations, rollback expectations, + and the generic workload contract. +- `railiance-cluster` owns only the substrate prerequisites published to that + rail: cluster connectivity, namespace behavior, ingress availability, and + operator/runtime expectations. - `railiance-apps` owns workload-specific Helm values, application release definitions, and production workload configuration. - `railiance-platform` owns shared platform services such as databases, @@ -329,4 +337,3 @@ bin/railiance rollback --plan # rollback to previous s The exact command names may change as implementation lands, but the behavior must preserve the stage gates and evidence requirements in this document. - diff --git a/docs/rail-kubernetes-extraction-map.md b/docs/rail-kubernetes-extraction-map.md new file mode 100644 index 0000000..8034f07 --- /dev/null +++ b/docs/rail-kubernetes-extraction-map.md @@ -0,0 +1,85 @@ +# rail-kubernetes Extraction Map + +This document records the reviewed wave-1 extraction map from +`railiance-cluster` to a future `rail-kubernetes` repo. + +The goal is to separate: + +- S2 Kubernetes substrate ownership that stays in `railiance-cluster` +- generic workload-on-Kubernetes contract material that moves to + `rail-kubernetes` +- unrelated or workload-specific helpers that must be rehomed elsewhere instead + of being normalized into either repo + +## Move To Future `rail-kubernetes` + +| Path | Why it moves | +| --- | --- | +| `docs/deployment-lifecycle.md` | Generic Stage 1/2/3 workload lifecycle semantics, not S2 substrate ownership | +| `docs/app-toml-contract.md` | Generic workload declaration contract | +| `docs/overlay-repo-pattern.md` | Generic wrapper/overlay packaging pattern | +| `docs/canary-helm-template.md` | Generic canary chart pattern for workloads | +| `docs/stage2-deploy-observe.md` | Generic Stage 2 command behavior | +| `docs/promote-rollback-onboarding.md` | Generic workload onboarding to the lifecycle | +| `docs/railiance-run-command.md` | Generic Stage 1 command contract | +| `schemas/railiance-app.schema.json` | Schema for the generic workload contract | +| `examples/railiance/app.toml` | Example for the generic workload contract | +| `tools/create_railiance_overlay_repo.sh` | Generic wrapper/overlay scaffolding | +| `tools/cmd/railiance-run` | Generic Stage 1 executor | +| `tools/cmd/railiance-stage2` | Generic Stage 2 canary deploy/observe executor | +| `tools/cmd/railiance-stage3` | Generic Stage 3 promote/rollback executor | +| `bin/railiance` subcommands `create-overlay`, `run`, `deploy`, `observe`, `promote`, `rollback` | Dispatcher surface for the generic workload rail | +| `tools/README_tools.md` sections for `railiance-run`, `railiance-stage2`, `railiance-stage3`, and `create_railiance_overlay_repo.sh` | Tool documentation should move with the tools it describes | + +## Retain In `railiance-cluster` + +| Path | Why it stays | +| --- | --- | +| `ansible/bootstrap.yml` | k3s and Helm bootstrap are core S2 substrate ownership | +| `docs/backup-restore.md` | Cluster-state backup and restore posture | +| `docs/kubeconfig.md` | Cluster access delivery and handling | +| `docs/operator-runbook.md` | Operator-facing cluster-touching commands, though some rows need separate cleanup | +| `docs/first_host.md` | Host-to-cluster bootstrap guidance tied to S2 setup | +| `tools/cmd/railiance-backup-s2` | S2 cluster-state backup helper | +| `tools/cmd/railiance-restore-s2` | S2 restore guidance helper | +| `tools/cmd/railiance-preflight` | Cluster safety gate before invasive work | +| `tests/smoke_kube.sh` | Cluster health smoke test | +| `tests/test_ha_failover.sh` | Cluster/platform integration smoke for HA failover expectations | +| `Makefile` targets `k3s-install`, `smoke`, `backup`, `restore`, `preflight`, `test-ha-failover` | Cluster substrate operations and safety rails | +| `bin/railiance` subcommands `backup` and `preflight` | Compatibility wrapper for retained S2 operations until a cleaner CLI split exists | + +## Rehome Outside Both Repos + +These files are real migration debt, but they should not be normalized into +future `rail-kubernetes` or kept as permanent S2 identity. + +| Path | Why it needs another home | +| --- | --- | +| `tools/cmd/railiance-verify-activity-core` | Workload-specific reconcile/verify flow for one app | +| `tools/cmd/railiance-reconcile-activity-core-llm-connect` | Cross-repo workload-specific helper, not generic substrate or generic rail | +| `tools/cmd/railiance-deploy-activity-core-triage-robustness` | Workload-specific deployment hardening helper | +| `tools/cmd/railiance-admin-sync-smoke` | Workload-specific app smoke command | +| `Makefile` targets `verify-activity-core`, `reconcile-activity-core-llm-connect`, `deploy-activity-core-triage-robustness`, `admin-sync-smoke` | Operator entry points for workload-specific helpers above | +| `bin/railiance` subcommands `deploy-triage-robustness` and `admin-sync-smoke` | Dispatcher surface for workload-specific helpers | + +## Shared Tooling Debt Outside This Wave + +The repo also contains bootstrap and shared-tooling commands that belong +neither to S2 substrate ownership nor to the future `rail-kubernetes` rail. +They should get a separate placement review rather than piggybacking on the +current extraction: + +- `bin/railiance` subcommands `doctor`, `next`, `plan-host`, `gen-ssh-key`, + `cloudinit`, `init-repo`, `build-spore`, `seed-local`, `checklist` +- `tools/cmd/railiance-doctor` +- `tools/cmd/railiance-plan-host` +- `tools/build_spore.sh` +- `tools/seed_node.sh` +- `tools/create_railiance_repo.sh` +- `tools/furnish_railiance_repo.sh` + +## Resulting Rule + +Until `rail-kubernetes` exists, `railiance-cluster` may host compatibility +copies of the generic lifecycle and command surface. It must not keep claiming +that those materials are the steady-state S2 ownership boundary. diff --git a/docs/rail-kubernetes-substrate-profile.md b/docs/rail-kubernetes-substrate-profile.md new file mode 100644 index 0000000..c2c4ca6 --- /dev/null +++ b/docs/rail-kubernetes-substrate-profile.md @@ -0,0 +1,113 @@ +# rail-kubernetes Substrate Profile + +This document records the minimum cluster substrate facts that +`railiance-cluster` publishes for a future `rail-kubernetes` repo. + +The intent is narrow: future rail code should depend on explicit substrate +capabilities, not on incidental implementation details scattered across this +repo. + +## Runtime Base + +- Kubernetes runtime: k3s installed by `ansible/bootstrap.yml` +- Current pinned k3s version in repo: `v1.35.1+k3s1` +- Current pinned Helm version in repo: `v3.17.3` +- Baseline health checks: `make smoke` +- Cluster safety gate before invasive work: `make preflight` + +`rail-kubernetes` may assume a k3s-backed Kubernetes API plus Helm-based apply +paths on the current Railiance substrate. It should not assume more than that +without a declared extension. + +## Access Model + +- Operator access is delivered from `/etc/rancher/k3s/k3s.yaml` to + `~/.kube/config-hosteurope` as documented in `docs/kubeconfig.md` +- The raw k3s kubeconfig uses `127.0.0.1` as the server address and may require + rewrite or tunneling for remote use +- The documented operator model is cluster-admin kubeconfig access, not a + least-privilege workload service-account contract + +Future `rail-kubernetes` should assume operator-driven cluster access for now. +It should not assume a published per-workload RBAC template yet. + +## Routing And Canary Exposure + +- The current generic tooling supports isolated canary deployment by creating a + separate Stage 2 release and namespace +- `docs/canary-helm-template.md` documents a Traefik weighted-routing example, + but `railiance-cluster` does not currently publish weighted routing as a + guaranteed substrate capability +- `tools/cmd/railiance-stage2` can inspect rollout, pods, and ingress/routing + resources for the canary release + +Published guarantee for wave 1: isolated canary exposure is the safe default. +Weighted, header-based, path-based, or shadow routing must be treated as +optional future capabilities until S2 documents them explicitly. + +## TLS And Cluster Operators + +`SCOPE.md` currently records these cluster-level addons/operators on the active +substrate: + +- nginx ingress +- cert-manager +- ArgoCD +- CloudNative PG operator +- SSO stack namespaces (`mfa`, `sso`) via Net Kingdom + +Future `rail-kubernetes` should depend on capabilities such as ingress +availability or TLS readiness, not on owning these operators directly. + +## Observability Expectations + +- `tools/cmd/railiance-stage2` live observe checks rollout status, deployment + JSON, canary pod state, ingress/routing resources, and pod metrics +- `docs/stage2-deploy-observe.md` explicitly treats metrics-server absence as a + separate observability note rather than as proof that rollout failed + +Published guarantee for wave 1: rollout, pod, and ingress inspection are part +of the substrate contract. Metrics availability is opportunistic unless the +cluster profile is later strengthened. + +## Namespace And Release Behavior + +- `tools/cmd/railiance-stage2` and `tools/cmd/railiance-stage3` use + `--create-namespace` +- Stage defaults derive namespace and release names from workload contract data + when the workload does not override them + +Future `rail-kubernetes` may assume that namespace creation is acceptable in the +current operator flow. It should not assume namespaces or release names are +pre-provisioned by S2. + +## Storage And Stateful Constraints + +- `tools/cmd/railiance-backup-s2` documents that the current cluster runs k3s + in SQLite mode and backs up `/var/lib/rancher/k3s/server/db/state.db` +- This repo does not yet publish a generic storage-class, PVC, or stateful + workload placement contract for downstream workload rails + +That means stateful workload assumptions remain explicit-review territory for +now. `rail-kubernetes` should not invent a storage contract on behalf of S2. + +## Safety Rails Published By S2 + +- age-encrypted cluster backup via `make backup` +- printed restore procedure via `make restore` +- preflight gate via `make preflight` +- smoke validation via `make smoke` + +These are substrate safety rails. They are not a substitute for workload-level +promotion or rollback logic. + +## Not Yet Published + +The future `rail-kubernetes` must currently treat these as absent or +repo-specific until S2 publishes them explicitly: + +- guaranteed weighted routing on the active ingress controller +- a generic workload RBAC model +- a generic storage-class or persistent-volume contract +- a secret-delivery contract at the S2 layer +- multi-node HA assumptions beyond the active `RAIL-BS-WP-0007` work diff --git a/workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md b/workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md index 762d13a..84c1fa6 100644 --- a/workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md +++ b/workplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md @@ -4,7 +4,7 @@ type: workplan title: "rail-kubernetes extraction from railiance-cluster" domain: financials repo: railiance-cluster -status: ready +status: active owner: codex topic_slug: railiance created: "2026-07-25" @@ -42,7 +42,7 @@ It must not: ```task id: RAIL-BS-WP-0012-T01 -status: todo +status: done priority: high state_hub_task_id: "7255ef32-3fdf-473f-a5c0-62b509ee7a4e" ``` @@ -55,11 +55,16 @@ Update S2 scope and related docs so they clearly distinguish: Done when the repo no longer describes the staged workload lifecycle as a long-term S2 ownership concern. +2026-07-25: Updated `SCOPE.md`, `README.md`, and `docs/README.md` so S2 now +claims Kubernetes substrate ownership only, while the generic workload +lifecycle is marked as transitional material targeted for future +`rail-kubernetes`. + ## T02 - Inventory exact extraction candidates and retained files ```task id: RAIL-BS-WP-0012-T02 -status: todo +status: done priority: high state_hub_task_id: "e80b511a-33c6-445b-95e2-3d0755ea9b5e" ``` @@ -70,11 +75,15 @@ files remain cluster-owned. Done when the repo has one reviewed move map tied to real file paths. +2026-07-25: Added `docs/rail-kubernetes-extraction-map.md` with reviewed file +paths for material that moves to `rail-kubernetes`, material that remains +cluster-owned, and migration debt that must be rehomed elsewhere. + ## T03 - Define the cluster substrate profile consumed by `rail-kubernetes` ```task id: RAIL-BS-WP-0012-T03 -status: todo +status: done priority: high state_hub_task_id: "517e2849-9b36-4508-9e2a-90f219e211c7" ``` @@ -90,6 +99,10 @@ Define the minimum cluster profile that S2 publishes for the future rail: Done when `rail-kubernetes` has a narrow substrate contract to depend on. +2026-07-25: Added `docs/rail-kubernetes-substrate-profile.md` to publish the +current S2 substrate facts, guaranteed canary mode, operator/runtime +expectations, and explicit non-guarantees for wave 1. + ## T04 - Prepare compatibility shims for the migration window ```task