diff --git a/README.md b/README.md index 406a825..8575158 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,16 @@ Start with: 5. `workplans/` Current implementation status: active forge extraction. Canonical registry -operation docs, deploy-capable Gitea files, and operator targets live here now. -No live Helm deploy or Kubernetes apply was run as part of the move. +operation docs, runner ownership contracts, deploy-capable Gitea files, and +operator targets live here now. No live Helm deploy or Kubernetes apply was run +as part of the move. + +Key contracts: + +- `docs/initial-operating-contracts.md` +- `docs/ci-runner-actions-gitops-ownership.md` +- `docs/gitea-container-registry.md` +- `docs/gitea-package-registry.md` Useful entry points: diff --git a/SCOPE.md b/SCOPE.md index 94acd96..73ac072 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -32,6 +32,8 @@ The practical contract is: Canonical registry operation docs and read-only forge checks now live here. Deploy-capable Gitea Helm/SOPS/manifests also live here now; `railiance-apps` keeps only transitional compatibility wrappers for old operator entry points. +The runner, Actions, and GitOps ownership contract lives in +`docs/ci-runner-actions-gitops-ownership.md`. --- @@ -174,7 +176,9 @@ Known starting point: 4. Read active files in `workplans/`. 5. For registry operations, read `docs/gitea-container-registry.md` and `docs/gitea-package-registry.md`. -6. For migration context, read +6. For runner, Actions, and GitOps ownership, read + `docs/ci-runner-actions-gitops-ownership.md`. +7. For migration context, read `/home/worsch/railiance-apps/workplans/RAILIANCE-WP-0006-railiance-forge-extraction.md`. --- diff --git a/docs/ci-runner-actions-gitops-ownership.md b/docs/ci-runner-actions-gitops-ownership.md new file mode 100644 index 0000000..f32c0b3 --- /dev/null +++ b/docs/ci-runner-actions-gitops-ownership.md @@ -0,0 +1,171 @@ +# CI Runner, Actions, And GitOps Ownership + +Last reviewed: 2026-06-05 + +Status: contract v1. This document defines ownership and handoffs only; it +does not authorize a live runner deployment, credential change, GitOps controller +change, or Gitea-to-Forgejo cutover. + +## Purpose + +Railiance uses forge-hosted automation to build, test, publish, and verify +workloads. The automation path crosses several repos, so this contract separates +runner substrate, reusable workflow templates, app-specific checks, and GitOps +operation. + +The short version: + +- `railiance-forge` owns the runner substrate and forge automation runtime. +- `railiance-enablement` owns reusable workflow templates and paved paths. +- Source and app repos own their repo-specific workflows and build scripts. +- `railiance-apps` owns S5 app-release checks and deployment evidence. +- Lower layers own the cluster, platform services, and runtime secret custody + that runners consume through approved handoffs. + +## Ownership Matrix + +| Concern | Owner | Contract | +| --- | --- | --- | +| Gitea/Forgejo Actions runner deployment and registration | `railiance-forge` | Defines how runners are installed, registered, upgraded, drained, replaced, and removed. | +| Runner labels, placement, and capacity | `railiance-forge` | Publishes stable capability labels and placement rules. Consumers reference labels, not hostnames. | +| Runner registration tokens and runtime credentials | `railiance-forge` with secret custody from `railiance-platform` | References secret names and approved delivery paths only; no decrypted values or tokenized URLs in Git. | +| Reusable CI/CD and GitOps workflow templates | `railiance-enablement` | Defines generic build, test, publish, scan, promote, and GitOps review patterns that consume forge labels and credentials. | +| App-specific workflows and build scripts | Source repo or app repo | Owns language build details, package metadata, image build definitions, and repo-local test behavior. | +| S5 app-release dry-run checks | `railiance-apps` | Owns checks for app Helm charts, app values, app runbooks, and deployment guardrails. | +| Runner prerequisites for S5 checks | `railiance-forge` plus lower-layer providers | Forge owns runner label and health evidence; cluster/platform own API reachability, CRDs, kubeconfig delivery, and secret custody. | +| ArgoCD and GitOps controller operation | `railiance-cluster` for current addon operation, with patterns from `railiance-enablement` | Forge hosts source and executes checks, but does not own the desired state controller. | +| Artifact publish evidence | `railiance-forge` | Captures source repo, commit SHA, artifact identity, package/image version, runner identity, and publish result. | +| Deployment and smoke evidence | `railiance-apps` | Captures S5 manifest change, server-side dry-run result, deployment result, and app smoke result. | +| Gitea-to-Forgejo automation cutover | `railiance-forge` | Preserves semantic runner labels and evidence contracts while moving the automation runtime. | + +## Runner Label Contract + +Runner labels are the public interface between forge-owned substrate and +workflow consumers. Labels should describe capability and trust level, not the +machine that happens to run the job. + +Recommended label categories: + +- OS/runtime: `linux`, `container-runtime`. +- Build capability: `container-build`, `python-build`, `node-build`. +- Publication capability: `registry-publish`, `package-publish`. +- Cluster access: `cluster-read`, `cluster-dry-run`. +- Release posture: `s5-release-check`, `trusted-secrets`. + +Rules: + +- `railiance-forge` is the only repo that defines and changes the label + contract. +- `railiance-enablement` templates may require labels from this contract. +- Source and app workflows may use labels only when the workflow purpose matches + the capability. +- Labels that imply secrets or cluster access require a named credential path + and a human-reviewed purpose. +- Workflow files should not hard-code runner hostnames, local paths, or + registration-token details. + +## Placement And Secret Access + +Runner placement is a security boundary. Treat a runner with publish credentials +or cluster access as a privileged execution environment. + +- Registry/package publish jobs should run only on runners intended for trusted + publication. +- Server-side manifest dry-run jobs should run only on runners approved for + representative cluster API access. +- General build jobs should not receive cluster credentials or broad package + publication tokens. +- Production-like credentials must be scoped by repository, workflow purpose, + and runner label wherever the forge supports that granularity. +- Runner tokens should rotate when a runner is replaced, when a trust boundary + changes, or during a Gitea-to-Forgejo cutover. +- Documentation may reference secret names, SOPS files, OpenBao paths, and + Kubernetes Secret names, but must not include live secret values. + +## GitOps Boundary + +Forge automation is not the GitOps control plane. + +- `railiance-forge` hosts source, runs automation, and provides run/publish + evidence. +- `railiance-enablement` defines reusable GitOps workflow patterns, such as + review gates, promotion conventions, and rollback evidence shape. +- `railiance-apps` owns app deployment declarations and S5 release guardrails. +- `railiance-cluster` currently owns ArgoCD addon operation until another + reviewed workplan moves that responsibility. +- `railiance-platform` owns shared runtime services consumed by GitOps-managed + workloads. + +Automation should normally produce evidence and reviewed manifest changes. +Direct runner-driven syncs against a live GitOps controller require a separate +approval path because they couple CI credentials to deployment authority. + +## S5 Server-Side Dry-Run Split + +The current S5 dry-run surface belongs in `railiance-apps`: + +- `.gitea/workflows/manifest-server-dry-run.yaml` +- `make k8s-server-dry-run` +- `tools/k8s-server-dry-run.sh` +- app Helm charts and app values + +Forge-owned prerequisites: + +- a runner label such as `cluster-dry-run` or `s5-release-check`; +- runner health evidence for that label; +- documented placement and trust posture for runners with cluster reachability; +- evidence that the runner can receive approved kubeconfig material without + exposing live values in Git. + +Lower-layer prerequisites: + +- `railiance-cluster` provides a representative API server and installed CRDs. +- `railiance-platform` provides approved secret delivery and shared service + dependencies required by the manifests. + +If a workflow cannot find a runner with the required label or cannot access the +representative cluster, the failure should be reported as a runner/prerequisite +gap, not worked around inside the app chart. + +## Gitea To Forgejo Cutover Path + +The cutover from current Gitea Actions to future Forgejo automation must keep +the consumer contract stable. + +Minimum path: + +1. Inventory current runners, labels, credentials, repository hooks, and + workflows. +2. Define the Forgejo runner equivalent in `railiance-forge`. +3. Preserve semantic labels used by S4 templates and S5 checks unless a reviewed + migration note announces a replacement. +4. Prove a non-production workflow can run on the new runner substrate. +5. Dual-run critical publish and dry-run checks where feasible. +6. Rotate registration tokens and publish credentials during the switchover. +7. Update forge evidence docs with the new runner identity and endpoint. +8. Retire the old Gitea runner only after downstream workflows no longer depend + on it. + +This cutover does not move template ownership into forge and does not move app +release checks out of S5. + +## Minimum Evidence Before Enforcement + +Before a workflow template or S5 check treats a runner label as required, forge +should provide: + +- runner inventory with labels, placement, and trust level; +- credential scope notes by repository/workflow purpose; +- a successful sample job for each privileged label; +- package or image publish evidence for publication labels; +- representative cluster dry-run evidence for cluster-access labels; +- a rollback or disable path for a bad runner registration. + +## Open Follow-Ups + +- WP-0006-T08 should turn runner health and artifact evidence into explicit + observability requirements. +- WP-0006-T09 should declare runner substrate, label contracts, and evidence + edges in Railiance Fabric. +- `RAILIANCE-WP-0005-T05` should document app-side dry-run behavior once forge + runner prerequisites are ready to enforce. diff --git a/docs/initial-operating-contracts.md b/docs/initial-operating-contracts.md index 25760bd..a8954f9 100644 --- a/docs/initial-operating-contracts.md +++ b/docs/initial-operating-contracts.md @@ -56,6 +56,8 @@ leaving live deploy and secret custody changes behind separate review gates. - Runner secret access must be explicit by label, repository, and workflow purpose. Broad package or cluster credentials should not be shared across unrelated jobs. +- The detailed runner, Actions, and GitOps boundary contract lives in + `docs/ci-runner-actions-gitops-ownership.md`. ## Backup And Restore Handoff