From e0f9a08b1c01f4213c190f5902d53a2ca54f539c Mon Sep 17 00:00:00 2001 From: tegwick Date: Fri, 5 Jun 2026 00:56:33 +0200 Subject: [PATCH] Clarify app scope and plan forge extraction --- INTENT.md | 137 +++++++ SCOPE.md | 232 +++++++++--- ...LIANCE-WP-0005-s5-app-release-readiness.md | 195 ++++++++++ ...ANCE-WP-0006-railiance-forge-extraction.md | 351 ++++++++++++++++++ 4 files changed, 872 insertions(+), 43 deletions(-) create mode 100644 INTENT.md create mode 100644 workplans/RAILIANCE-WP-0005-s5-app-release-readiness.md create mode 100644 workplans/RAILIANCE-WP-0006-railiance-forge-extraction.md diff --git a/INTENT.md b/INTENT.md new file mode 100644 index 0000000..02ae3eb --- /dev/null +++ b/INTENT.md @@ -0,0 +1,137 @@ +# 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 application workload layer - turning platform capabilities into reliable, user-facing Railiance services with repeatable release operations.** + +--- + +## Why This Exists + +A converged platform is not yet a useful experience for users. +Someone must take shared runtime, data, identity, registry, and enablement +capabilities and turn them into deployed workloads with clear release +configuration, operator runbooks, and app-level verification. + +Without a disciplined application layer: + +* deployment concerns scatter across source repos and live clusters, +* lower-layer boundaries blur when apps need "just one" platform tweak, +* operators rediscover the same ingress, secret, probe, and registry traps, +* and user-facing services become difficult to promote, debug, and recover. + +This layer exists to make application releases **repeatable, bounded, and +operable**, so Railiance can add services without turning every deployment into +a new archaeology exercise. + +--- + +## The Mission + +> *Where we are going.* + +To become the **canonical home for Railiance application workload releases** - +the Helm values, Kubernetes manifests, registry enablement, app-level runbooks, +smoke checks, and operator recipes that make user-facing services safe to ship +on top of the platform. + +This means: + +* Application deployments have **source-controlled release contracts** +* Operators can deploy, verify, and recover apps through **repeatable runbooks** +* Apps consume lower-layer capabilities through **stable handoff points** +* Source application repos remain responsible for their code, packages, and + build artifacts +* The first-app lessons become **reusable patterns** for the next app + +--- + +## Core Principles + +### 1. Workloads, Not Runtime + +Own the application releases that run on the platform. Do not own the +infrastructure, cluster runtime, or shared platform services beneath them. + +### 2. Release Contracts over Source Internals + +This repo should describe how an application is released and operated on +Railiance, not become the application's source-code repository. + +### 3. Repeatable Operations + +Deploys, upgrades, smoke tests, migrations, and emergency checks should be +codified as scripts, Make targets, and runbooks rather than remembered by +operators. + +### 4. Clear Lower-Layer Handoffs + +Applications consume databases, secrets, storage, identity, and runtime +capabilities through explicit contracts with S1-S4. This layer does not reach +down and mutate those layers to make an app work. + +### 5. Evidence Before Confidence + +An app release is healthy when probes, status checks, smoke tests, and operator +evidence say it is healthy, not merely because manifests applied successfully. + +### 6. Current Workload, Future Path + +Gitea and early application releases are current S5 workloads and learning +surfaces. Their lessons should leave behind reusable deployment patterns that +survive future forge and app migrations. + +--- + +## What This Is (Conceptually) + +This layer is: + +* an **application workload release** layer +* a home for **Helm release configuration** and app-level manifests +* an **operator runbook** and deployment guardrail surface +* a bridge from shared platform capabilities to **user-facing services** +* a place where app deployment lessons become **reusable S5 patterns** + +--- + +## What This Is Not + +This layer is not: + +* the infrastructure substrate beneath Railiance +* the Kubernetes runtime or cluster addon layer +* the shared platform-services layer for databases, secrets, cache, or storage +* the CI/CD and developer enablement layer +* the source-code home for deployed applications +* a secret custody authority + +It is the **last-mile release and operations surface** for services users +actually touch. + +--- + +## Direction of Evolution + +This layer is expected to evolve toward: + +* A reusable **new S5 app release checklist** +* Stronger **image and package promotion** patterns +* Clearer **backup, restore, and data ownership handoffs** with S3 +* More complete **smoke, migration, rollback, and observability** recipes +* Cleaner separation between **current forge operation** and future forge + migration paths +* Self-evidencing, reviewable **application readiness** before promotion + +--- + +## Guiding Question + +> **How can each Railiance application become easy to release, verify, operate, and recover without weakening the boundaries of the layers beneath it?** diff --git a/SCOPE.md b/SCOPE.md index 9dad382..3f51ba9 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -1,85 +1,218 @@ # 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. +This file defines what `railiance-apps` owns, when to use it, and where its +boundaries stop. + +Last reviewed: 2026-06-04 --- ## One-liner -S5 Workloads & Experience layer of the Railiance OAS Stack — owns application Helm releases and Kubernetes manifests for user-facing services (Gitea, coulomb services, web frontends). +S5 Workloads & Experience Endpoints for Railiance: application Helm releases, +Kubernetes workload manifests, registry enablement, and operator runbooks for +user-facing services such as Gitea and `vergabe-teilnahme`. --- ## Core Idea -Railiance is structured as five independent repos, one per OAS (Open Application Stack) layer. This repo is S5 — the top layer. It owns application-level deployments: Helm values and manifests for Gitea, coulomb services, APIs, and web portals. It depends on S1–S4 being operational before it can do anything. +Railiance is organized as layered repositories for the Open Application Stack. +This repository owns the S5 application deployment surface. It does not build +the lower platform; it takes already-converged infrastructure, cluster, +platform services, and enablement paths, then ships user-facing workloads on +top of them. + +The practical contract is: + +1. lower layers provide runtime primitives and platform services, +2. this repo owns application release configuration and app-level manifests, +3. operator docs and checks here make those releases repeatable, +4. source application repos own their app code, package metadata, and image + build pipelines. + +--- + +## Intent Comparison + +`INTENT.md` now defines the stable purpose of this repo as the S5 application +workload layer: turning platform capabilities into reliable, user-facing +Railiance services with repeatable release operations. Compared with that +intent, the current implementation is aligned around: + +- keep S5 application deployments portable across operators, CI, and remote + builders; +- keep application release concerns in S5 while respecting S1-S4 ownership; +- provide enough runbook and guardrail coverage that the next app does not + rediscover the same deployment traps; +- use Gitea as the current forge and package registry until the Forgejo + production migration supersedes it. + +The remaining gap is not the absence of intent; it is turning the first-app +lessons into reusable S5 app release patterns. --- ## In Scope -- Application Helm releases: Gitea, coulomb services, web portals, APIs -- Kubernetes manifests for user-facing workloads -- Application-level configuration and deployment orchestration +- Gitea as the current S5 forge workload: + - Helm release values in `helm/gitea-values.sops.yaml`; + - non-secret registry overlay in `helm/gitea-registry-values.yaml`; + - ingress manifest in `manifests/gitea-ingress.yaml`; + - `make gitea-deploy`, `make gitea-status`, and related operator checks. +- Gitea package registry enablement and operator documentation: + - container registry path and smoke evidence; + - Python package registry endpoint and consumer guidance; + - registry settings applied as application Helm configuration. +- `vergabe-teilnahme` as the first concrete S5 application release: + - chart in `charts/vergabe-teilnahme/`; + - values in `helm/vergabe-teilnahme-values.yaml`; + - ingress in `manifests/vergabe-teilnahme-ingress.yaml`; + - Makefile targets for deploy, status, migrations, seed, logs, and DB URL + secret rebuilds. +- Application deployment operator guardrails: + - `make check-tools`; + - `make check-sops`; + - `make k8s-server-dry-run`; + - `.gitea/workflows/manifest-server-dry-run.yaml`; + - scripts under `tools/`. +- S5 app runbooks and recipes in `docs/`, especially: + - `docs/vergabe-teilnahme.md`; + - `docs/gitea-container-registry.md`; + - `docs/gitea-package-registry.md`; + - `docs/django-on-railiance.md`; + - `docs/operator-setup.md`; + - `docs/operator-recipes.md`. +- Repo-local workplan files under `workplans/`. --- ## Out of Scope -- OS-level concerns → railiance-infra (S1) -- Kubernetes runtime → railiance-cluster (S2) -- Platform services (PostgreSQL, caches, storage) → railiance-platform (S3) -- Developer tooling (CI/CD, portals) → railiance-enablement (S4) -- No re-configuration of lower layers from this repo +- OS or host provisioning: `railiance-infra`. +- Kubernetes runtime, ingress controller primitives, and cluster-level routing: + `railiance-cluster`. +- Platform databases, shared backup primitives, object storage, caches, and + durable platform services: `railiance-platform`. +- CI/CD systems, source templates, and developer portal enablement outside the + S5 app release surface: `railiance-enablement`. +- Application source code and package build metadata for deployed apps: + source application repos such as `vergabe-teilnahme`. +- Publishing `issue-core` itself or regenerating `vergabe-teilnahme` package + locks: `issue-core` and `vergabe-teilnahme` own those release artifacts. +- Secret value custody. This repo may reference SOPS files and Kubernetes + Secret names, but it must not commit decrypted values or secret material. --- ## Relevant When -- Deploying or updating user-facing applications in the Railiance stack -- S1–S4 are all operational and it's time to deploy workloads +- Deploying or upgrading Gitea as the current S5 forge workload. +- Enabling or verifying Gitea package registry behavior for S5 consumers. +- Deploying or upgrading `vergabe-teilnahme` on Railiance. +- Adding another user-facing S5 application release. +- Debugging app-level Helm values, app ingress, app probes, app secrets, or + app-specific runbook behavior. +- Turning lessons from an app deployment into reusable operator recipes. --- ## Not Relevant When -- S1–S4 are not yet operational (pre-conditions not met) -- Infrastructure, cluster, or platform work needed (wrong layer) -- No user-facing applications to deploy +- S1-S4 are not converged enough for S5 workloads to deploy. +- The work requires platform database provisioning, backup controller setup, or + shared storage changes. +- The work is application source-code behavior rather than release wiring. +- The work is Forgejo production migration design rather than current Gitea + operation. +- The work requires secret custody, credential generation, or token storage + outside approved operator paths. --- -## Current State +## Current Implementation Surface -- Status: active (Gitea Helm values now owned by S5; boundary violation resolved) -- Implementation: Gitea is deployed and operational. Helm values (`helm/gitea-values.sops.yaml`) are now managed from this repo (S5) — moved from railiance-cluster in RAIL-HO-WP-0004-T06. Gitea uses an external cnpg database (`gitea-db` in the `databases` namespace) and standalone Valkey. -- Stability: Gitea stable; S5 layer now owns the Gitea deployment lifecycle -- Usage: Gitea serves as the git hosting platform for all Railiance and Custodian repos +- Gitea is deployed and operational as the current forge. Its S5 Helm values + live here, and registry settings are layered through + `helm/gitea-registry-values.yaml`. +- The Gitea container registry path is verified and documented. Package blobs + currently land on the Gitea shared PVC, so storage growth and backup/retention + posture remain important follow-up concerns. +- The Gitea Python package registry endpoint is enabled and documented. The + `issue-core` migration is still blocked on publishing `issue-core==0.2.0` + with package credentials in the `issue-core` repo and refreshing the + `vergabe-teilnahme` lock in its source repo. +- `vergabe-teilnahme` is represented as a local Helm chart plus values, + ingress, Makefile targets, and an operator runbook. +- Several deployment lessons are now repo-local guardrails: URL-encoded + database URL secret creation, Django probe Host headers, operator tool checks, + SOPS age-key checks, server-side manifest dry-run, and persistent-pod smoke + testing. +- Workplan files are now the source artifacts for planned work. State Hub + indexes those files as workstreams and task blocks after + `make fix-consistency REPO=railiance-apps`. + +--- + +## Known Gaps And Opportunities + +- `docs/vergabe-teilnahme.md` still references the old local `issue-core` + Docker build-context path in the image promotion section. It needs to be + updated after the package registry handoff is fully closed. +- Gitea package blob storage is operational but not yet tied to an explicit + retention, capacity, and restore posture. +- The first-app lessons from `vergabe-teilnahme` are documented, but there is + no reusable "new S5 app release checklist" yet. +- The manifest dry-run workflow assumes access to a representative cluster and + CRDs. Its operating requirements should be made explicit for future runners. +- App-level backup and restore responsibilities need clearer handoff contracts + with `railiance-platform`, especially for shared CNPG databases consumed by + S5 apps. + +--- + +## Workplan And State Hub Model + +Work items originate as files in this repository under `workplans/`. State Hub +does not own the canonical file; it indexes workplan files as hub workstreams +and indexes each fenced task block as a hub task. + +After editing workplan files, run from `~/state-hub`: + +```bash +make fix-consistency REPO=railiance-apps +``` + +Use "workplan" for the repo file and "workstream" for the State Hub row created +from that file. --- ## How It Fits -- Upstream dependencies: railiance-infra (S1) → railiance-cluster (S2) → railiance-platform (S3) → railiance-enablement (S4) → this repo (S5) -- Downstream consumers: end users accessing Gitea, coulomb services, web portals -- Often used with: railiance-platform (database/cache backends), net-kingdom (identity for apps) - ---- - -## Terminology - -- Preferred terms: OAS Stack Level S5, workloads, experience endpoints, boundary rule -- Potentially confusing terms: "S5" is a stack level designation, not a version +- Upstream dependencies: + `railiance-infra` (S1) -> `railiance-cluster` (S2) -> + `railiance-platform` (S3) -> `railiance-enablement` (S4) -> + `railiance-apps` (S5). +- Downstream consumers: + operators deploying S5 workloads, users accessing deployed apps, and source + repos that need a governed deployment target. +- Frequent collaborators: + `railiance-platform` for databases and backup contracts, `net-kingdom` for + identity integrations, `issue-core` for task/package coordination, and source + app repos such as `vergabe-teilnahme`. --- ## Related / Overlapping -- `railiance-platform` (S3) — provides database, cache, identity services consumed by S5 apps -- `railiance-enablement` (S4) — provides CI/CD and templates that S5 uses -- `railiance-cluster` (S2) — Kubernetes runtime where S5 workloads run +- `railiance-platform`: shared CNPG clusters, backup primitives, object storage, + and other platform services consumed by S5 apps. +- `railiance-enablement`: CI/CD and templates used by S5 releases. +- `railiance-cluster`: Kubernetes runtime, ingress controllers, cert-manager, + and cluster networking. +- `vergabe-teilnahme`: source Django app, package lock, Dockerfile, and app code. +- `issue-core`: package release required by `vergabe-teilnahme` and future apps. --- @@ -87,16 +220,29 @@ Railiance is structured as five independent repos, one per OAS (Open Application ```capability type: infrastructure -title: Application workload deployment (Gitea, coulomb services) -description: Deploy and manage user-facing applications — Gitea, coulomb services, APIs, and web portals — as Helm releases on the Railiance Kubernetes cluster. -keywords: [gitea, coulomb, webapp, helm, application, deployment, workload] +title: S5 application workload deployment +description: Deploy and operate user-facing Railiance applications as Helm releases and Kubernetes manifests, including Gitea, registry enablement, and the first Django S5 app release. +keywords: [railiance, s5, gitea, registry, helm, django, vergabe-teilnahme, workload, deployment] +``` + +```capability +type: operations +title: S5 deployment guardrails and runbooks +description: Provide operator checks, SOPS verification, server-side manifest dry-runs, smoke-test patterns, and app-specific deployment runbooks for Railiance S5 workloads. +keywords: [operator, runbook, sops, cnpg, dry-run, smoke-test, deployment] ``` --- ## Getting Oriented -- Start with: `CLAUDE.md` (session protocol, boundary rules) -- Key files / directories: `workplans/` (currently empty), `Makefile` -- Pre-conditions: all four lower layers (S1–S4) must be converged and verified -- Key files: `helm/gitea-values.sops.yaml` (Gitea Helm values, SOPS-encrypted), `releases/gitea/values.yaml` (legacy plain values — superseded) +1. Read `AGENTS.md` for session protocol and State Hub conventions. +2. Read `INTENT.md` for the stable purpose of the S5 layer. +3. Read this file for scope and boundaries. +4. Read the active files in `workplans/`. +5. For Gitea registry work, start with `docs/gitea-container-registry.md` and + `docs/gitea-package-registry.md`. +6. For `vergabe-teilnahme`, start with `docs/vergabe-teilnahme.md`, then inspect + `charts/vergabe-teilnahme/`, `helm/vergabe-teilnahme-values.yaml`, and + `manifests/vergabe-teilnahme-ingress.yaml`. +7. Run `make check-tools` and `make check-sops` before deploy work. diff --git a/workplans/RAILIANCE-WP-0005-s5-app-release-readiness.md b/workplans/RAILIANCE-WP-0005-s5-app-release-readiness.md new file mode 100644 index 0000000..dd04859 --- /dev/null +++ b/workplans/RAILIANCE-WP-0005-s5-app-release-readiness.md @@ -0,0 +1,195 @@ +--- +id: RAILIANCE-WP-0005 +type: workplan +title: "S5 app release readiness and scope alignment" +domain: railiance +repo: railiance-apps +status: ready +owner: codex +topic_slug: railiance +planning_priority: medium +created: "2026-06-04" +updated: "2026-06-04" +state_hub_workstream_id: "685f1c18-33c0-400d-a2b1-e1dae0f27c3e" +--- + +# S5 app release readiness and scope alignment + +## Context + +The 2026-06-04 review of `SCOPE.md` against the actual repository +implementation found that `railiance-apps` has moved beyond "Gitea Helm values" +and now owns the repeatable S5 application release surface: Gitea registry +enablement, the `vergabe-teilnahme` Helm release, operator guardrails, and +deployment runbooks. + +The same review found several gaps: + +- `INTENT.md` is missing, so purpose and scope are collapsed into one document. +- The `vergabe-teilnahme` runbook still contains stale image-promotion guidance + tied to the old local `issue-core` build context. +- First-app lessons are documented, but there is no reusable checklist for the + next S5 app release. +- Gitea package storage and app database backup responsibilities need clearer + contracts with platform-layer work. +- The server-side dry-run workflow does not state its live-cluster/CRD + prerequisites clearly enough for a future runner. + +This workplan turns those scope gaps into the next improvement strand. + +## T01 - Write `INTENT.md` + +```task +id: RAILIANCE-WP-0005-T01 +status: done +priority: high +state_hub_task_id: "af15d202-c013-48b1-8522-671477e31381" +``` + +Create `INTENT.md` for `railiance-apps`. + +It should explain: + +- why this repo exists as the S5 application deployment surface; +- what problem it solves for operators and source app repos; +- what it intentionally does not own across S1-S4 boundaries; +- how Gitea, package registry enablement, `vergabe-teilnahme`, and future S5 + apps fit together; +- how workplan files relate to State Hub workstreams and task rows. + +Done when `INTENT.md` stands on its own and `SCOPE.md` can reference it instead +of carrying all purpose language itself. + +--- + +## T02 - Normalize app image promotion and package registry docs + +```task +id: RAILIANCE-WP-0005-T02 +status: todo +priority: high +state_hub_task_id: "f8f63edb-a7ef-4692-8b01-66402d296cbb" +``` + +Update app promotion docs after the `issue-core` package handoff is complete. + +Focus areas: + +- remove stale references to the old `--build-context issue-core=...` path from + `docs/vergabe-teilnahme.md`; +- document the package-registry credential path for private Python package + installs without committing tokenized index URLs; +- state when `vergabe-teilnahme/uv.lock` must be regenerated in the source repo; +- keep `docs/gitea-package-registry.md` focused on the S5 registry endpoint and + cross-link source-repo release docs instead of duplicating them. + +Done when the Railiance operator docs describe the portable image promotion path +and no active runbook tells an operator to rely on a sibling repo checkout. + +--- + +## T03 - Create a reusable S5 app onboarding checklist + +```task +id: RAILIANCE-WP-0005-T03 +status: todo +priority: medium +state_hub_task_id: "4eab93a9-ad1b-46ca-97ef-18a059f64ab5" +``` + +Turn the `vergabe-teilnahme` deployment lessons into a reusable checklist for +the next S5 app. + +The checklist should cover: + +- chart and values layout; +- ingress and TLS ownership; +- health probe Host headers for framework apps; +- database secret handoff and URL-encoding guidance; +- image registry naming and pull verification; +- runbook sections every S5 app should ship; +- smoke-test pattern using persistent pods plus `kubectl exec`; +- State Hub workplan and task-sync expectations. + +Done when a new app can start from the checklist without reading all historical +workplans first. + +--- + +## T04 - Define app data backup and restore handoffs + +```task +id: RAILIANCE-WP-0005-T04 +status: todo +priority: high +state_hub_task_id: "299d9623-3a54-4e85-9a70-016e8356c3d9" +``` + +Clarify where S5 app data durability begins and ends. + +Cover at least: + +- Gitea package blobs on the shared Gitea PVC; +- `vergabe_db` on the shared `apps-pg` CNPG cluster; +- responsibility split between S5 runbooks and `railiance-platform` backup + controllers; +- minimum restore-drill evidence S5 app operators need before promoting an app + beyond smoke-test usage; +- how to file or link platform-layer workplans when the durability gap is not + local to this repo. + +Done when `SCOPE.md` and app runbooks clearly separate S5 release ownership from +S3 backup implementation while still giving operators an actionable restore +readiness gate. + +--- + +## T05 - Make manifest dry-run workflow prerequisites explicit + +```task +id: RAILIANCE-WP-0005-T05 +status: todo +priority: medium +state_hub_task_id: "6cf0e662-d7e2-48b1-b1f2-c7636240dd81" +``` + +Document and, where useful, encode the assumptions behind +`.gitea/workflows/manifest-server-dry-run.yaml` and +`make k8s-server-dry-run`. + +Questions to answer: + +- Does the workflow expect a live representative cluster? +- Which CRDs must already exist for server-side dry-run to be meaningful? +- What credentials or runner placement are required? +- What should happen when a runner has no cluster access? +- Which failures are release-blocking versus local operator setup issues? + +Done when a future operator can tell whether the workflow is ready to enforce +PR checks or still needs runner/cluster preparation. + +--- + +## T06 - Define Gitea package registry storage and retention posture + +```task +id: RAILIANCE-WP-0005-T06 +status: todo +priority: medium +state_hub_task_id: "382ba252-0f54-45fa-8e33-e656f4472341" +``` + +Document the operating posture for Gitea package storage while Gitea remains the +active forge. + +Include: + +- current PVC, size, and package blob location; +- expected retention approach for smoke-test images and Python wheels; +- cleanup procedure for superseded test tags; +- alert or inspection command for package storage growth; +- handoff to platform backup/restore work when package data becomes production + critical. + +Done when registry growth is no longer only a note in +`docs/gitea-container-registry.md`. diff --git a/workplans/RAILIANCE-WP-0006-railiance-forge-extraction.md b/workplans/RAILIANCE-WP-0006-railiance-forge-extraction.md new file mode 100644 index 0000000..328cd7f --- /dev/null +++ b/workplans/RAILIANCE-WP-0006-railiance-forge-extraction.md @@ -0,0 +1,351 @@ +--- +id: RAILIANCE-WP-0006 +type: workplan +title: "Extract railiance-forge and formalize forge-layer contracts" +domain: railiance +repo: railiance-apps +status: ready +owner: codex +topic_slug: railiance +planning_priority: high +created: "2026-06-04" +updated: "2026-06-04" +state_hub_workstream_id: "1960b22b-82ae-4b67-9fff-397bd38bdd65" +--- + +# Extract railiance-forge and formalize forge-layer contracts + +## Context + +The 2026-06-04 intent review found the S1-S5 Railiance framework mostly sound: + +```text +railiance-infra -> railiance-cluster -> railiance-platform -> +railiance-enablement -> railiance-apps +``` + +The main architecture smell is not the vertical layering. It is the set of +cross-cutting forge concerns currently straddling S4 and S5: + +- Gitea/Forgejo runtime ownership; +- container and Python package registries; +- Actions runners and CI/CD substrate; +- source-hosting operational runbooks; +- artifact lifecycle, retention, and restore posture; +- package/image promotion evidence used by application releases. + +The decision is to create a dedicated `railiance-forge` repository rather than +leaving forge responsibilities split between `railiance-apps` and +`railiance-enablement`. + +This workplan coordinates the extraction and the accompanying framework +contracts so the new repo becomes a clean abstraction rather than another place +for cross-layer drift. + +## Boundary Target + +`railiance-forge` should own: + +- current Gitea operation and future Forgejo migration/cutover; +- source forge deployment configuration and runbooks; +- container, package, and release artifact registries; +- forge-backed Actions runner substrate and repository automation hooks; +- artifact retention, registry storage, and restore readiness; +- forge observability and operational evidence; +- Fabric declarations for forge capabilities and interfaces. + +`railiance-forge` should not own: + +- server provisioning and OS hardening (`railiance-infra`); +- Kubernetes runtime primitives, ingress controllers, and cluster addons + (`railiance-cluster`); +- shared databases, object storage, caches, and runtime secret custody + (`railiance-platform`); +- generic workload templates, SDKs, and developer portal surfaces + (`railiance-enablement`); +- user-facing application release charts and app runbooks + (`railiance-apps`); +- application source code, package metadata, and image build definitions in + source repos. + +## T01 - Define the `railiance-forge` repository contract + +```task +id: RAILIANCE-WP-0006-T01 +status: todo +priority: high +state_hub_task_id: "129c2920-8868-4118-8772-ff5d925588cd" +``` + +Write the initial repository contract for `railiance-forge`. + +Deliverables: + +- `INTENT.md` explaining why the forge layer exists; +- `SCOPE.md` defining in-scope and out-of-scope responsibilities; +- `AGENTS.md` with State Hub integration, workplan prefix, repo identity, and + task-status vocabulary aligned with current State Hub canon; +- initial workplan convention using a new prefix, for example `FORGE-WP-`; +- explicit relationship to `railiance-apps`, `railiance-enablement`, + `railiance-platform`, and `railiance-cluster`. + +Done when the repo can be created without ambiguity about whether forge work +belongs there. + +--- + +## T02 - Create and register the `railiance-forge` repository + +```task +id: RAILIANCE-WP-0006-T02 +status: todo +priority: high +state_hub_task_id: "0e71e5a6-ce3c-4334-abf3-750aa8bef4df" +``` + +Create the sibling repository and connect it to the work coordination model. + +Steps: + +- create `/home/worsch/railiance-forge`; +- initialize Git metadata and baseline files; +- add `INTENT.md`, `SCOPE.md`, `AGENTS.md`, `README.md`, and a first workplan; +- create or register the State Hub topic for the new repo; +- run `make fix-consistency REPO=railiance-forge` once State Hub knows the repo; +- verify that the new workplan appears as a State Hub workstream. + +Done when `railiance-forge` is a first-class sibling repo with State Hub +indexing and no reliance on `railiance-apps` as its planning home. + +--- + +## T03 - Move current forge deployment surface out of `railiance-apps` + +```task +id: RAILIANCE-WP-0006-T03 +status: todo +priority: high +state_hub_task_id: "57162f50-d1a4-4fb3-b4fa-503939b22450" +``` + +Move the existing Gitea/registry operational surface into `railiance-forge`. + +Candidate source files in `railiance-apps`: + +- `helm/gitea-values.sops.yaml`; +- `helm/gitea-registry-values.yaml`; +- `manifests/gitea-ingress.yaml`; +- `releases/gitea/values.yaml`; +- Gitea-related `Makefile` targets; +- `docs/gitea-container-registry.md`; +- `docs/gitea-package-registry.md`; +- Gitea/package-registry sections in `SCOPE.md` and workplans. + +Migration rules: + +- preserve secret boundaries and do not expose decrypted values; +- keep the existing deployed service stable during the repo move; +- leave compatibility pointers in `railiance-apps` until operators have the + new paths; +- do not mix this move with the future Forgejo production cutover unless an + explicit cutover workplan says to. + +Done when `railiance-apps` no longer owns source-forge deployment config, and +current Gitea operation has an equivalent or better home in `railiance-forge`. + +--- + +## T04 - Re-scope `railiance-apps` and `railiance-enablement` + +```task +id: RAILIANCE-WP-0006-T04 +status: todo +priority: high +state_hub_task_id: "64ac73e7-abe5-47df-abbc-51aed25a7ce4" +``` + +Update the adjacent repos so the new abstraction is visible in their own +contracts. + +In `railiance-apps`: + +- remove Gitea/Forgejo as an owned S5 workload after migration; +- describe forge services as upstream release infrastructure consumed by app + releases; +- keep application charts, app-level runbooks, smoke tests, and deployment + guardrails in S5; +- update `RAILIANCE-WP-0005` tasks that mention Gitea package storage so they + point to the new forge ownership. + +In `railiance-enablement`: + +- clarify that reusable CI/CD templates and developer portal paths live in S4; +- clarify that the forge runtime, package registries, and Actions runner + substrate live in `railiance-forge`; +- define the handoff from S4 templates to forge-hosted automation. + +Done when a new operator can answer "is this S4, S5, or forge?" from the scope +documents without inspecting historical workplans. + +--- + +## T05 - Define artifact lifecycle, retention, and provenance policy + +```task +id: RAILIANCE-WP-0006-T05 +status: todo +priority: high +state_hub_task_id: "a99520c3-91dc-4af0-9f9b-0f0b53137be5" +``` + +Make artifact ownership explicit for images, packages, and source-hosted +release assets. + +Cover: + +- container image retention for smoke, development, and production tags; +- Python package retention for internal libraries such as `issue-core`; +- package/blob storage location and capacity inspection; +- cleanup commands and operator guardrails; +- artifact provenance expectations, including commit SHA tagging; +- future SBOM, vulnerability scanning, signing, and attestations; +- what evidence S5 needs before consuming a new artifact in an app release. + +Done when package and image growth, cleanup, and release evidence are not +implicit tribal knowledge. + +--- + +## T06 - Define CI runner, Actions, and GitOps ownership + +```task +id: RAILIANCE-WP-0006-T06 +status: todo +priority: high +state_hub_task_id: "37945939-e7c5-4717-83d9-294873810fb3" +``` + +Set the boundary between forge runtime, S4 reusable automation, and S5 release +checks. + +Questions to answer: + +- Which repo owns Gitea/Forgejo Actions runner deployment and credentials? +- Which repo owns workflow templates? +- Which repo owns app-specific workflows? +- How are runner labels, placement, and secret access controlled? +- What is the cutover path from current Gitea Actions to future Forgejo? +- Which server-side manifest dry-run checks belong in S5, and which runner + prerequisites belong in forge? + +Done when CI runner substrate and CI/CD templates no longer blur together. + +--- + +## T07 - Define backup, restore, and secret handoff contracts + +```task +id: RAILIANCE-WP-0006-T07 +status: todo +priority: high +state_hub_task_id: "da8bfbab-4bc3-48f0-9837-acf43fec9f0c" +``` + +Document how forge data and credentials interact with platform services. + +Cover: + +- forge database and package blob backup responsibilities; +- restore drills for source repos, packages, runners, and registry data; +- handoff to `railiance-platform` for CNPG/object-storage backup mechanisms; +- secret custody boundaries with SOPS/age bootstrap and OpenBao runtime + delivery; +- what operators may reference in docs without storing live secret values; +- how S5 apps verify forge artifacts without owning registry credentials. + +Done when the forge repo can state exactly what it owns, what S3 implements, +and what evidence consumers can rely on. + +--- + +## T08 - Add forge observability and operating evidence requirements + +```task +id: RAILIANCE-WP-0006-T08 +status: todo +priority: medium +state_hub_task_id: "ce2ebe48-052a-4e3e-86aa-441274940078" +``` + +Close the framework gap around observability for the forge layer. + +Define at least: + +- health checks for web, SSH, registry, package, and Actions endpoints; +- log inspection and dashboard expectations; +- storage growth checks for package/blob data; +- alert thresholds or manual inspection commands; +- release-readiness evidence that downstream app deployments can cite; +- where future centralized observability should live if a dedicated repo or + S3/S4 surface is created. + +Done when forge availability and artifact health can be inspected without +manually reconstructing the system. + +--- + +## T09 - Add Railiance Fabric declarations for forge capabilities + +```task +id: RAILIANCE-WP-0006-T09 +status: todo +priority: medium +state_hub_task_id: "fd231acc-fe55-417f-a27b-797e1f520e1d" +``` + +Use `railiance-fabric` to make the new layer visible as a graph contract. + +Declare forge capabilities such as: + +- source hosting; +- Git SSH endpoint; +- container registry; +- Python package registry; +- workflow runner substrate; +- artifact promotion evidence. + +Declare dependencies such as: + +- Kubernetes runtime from `railiance-cluster`; +- database, object storage, and secret services from `railiance-platform`; +- CI/CD templates from `railiance-enablement`; +- app release consumers from `railiance-apps`. + +Done when State Hub or local Fabric tooling can show the new forge layer's +provider and consumer edges without relying only on prose docs. + +--- + +## T10 - Decommission compatibility pointers after migration + +```task +id: RAILIANCE-WP-0006-T10 +status: todo +priority: medium +state_hub_task_id: "5bca2a11-453c-4cd0-b86a-7ed269564dfb" +``` + +After the new repo is operational, clean up transitional references. + +Steps: + +- remove stale Gitea/registry ownership language from `railiance-apps`; +- update docs that point to old file locations; +- archive or supersede workplans that were only about forge ownership in S5; +- ensure State Hub workstreams reference the new repo for forge work; +- run consistency sync for affected repos; +- record a final decision that `railiance-forge` is the source of truth for + forge runtime and artifact-registry operations. + +Done when no active railiance workplan asks operators to modify forge runtime +state from the wrong repo.