# ADR 0004: Single Argo CD root and stage-gated ApplicationSets Status: accepted Updated: 2026-07-26 Argo CD 설치 후 bootstrap 전용 `gitops-control-plane` AppProject와 단일 root Application을 순서대로 수동 seed합니다. Root는 `gitops/clusters/dev-k3s`를 source로 사용합니다. 이 cluster root가 `gitops/platform/control-plane/argocd`의 AppProject와 ApplicationSet을 소유하고, ApplicationSet이 platform addon/shared service, system, workload Application을 생성합니다. Bootstrap Project는 canonical repository, `argocd` namespace와 AppProject/ApplicationSet kind만 허용합니다. 반복 `kubectl apply`와 category별 root wrapper는 사용하지 않습니다. Routine deployment는 Git merge만으로 시작합니다. 각 ApplicationSet inventory 항목은 다음 계약을 명시합니다. - 고유 이름, AppProject, source, destination namespace - component/cluster/path와 automated reconciliation 허용 여부인 quoted string `autoSync` 새 항목과 외부 준비 조건이 있는 항목은 `autoSync: "false"`로 시작합니다. 현재 bootstrap은 Sealed Secrets와 Vault만 열린 상태에서 시작해 foundation/workloads state와 secret seed, injector, auth-system, database, first-party workload 순서로 별도 PR gate를 엽니다. Template은 `autoSync: "true"`인 항목에만 automated sync, prune, self-heal을 생성합니다. Gate가 닫힌 Application의 수동 sync도 change record와 명시적 operator 판단을 요구합니다. Sync wave는 AppProject(`-10`)를 ApplicationSet(`-5`)보다 먼저 생성합니다. 모든 ApplicationSet은 같은 wave이며 element별 stage field는 없습니다. 서로 다른 generated Application의 readiness는 gate와 runbook이 제어합니다. Workload와 hook은 Vault/DB가 늦게 준비되는 상황을 retry할 수 있고 idempotent해야 합니다. Root는 AppProject와 ApplicationSet만 prune 대상으로 봅니다. Generated Application의 owner는 ApplicationSet이며 `create-update`에서는 element 제거만으로 삭제되지 않습니다. Application/resource 해체는 별도 decommission runbook과 확인 승인을 사용합니다. Shared resource 소유권 충돌은 sync를 실패시킵니다. Sync hook을 사용하는 Application에는 `ApplyOutOfSyncOnly=true`를 사용하지 않습니다.