--- id: RAIL-HO-WP-0003 type: workplan title: "Railiance 5-Repo Stack Restructure" domain: railiance repo: railiance-infra status: completed owner: railiance topic_slug: railiance state_hub_workstream_id: "3ae0afc5-13f2-4e6c-aea7-1c1fb9f1ab81" created: "2026-03-09" updated: "2026-03-10" completed: "2026-03-10" --- # Railiance 5-Repo Stack Restructure ## Goal Restructure the railiance tooling to align one-to-one with the OAS Stack dimensions (S1–S5). Each repo owns exactly one stack layer. | OAS Level | Repo | Stack Responsibility | |-----------|------|---------------------| | S1 Infrastructure Substrate | `railiance-infra` | OS, Ansible roles, Goss spec, Terraform, inventory | | S2 Cluster Runtime | `railiance-cluster` | k3s, Helm, ingress, CNI, operators | | S3 Platform Services | `railiance-platform` | PostgreSQL HA, object storage, secret mgmt, identity | | S4 Developer Enablement | `railiance-enablement` | CI/CD, developer portal, platform templates | | S5 Workloads & Experience | `railiance-apps` | App Helm releases, Gitea, coulomb services | ## Motivation The original names (`railiance-hosts`, `railiance-bootstrap`) do not signal their stack layer. The new names make the architecture self-documenting and enforce the OAS P1 principle (Separation of Dimensions). ## Boundary rule (new) > **Every file and playbook belongs in exactly one repo, determined by the > OAS Stack level of the concern it addresses.** ADR-003 (written in T01) supersedes ADR-002. ## Content relocations from railiance-cluster The following items currently in railiance-bootstrap (→ railiance-cluster) belong at other layers and must move: | Item | Current location | Destination | Layer | |------|-----------------|-------------|-------| | `cloudinit/user-data.yaml` | railiance-cluster | railiance-infra | S1 | | `tools/cmd/railiance-plan-host` | railiance-cluster | railiance-infra | S1 | | `tools/cmd/railiance-backup` | railiance-cluster | railiance-platform | S3 | Everything else in railiance-cluster (k3s playbook, Helm, smoke tests, preflight, doctor, seed_node) is correctly placed at S2. --- ## Tasks ### T01 — Write ADR-003: Railiance 5-Repo Stack Architecture ```task id: T01 status: done priority: high state_hub_task_id: "4ff2c35f-7cf8-46a3-a5e3-366bb0e193c7" completed: "2026-03-10" ``` Create `docs/adr/ADR-003-railiance-5repo-stack-architecture.md` in railiance-infra (formerly railiance-hosts) covering: - The five-repo layout and OAS S1–S5 mapping - Naming rationale (`railiance-{infra,cluster,platform,enablement,apps}`) - Boundary rule: one repo per stack layer - Content relocation table (items moving from railiance-cluster) - Migration note: supersedes ADR-002 - Invalidation note in ADR-002 header pointing to ADR-003 **Done when:** ADR-003 written; ADR-002 updated with superseded status and forward reference. --- ### T02 — Rename railiance-hosts → railiance-infra ```task id: T02 status: done priority: high state_hub_task_id: "5b29d8f8-ab9b-4d8c-a2a0-87918eac5cc4" completed: "2026-03-10" ``` **Local:** ```bash mv ~/railiance-hosts ~/railiance-infra cd ~/railiance-infra # Update any self-referencing paths (CLAUDE.md, Makefile REPO var, etc.) grep -r "railiance-hosts" . --include="*.md" --include="*.sh" --include="Makefile" ``` **Gitea remote:** Rename the repository in Gitea UI or via API, then update the local remote: ```bash git remote set-url origin https://gitea.example.com/coulomb/railiance-infra.git ``` **State Hub:** ``` rename_domain is not the right tool — use the API directly or update the ManagedRepo slug via the admin API once rename_repo is available. ``` Current slug: `railiance-hosts` → new slug: `railiance-infra` **CLAUDE.md:** Update repo name references. **Workplan files:** Update `repo:` frontmatter field in all workplans. **Done when:** `ls ~/railiance-infra` works; git remote points to renamed Gitea repo; state hub slug updated. --- ### T03 — Rename railiance-bootstrap → railiance-cluster ```task id: T03 status: done priority: high state_hub_task_id: "caf3c22e-3d83-46a3-9bd8-23a5d9021f72" completed: "2026-03-10" ``` Same procedure as T02 for railiance-bootstrap → railiance-cluster: ```bash mv ~/railiance-bootstrap ~/railiance-cluster ``` Update: - Gitea remote - State hub slug (`railiance-bootstrap` → `railiance-cluster`) - CLAUDE.md repo name references - Workplan `repo:` frontmatter fields **Done when:** rename complete; all cross-references updated. --- ### T04 — Relocate misplaced content to correct repos ```task id: T04 status: done priority: medium state_hub_task_id: "35d3b599-8325-472c-abd0-2c4939f1f8cd" completed: "2026-03-10" ``` After T02 and T03 are complete, move items to their correct layer repos: **→ railiance-infra (S1):** ```bash # From railiance-cluster: git mv cloudinit/user-data.yaml /path/to/railiance-infra/cloudinit/ git mv tools/cmd/railiance-plan-host /path/to/railiance-infra/tools/cmd/ ``` **→ railiance-platform (S3):** ```bash # From railiance-cluster (after T05 creates the repo): git mv tools/cmd/railiance-backup /path/to/railiance-platform/tools/cmd/ ``` Commit in both source and destination repos. Add a tombstone stub in the source location pointing to the new home. **Done when:** all three items committed in their destination repos; stubs in place in railiance-cluster. --- ### T05 — Create and scaffold three new repos ```task id: T05 status: done priority: medium state_hub_task_id: "ba48bdca-a3e5-4efa-8bd1-55077e92a787" completed: "2026-03-10" ``` Create `railiance-platform`, `railiance-enablement`, `railiance-apps` as git repos with minimal scaffolding: For each repo: 1. `git init ~/railiance-{platform,enablement,apps}` 2. Create `CLAUDE.md` using the Custodian project template 3. Create `workplans/` directory with a `.gitkeep` 4. Create a `Makefile` stub with `help` target 5. Create `README.md` describing the layer's scope 6. Initial commit **Done when:** all three repos exist locally with at least CLAUDE.md, workplans/, and a Makefile stub. --- ### T06 — Register all five repos in the state hub ```task id: T06 status: done priority: medium state_hub_task_id: "a5310b9a-665c-4341-92bf-e51db65c2388" completed: "2026-03-10" ``` After T02, T03, T05: ``` register_repo(domain_slug="railiance", name="railiance-infra", slug="railiance-infra", local_path="/home/worsch/railiance-infra") register_repo(domain_slug="railiance", name="railiance-cluster", slug="railiance-cluster", local_path="/home/worsch/railiance-cluster") register_repo(domain_slug="railiance", name="railiance-platform", slug="railiance-platform", local_path="/home/worsch/railiance-platform") register_repo(domain_slug="railiance", name="railiance-enablement", slug="railiance-enablement", local_path="/home/worsch/railiance-enablement") register_repo(domain_slug="railiance", name="railiance-apps", slug="railiance-apps", local_path="/home/worsch/railiance-apps") ``` The old slugs (`railiance-hosts`, `railiance-bootstrap`) can be archived or left as stale records until a rename-repo API endpoint exists. **Done when:** all five repos appear in `list_domain_repos("railiance")`. --- ### T07 — Resolve pending railiance-apps decision ```task id: T07 status: done priority: low state_hub_task_id: "2aaebc21-da59-456e-abdf-8cf03fd82e49" completed: "2026-03-10" ``` Decision `7cddead6` ("Create railiance-apps repo for application-layer deployments") is now resolved by this workplan. Resolve it in the state hub: ``` resolve_decision(decision_id="7cddead6-79dd-4cca-a6d5-6512369603bb", rationale="railiance-apps created as S5 layer of the 5-repo OAS stack.", decided_by="Bernd Worsch") ``` **Done when:** decision marked resolved. --- ## References - OAS Standard: `canon/standards/orthogonal-architecture_v1.0.md` - ADR-002 (superseded): `docs/adr/ADR-002-repo-boundary-hosts-vs-bootstrap.md` - State Hub workstream: `3ae0afc5-13f2-4e6c-aea7-1c1fb9f1ab81` - Pending decision (railiance-apps): `7cddead6-79dd-4cca-a6d5-6512369603bb`