GloriousFlywheel Deployment Authority Execution Plan 2026-04-15

GloriousFlywheel Deployment Authority Execution Plan 2026-04-15

Snapshot date: 2026-04-15

Purpose

Turn the deployment-authority decision originally captured in #169 and TIN-128 into a concrete edit sequence.

This document is intentionally narrow. It covers only the execution path needed to move GloriousFlywheel off its mixed GitLab-state plus Civo-bootstrap model without reopening the broader cache, FlakeHub, or runner-topology discussions.

Companion note:

Historical note:

  • GitHub issue #169 closed on 2026-04-16
  • this execution plan remains the canonical repo-local sequencing note
  • live GitHub rollout owner is now #208

Status

Phase 1 completed in-repo on 2026-04-15 for the documentation and example surfaces:

  • docs/infrastructure/quick-start.md
  • config/organization.example.yaml
  • tofu/stacks/arc-runners/terraform.tfvars.example
  • tofu/stacks/attic/terraform.tfvars.example
  • tofu/stacks/runner-dashboard/terraform.tfvars.example
  • tofu/stacks/gitlab-runners/terraform.tfvars.example

Result:

  • the primary onboarding and example surfaces now describe the target local-first kubeconfig contract
  • GitLab HTTP backend init and GitLab runner-manager paths are explicitly labeled as legacy-current compatibility where they still appear
  • the next execution slice should start with Justfile, not with more operator copy cleanup

Phase 2 completed in-repo on 2026-04-15 for the local operator entry surfaces:

  • Justfile
  • docs/reference/justfile-commands.md
  • docs/reference/environment-variables.md
  • .env.example
  • docs/infrastructure/quick-start.md

Result:

  • just tofu-init <stack> no longer presents GitLab HTTP state as the primary operator path
  • the Justfile now supports a generic backend-init contract through TOFU_BACKEND_CONFIG_DIR, TOFU_BACKEND_CONFIG_FILE, or TF_HTTP_*
  • the repo now includes config/backend.http.example.hcl as the concrete example for per-stack backend config files
  • the explicit legacy path is now just tofu-init-gitlab-legacy <stack>
  • the next execution slice should start with workflow authority and backend files, not with more local init cleanup

Phase 3 partially completed in-repo on 2026-04-15 for the workflow authority surface:

  • .github/workflows/deploy-arc-runners.yml
  • tofu/stacks/arc-runners/dev-policy.tfvars
  • tofu/stacks/arc-runners/dev-extra-runner-sets.tfvars
  • tofu/stacks/arc-runners/legacy-civo.tfvars
  • tofu/stacks/arc-runners/terraform.tfvars.example

Result:

  • the GitHub Actions deployment path is now explicitly a compatibility workflow
  • it now prefers explicit KUBECONFIG_B64, KUBE_CONTEXT, and TOFU_BACKEND_CONFIG inputs when they are present
  • it now consumes committed dev ARC policy from dev-policy.tfvars instead of treating legacy-civo.tfvars as the primary workflow policy source
  • extra runner-set policy is now split into the additive dev-extra-runner-sets.tfvars surface
  • the workflow now also supports org-specific additive or overriding policy through the TOFU_EXTRA_POLICY_TFVARS secret
  • automatic main-branch apply behavior was removed; legacy apply is now manual via workflow_dispatch
  • the repo still needs one real non-legacy backend authority and a non-legacy CI environment contract for cluster-access inputs to fully converge with the local path
  • the current CI-side input analysis now lives in docs/research/gloriousflywheel-arc-ci-input-contract-2026-04-15.md
  • additive runner-set ownership is now classified explicitly in docs/research/gloriousflywheel-arc-additive-policy-governance-2026-04-15.md

Phase 4 completed in-repo on 2026-04-15 for the stack backend surfaces:

  • tofu/stacks/attic/backend.tf
  • tofu/stacks/arc-runners/backend.tf
  • tofu/stacks/gitlab-runners/backend.tf
  • tofu/stacks/runner-dashboard/backend.tf

Result:

  • stack backend files now describe the current generic HTTP backend contract instead of teaching GitLab project state as the active model
  • each stack now points operators toward just tofu-init <stack> for the preferred init path and just tofu-init-gitlab-legacy <stack> for compatibility
  • the remaining deployment-authority gap is no longer backend comment drift; it is the still-unresolved non-legacy backend authority that local and CI paths should converge on

Phase 5 partially completed in-repo on 2026-04-15 for secondary cleanup:

  • docs/reference/config-reference.md
  • docs/infrastructure/customization-guide.md
  • docs/reference/tofu-modules.md
  • docs/guides/github-app-adoption.md
  • docs/getting-started-guide.md
  • docs/infrastructure/overlay-creation.md
  • docs/ci-cd/overlay-pipelines.md
  • docs/guides/cross-forge-ci.md
  • docs/runners/project-onboarding.md
  • docs/runners/runbook.md
  • docs/runners/troubleshooting.md
  • tofu/stacks/attic/Justfile
  • tofu/stacks/runner-dashboard/Justfile
  • tofu/stacks/gitlab-runners/Justfile

Result:

  • the shared config docs now describe the real organization.yaml shape instead of the old organization.environments schema
  • the ARC adoption guide now uses the local-first kubeconfig path instead of Civo-era apply examples
  • the remaining getting-started, overlay, and cross-forge docs now label GitLab-backed state as compatibility instead of teaching it as the normal GloriousFlywheel operator path
  • the GitLab runner onboarding and operations docs are now explicitly labeled as legacy support surfaces
  • the stack-local Justfile helpers are now explicitly classified as legacy-current direct-stack helpers rather than peer operator entrypoints
  • the root Justfile path is now explicitly documented as taking cluster_context authority from config/organization.yaml
  • per-stack tfvars cluster_context values are now explicitly described as direct-stack or compatibility inputs that should only be kept aligned when those secondary paths are in use
  • the remaining cleanup is lower-signal and should not block backend-authority decisions
  • the remaining deployment-authority gap is now backend authority, not cluster-context ownership

Phase 6 completed in-repo on 2026-04-16 for corrected on-prem cluster truth:

  • docs/infrastructure/quick-start.md
  • docs/getting-started-guide.md
  • docs/infrastructure/cluster-access.md
  • docs/infrastructure/clusters-and-environments.md
  • docs/infrastructure/proxy-and-access.md
  • docs/reference/config-reference.md
  • docs/reference/justfile-commands.md
  • docs/infrastructure/customization-guide.md
  • config/organization.example.yaml
  • scripts/validate-org-config.sh
  • app/scripts/generate-environments.ts

Result:

  • primary docs now model honey as the only physical on-prem cluster target
  • bumble and sting are now documented as node-role placement inputs rather than separate clusters
  • config validation and generated environment metadata now accept honey as a first-class kubeconfig context
  • the remaining blocker is backend authority, not cluster identity or access wording

Phase 7 partially validated live on 2026-04-16 from the local operator machine:

  • ~/.kube/kubeconfig-honey.yaml exists and contains the honey context
  • kubectl --context honey get nodes -o wide succeeds
  • nodes honey, bumble, and sting are all Ready
  • live cache runtime already exists in namespace nix-cache
  • arc-systems, arc-runners, and runner-dashboard do not yet exist live on the cluster

Result:

  • cluster access is now verified, not inferred
  • the next blocker is no longer “can this machine reach honey?”
  • the next blockers are:
    • missing local config/organization.yaml
    • missing local backend config or TF_HTTP_*
    • unresolved backend authority choice
    • namespace or runtime drift between repo examples and live nix-cache naming on honey
  • backend target direction is now explicit: keep the current generic HTTP init path as transitional support, but converge the post-#208 rollout toward environment-owned S3-compatible state on the local honey environment once implemented

Phase 8 partially completed in-repo on 2026-04-16 for root-init and stack example convergence:

  • Justfile
  • docs/reference/justfile-commands.md
  • tofu/stacks/attic/terraform.tfvars.example
  • tofu/stacks/arc-runners/terraform.tfvars.example
  • tofu/stacks/runner-dashboard/terraform.tfvars.example
  • tofu/stacks/gitlab-runners/terraform.tfvars.example
  • docs/research/gloriousflywheel-backend-target-state-2026-04-16.md

Result:

  • root init/help text now says plainly that current TOFU_BACKEND_CONFIG_* and TF_HTTP_* inputs all feed the same transitional HTTP backend family
  • the current Tinyland stack examples now default to the honey context
  • the Attic example now reflects the current nix-cache namespace plus the OpenEBS-on-bumble storage bias
  • cache/Kubernetes shortcut defaults now target the live nix-cache namespace instead of the stale attic-cache helper default
  • the repo now states explicitly that future S3-compatible backend migration will require stack backend.tf changes, not just new init files

Phase 9 partially completed in-repo on 2026-04-16 for local preflight:

  • scripts/tofu-preflight.sh
  • Justfile
  • docs/reference/justfile-commands.md
  • docs/infrastructure/quick-start.md
  • docs/getting-started-guide.md

Result:

  • the repo now has a GloriousFlywheel-side local preflight before tofu init
  • just tofu-preflight <stack> validates:
    • config/organization.yaml
    • resolved cluster context
    • resolved kubeconfig path and local context presence
    • {ENV}.tfvars for the chosen stack
    • the currently configured backend-init path
  • this narrows the remaining blocker again: if preflight passes, the next gap is no longer local operator ambiguity; it is real backend endpoint selection and backend-family migration timing
  • current local execution from this checkout now fails cleanly at the first real blocker: missing config/organization.yaml

Current local validation update from this checkout after local config materialization:

  • local config/organization.yaml now exists and validates against the current honey truth
  • local tofu/stacks/attic/dev.tfvars now exists and matches the current nix-cache plus OpenEBS-on-bumble path
  • just tofu-backend-scaffold attic now creates the expected local backend file under config/backends/
  • just tofu-preflight attic now advances past missing config and missing backend-path failures
  • the current first blocker is now exact: config/backends/attic-dev.hcl still contains example placeholder values and needs a real backend endpoint plus credentials

Current Blocking Surfaces

These files currently define the mixed-era deployment contract.

Backend And Init

  • tofu/stacks/attic/backend.tf
  • tofu/stacks/arc-runners/backend.tf
  • tofu/stacks/gitlab-runners/backend.tf
  • tofu/stacks/runner-dashboard/backend.tf
  • Justfile
  • tofu/stacks/attic/Justfile
  • tofu/stacks/runner-dashboard/Justfile
  • tofu/stacks/gitlab-runners/Justfile

Why they block:

  • all active stacks still declare backend "http"
  • the actual non-legacy backend endpoint and credential authority is still chosen outside the repo at init time
  • the root operator flow still carries an explicit legacy GitLab init path for compatibility until a non-legacy backend authority is fully adopted
  • several stack-local helper surfaces still hard-code GitLab project state even after the root Justfile moved to a generic HTTP contract

Current Repo-Local Rollout Note

  • docs/research/gloriousflywheel-honey-onprem-rollout-2026-04-16.md

Why it matters:

  • it is the authoritative repo-local statement that honey is the only physical cluster target
  • it keeps node placement on honey, bumble, and sting explicit while the backend decision remains open

Workflow Authority

  • .github/workflows/deploy-arc-runners.yml
  • tofu/stacks/arc-runners/legacy-civo.tfvars

Why they still matter:

  • the workflow is now explicitly legacy-current and manual-only, but it still obtains kubeconfig through Civo CLI
  • it still initializes GitLab HTTP backend state directly
  • it still selects a legacy Civo-shaped tfvars file instead of the same {env}.tfvars path used by the local operator model

Secondary Legacy Teaching Surfaces

  • docs/getting-started-guide.md
  • docs/infrastructure/overlay-creation.md
  • docs/ci-cd/overlay-pipelines.md
  • docs/guides/cross-forge-ci.md

Why they still matter:

  • they can reintroduce GitLab-state assumptions even after the primary docs and root operator path are corrected
  • they should not block the backend decision itself, but they do need to be cleaned up before the slice can be called complete

Execution Rules

  1. Do not change stack backends without simultaneously updating the operator entrypoints that initialize them.
  2. Do not keep a CI deployment path that uses a different authority model from the documented local path.
  3. Mark GitLab-state and Civo-specific surfaces as legacy-current until the new path is implemented.
  4. Keep gitlab-runners explicitly classified as legacy support during the transition.
  5. Do not model bumble or sting as separate clusters anywhere in the primary operator path.

Phase Plan

Phase 1: Introduce The New Operator Contract In Docs And Examples

Goal:

  • make the target model explicit before refactoring runtime surfaces

Files:

  • docs/infrastructure/quick-start.md
  • config/organization.example.yaml
  • tofu/stacks/arc-runners/terraform.tfvars.example
  • tofu/stacks/attic/terraform.tfvars.example
  • tofu/stacks/runner-dashboard/terraform.tfvars.example

Edits:

  • rewrite quick-start initialization so GitLab HTTP state is clearly labeled as current legacy behavior, not the target operator contract
  • document the target operator inputs as: environment tfvars, explicit kubeconfig or ambient KUBECONFIG, and a backend owned by the deployment environment
  • replace primary cluster-context examples that imply GitLab agent or Civo-only operation
  • keep legacy examples only where they are explicitly marked as compatibility paths

Why first:

  • this reduces the chance of refactoring code into an undocumented or ambiguous model
  • it also provides the text that later code and workflow changes should match

Exit criteria:

  • a new operator can tell which deployment path is legacy-current and which is the intended local-first path

Phase 2: Refactor Local Operator Entry Points

Goal:

  • make local execution stop assuming GitLab HTTP state as the default init path

Files:

  • Justfile
  • docs/reference/justfile-commands.md

Edits:

  • split backend initialization concerns from plan and apply flows
  • remove TF_HTTP_PASSWORD as the default requirement presented to operators
  • add one explicit path for the target backend contract and one clearly labeled legacy path if temporary compatibility is required
  • keep cluster_context and kubeconfig handling aligned with the provider model already present in the stacks

Why second:

  • the root Justfile is the actual operator entry surface
  • backend refactors are not safely testable if the local init contract is still anchored to GitLab-specific environment variables

Exit criteria:

  • just tofu-init <stack> no longer implies GitLab backend as the primary path
  • docs and command output agree on the same credentials and inputs

Phase 3: Reclassify Or Replace CI Deploy Authority

Goal:

  • stop GitHub Actions from acting as a separate authority model

Files:

  • .github/workflows/deploy-arc-runners.yml
  • tofu/stacks/arc-runners/legacy-civo.tfvars
  • optionally .github/workflows/validate.yml if deploy responsibilities need to move

Edits:

  • remove or demote the current Civo-bootstrap plus GitLab-backend workflow path
  • if CI deployment remains, make it consume the same backend contract and kubeconfig model as the local operator path
  • replace civo.tfvars as the primary workflow input with the same environment-oriented tfvars naming used elsewhere, or explicitly mark the compatibility file as legacy

Why third:

  • local operator truth should be established before CI automation is allowed to mirror it
  • otherwise the repo will keep two competing deployment contracts

Exit criteria:

  • no primary deployment workflow depends on Civo CLI bootstrap
  • CI deploy automation no longer hard-codes a GitLab backend model that local operators are supposed to abandon

Phase 4: Rewrite Stack Backend Surfaces

Goal:

  • make stack-level backend declarations match the new authority model

Files:

  • tofu/stacks/attic/backend.tf
  • tofu/stacks/arc-runners/backend.tf
  • tofu/stacks/gitlab-runners/backend.tf
  • tofu/stacks/runner-dashboard/backend.tf

Edits:

  • replace GitLab-managed backend comments and examples with the chosen target backend contract
  • keep any temporary legacy instructions clearly bounded and labeled
  • ensure each stack follows the same backend authority family

Why fourth:

  • the backend files should be the final codification of the new decision, not the first place it appears
  • changing them earlier would create drift if the operator contract is still not implemented upstream in Justfile and docs

Exit criteria:

  • stack backend files no longer describe GitLab HTTP state as the primary model
  • all active stacks describe the same backend family and initialization pattern

Phase 5: Secondary Cleanup And Legacy Labeling

Goal:

  • remove remaining mixed-era wording after the primary path is consistent

Files:

  • docs/reference/config-reference.md
  • docs/reference/tofu-modules.md
  • docs/runners/project-onboarding.md
  • docs/runners/runbook.md
  • docs/runners/troubleshooting.md
  • any remaining stack examples or helper scripts that mention GitLab state or Civo bootstrap

Edits:

  • update references to match the final contract
  • label gitlab-runners and any GitLab-state instructions as legacy support where still retained

Exit criteria:

  • no primary operator surface contradicts the new deployment-authority model

File Ownership Map

#169 / TIN-128

Primary files:

  • tofu/stacks/*/backend.tf
  • Justfile
  • .github/workflows/deploy-arc-runners.yml
  • docs/infrastructure/quick-start.md
  • config/organization.example.yaml
  • tofu/stacks/arc-runners/legacy-civo.tfvars

Adjacent But Parallel

  • #167 / TIN-125: cache and publication contract
  • #171 / TIN-127: builder and clean-derivation contract
  • #170 / TIN-126: ARC topology and lifecycle

These can keep moving, but they should stay out of backend-authority files while #169 is active.

  1. docs/infrastructure/quick-start.md
  2. config/organization.example.yaml plus stack tfvars examples
  3. Justfile
  4. .github/workflows/deploy-arc-runners.yml
  5. tofu/stacks/*/backend.tf
  6. secondary sweep docs

Verification Plan

After each phase:

  • run git diff --check
  • search for residual TF_HTTP_PASSWORD, gitlab.com/api/v4/projects/.*/terraform/state, civo kubernetes config, and legacy-civo.tfvars references in primary surfaces
  • verify local docs and workflow docs describe the same kubeconfig and backend inputs

Before claiming implementation complete:

  • confirm there is only one primary deployment contract across local docs, Justfile, workflow automation, and stack backend files

Non-Goals For This Slice

  • choosing the final FlakeHub or clean-derivation publication policy
  • redesigning ARC pool topology
  • redesigning dashboard auth
  • deleting all GitLab support surfaces immediately

Those remain separate lanes after deployment authority is grounded.

GloriousFlywheel