Clarify app scope and plan forge extraction

This commit is contained in:
2026-06-05 00:56:33 +02:00
parent 179b87e244
commit e0f9a08b1c
4 changed files with 872 additions and 43 deletions

137
INTENT.md Normal file
View File

@@ -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?**

232
SCOPE.md
View File

@@ -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 S1S4 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
- S1S4 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
- S1S4 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 (S1S4) 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.

View File

@@ -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`.

View File

@@ -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.