--- id: RAILIANCE-WP-0006 type: workplan title: "Extract railiance-forge and formalize forge-layer contracts" domain: railiance repo: railiance-apps status: active owner: codex topic_slug: railiance planning_priority: high created: "2026-06-04" updated: "2026-06-05" 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: done 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: done 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: done 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`. Completed 2026-06-05: canonical registry docs moved to `railiance-forge`, with compatibility pointers left in `railiance-apps`. Deploy-capable Gitea Helm/SOPS/manifests and Makefile deploy/status targets also moved to `railiance-forge` after the review in `/home/worsch/railiance-forge/docs/deploy-capable-gitea-move-review.md`. `railiance-apps` now keeps compatibility wrappers only. No live deploy, SOPS decryption, or Kubernetes apply was run. --- ## T04 - Re-scope `railiance-apps` and `railiance-enablement` ```task id: RAILIANCE-WP-0006-T04 status: done 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. Completed 2026-06-05: `railiance-apps/SCOPE.md` now treats forge as an upstream service and keeps only compatibility wrappers for moved Gitea operations. `railiance-enablement/SCOPE.md` and `railiance-enablement/INTENT.md` now separate reusable S4 workflow templates and paved paths from forge-owned runtime, registries, runner substrate, labels, credentials, and artifact evidence. --- ## T05 - Define artifact lifecycle, retention, and provenance policy ```task id: RAILIANCE-WP-0006-T05 status: done 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. Completed on 2026-06-05 in `/home/worsch/railiance-forge/docs/initial-operating-contracts.md`. --- ## T06 - Define CI runner, Actions, and GitOps ownership ```task id: RAILIANCE-WP-0006-T06 status: done 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. Completed 2026-06-05: the detailed ownership contract now lives in `/home/worsch/railiance-forge/docs/ci-runner-actions-gitops-ownership.md`. It defines runner deployment and credential ownership, reusable template ownership, app-specific workflow ownership, label and placement rules, secret access constraints, the Gitea-to-Forgejo automation cutover path, GitOps controller boundaries, and the split between S5 server-side dry-run checks and forge-owned runner prerequisites. `railiance-apps` and `railiance-enablement` now point at that contract from their scope/intent docs. --- ## T07 - Define backup, restore, and secret handoff contracts ```task id: RAILIANCE-WP-0006-T07 status: done 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. Completed 2026-06-05: the detailed handoff contract now lives in `/home/worsch/railiance-forge/docs/backup-restore-secret-handoff.md`. It defines forge asset inventory, database/package blob restore gates, railiance-platform handoffs for CNPG, object storage, OpenBao, and runtime secret delivery, allowed versus forbidden operator references, SOPS/age bootstrap boundaries, and how S5 apps cite forge artifact restore evidence without owning registry credentials or package backup procedures. --- ## T08 - Add forge observability and operating evidence requirements ```task id: RAILIANCE-WP-0006-T08 status: done 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. Completed 2026-06-05: the detailed observability and operating evidence contract now lives in `/home/worsch/railiance-forge/docs/observability-operating-evidence.md`. It defines read-only health checks for web/API, Git SSH, OCI registry, Python package registry, Actions/runner, database, logs, and package storage; manual storage thresholds and intervention rules; release-readiness evidence that S5 app deployments can cite; and the future split between forge-owned signal definitions, platform-owned durable metrics/log storage, enablement templates, and a possible future observability repo. --- ## T09 - Add Railiance Fabric declarations for forge capabilities ```task id: RAILIANCE-WP-0006-T09 status: done 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. Completed 2026-06-05: `railiance-fabric` now declares the forge layer as a graph contract with source hosting, Git SSH, OCI registry, Python package registry, workflow runner substrate, and artifact promotion evidence capabilities. It also declares forge dependencies on Railiance Kubernetes, CNPG PostgreSQL, OpenBao runtime secrets, and planned object storage, plus S5 and S4 consumer edges from `railiance-apps` and `railiance-enablement` to forge capabilities. The S4 template relationship is modeled as enablement consuming forge runner substrate, not forge depending on templates, to avoid a false cycle. Validation passed with `0 error(s), 0 warning(s)`. --- ## 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.