Scrubbed extract of
HomeLab-Infrastructure/ADR/ADR-024-Repo-Split-Three-Repos.md— cited by the Chronicle (04-the-proving-ground). Redactions: phone / service detail / secrets / clearance / personal / internal hosts.
category: Work project: HomeLab-Infrastructure status: Accepted created: 2026-06-29 amends:
- “[[ADR-004-Repo-Layout-Separation-Of-Concerns]]” tags:
- adr
- layout
- separation-of-concerns
- infrastructure
- images
- deployments
- repo-split
ADR-024: Repo Split — Three Repos (DockerContainers → + homelab-stacks + homelab-infra)
Status
Accepted — 2026-06-29. Amends [[ADR-004-Repo-Layout-Separation-Of-Concerns]]: ADR-004’s
infrastructure/ + images/ + deployments/ boundary stands, but is now realized as three
separate Gitea repos rather than three directories inside one repo. Executed the same day.
Context
homelab/DockerContainers was meant to hold base images + CI runner images. It accreted 20+ Compose
stacks (hosts/), OpenTofu/Terraform IaC (infrastructure/, legacy root proxmox/), 17 deploy
workflows, n8n workflows, and k3s/Helm/Argo CD scaffolding (ansible/, charts/, gitops/). ADR-004
already named the three concerns and split them into directories, but a single repo still means:
- One release cadence for things that change at very different rates (stacks weekly; OpenTofu state monthly-or-less; base/runner images rarely).
- One access boundary — routine stack deploys and operator-gated infra provisioning share a repo.
- Blast radius conflation — a CI change to image builds sits in the same history as a compose tweak.
This blocked per-image-runner-versioning and the ADR-023 runbook→keycloak-idp-skill fold, both of
which were explicitly deferred “until the DockerContainers repo split lands.”
The original split task proposed numbering this ADR “023”, but 023 was consumed by the Keycloak⇄OpenBao integration; this decision is therefore ADR-024.
Decision
Split into three repos along ADR-004’s boundary (Option A of the split task):
| Repo | Owns | Cadence / access |
|---|---|---|
homelab/DockerContainers (kept) |
base-images/, runners/, verification/, root CA, image-build + self-verify CI |
rare; build-only |
homelab/homelab-stacks (new, public) |
hosts/, observability/, n8n-workflows/, ansible/, charts/, gitops/, per-stack certs, deploy/k3s/helm/realm workflows |
weekly; routine deploy |
homelab/homelab-infra (new, private) |
infrastructure/{cloudflare,proxmox,power,scripts,state-backups}/, legacy proxmox/, iac-validate.yml |
infrequent; operator-gated |
- History preserved via
git filter-repo(per-path) into each new repo; migrated paths removed from DockerContainers but kept in its history for recoverability. - Runner images stay in DockerContainers; the
gitea-runnerstack (with its socket-share threat model) lives in homelab-stacks.homelab-infra/iac-validate.ymlconsumes thehomelab-runner-build-iacimage from the DockerContainers registry. All threeuses: homelab/shared-workflows@v1. homelab-infrais private (holds IaC for the external surface, age-encrypted state); the other two are public.- Per-repo docs: each new repo carries a trimmed
CLAUDE.md+README.mdscoped to that repo;AGENTS.md/codex.md/.claude//.cursorrulesare not propagated to the new repos.
Corrections made during execution (vs. the split task’s draft commands)
- The task’s homelab-stacks
filter-repocommand erroneously included--path infrastructure/ --path proxmox/(would duplicate IaC into stacks). Removed — IaC goes only to homelab-infra. - ~7 files the task tables omitted were routed:
helm-lint.yml,keycloak-realm-validate.yml→ homelab-stacks;.gitea/scripts/post-webhook.sh→ homelab-stacks;scripts/release/(chart-version bump) → homelab-stacks;VERSIONING.mdstays in DockerContainers;.codesight/not migrated (regenerated per repo). - The legacy root
proxmox/module is internally broken (outputs.tfreferences the old Telmateproxmox_lxcname whilemain.tfuses bpgproxmox_virtual_environment_container). Carried into homelab-infra as-is; the fold-into-infrastructure/proxmox/+ delete is tracked as Phase 2a IaC work, not part of the split.
Consequences
Positive: cadence/access boundaries are real; image CI no longer churns with stack edits; the
per-image-runner-versioning follow-up unblocks; IaC lives in a private repo with its own validation
gate.
Negative / costs: more cross-repo references (CI uses:, the build-iac runner image dependency);
two new vault project surfaces to keep current; shared docs lightly duplicated. The legacy proxmox
module reconcile is now homelab-infra’s debt.
Follow-ups: Phase 2a reconcile + tofu validate blocking-green (homelab-infra); fold the ADR-023
client-integration runbook into the keycloak-idp skill; per-image-runner-versioning (DockerContainers).
Related
- [[ADR-004-Repo-Layout-Separation-Of-Concerns]] — in-repo three-way split this amends
- [[ADR-022-K3s-As-Homelab-Workload-Runtime]] — k3s/Helm/Argo path now homed in homelab-stacks
- [[ADR-005-Immutable-Image-Tag-Deployments]] — image tag conventions (DockerContainers + VERSIONING.md)
Tasks/Work/dockercontainers-repo-split-plan.md— the execution task