# Sanctity Rules — `devops-infra-argo-config` > Non-negotiable rules for this repository. Violations are hard stops — not warnings, not suggestions. > > **Audience:** Every agent and human who opens a PR against this repo. > > **Enforcement:** Pre-commit hooks (TruffleHog, CAC validate, Yaak) + branch protection on `main`. A merge to `main` **immediately deploys** — infra apps are auto-sync. --- ## R1: `main` is production A merge to `main` triggers immediate ArgoCD auto-sync across all managed clusters. There is no staging gate between merge and deploy. - No experiments on `main`. - No force-pushes to `main`. - Every PR must pass pre-commit hooks and receive platform-team review before merge. --- ## R2: The incubator ↔ values ↔ generic-chart contract is sacred Each cluster is bootstrapped by exactly three things working together: 1. **Incubator file** (`incubator//.yaml`) — parent ArgoCD Application that points at the generic chart + the cluster's values file. 2. **Values file** (`values//-values.yaml`) — defines `clusterSpec`, `teamSpec`, `argocdSpec`, and the `appSpec[]` list. 3. **Generic chart** (`generic-argo-apps-chart/`) — renders one child ArgoCD Application per `appSpec` entry. Breaking any leg of this triangle breaks the cluster's tooling. The naming conventions in CLAUDE.md are load-bearing — they are identifiers, not cosmetic. --- ## R3: `appSpec` entries must reference existing chart and values in `devops-infra-helm-charts` Every `appSpec[].chartDir` must correspond to a directory under `devops-infra-helm-charts/helm-templates/`. Every `appSpec[].valuesDir` must correspond to a directory under `devops-infra-helm-charts/helm-overrides//`. If either doesn't exist, the ArgoCD Application will fail to render. **Verify before adding:** ```bash # chartDir exists? ls devops-infra-helm-charts/helm-templates// # valuesDir exists? ls devops-infra-helm-charts/helm-overrides///custom-values.yaml ``` --- ## R4: Child Application names are auto-generated — do not invent names The generic chart template generates Application names as: ``` -- ``` Where cluster munging strips: `k8s-`, `prd-`, `int-`, `dev-`, `-ase1`; maps `-ase1c` to `-c`. Example: `keda` on `k8s-central-prd-ase1` becomes `keda-central-prd`. Only use `nameOverride` when: - The auto-generated name would exceed 253 characters (Kubernetes limit). - There is a genuine name collision between two appSpec entries. --- ## R5: `repository.yaml` is automation-owned Owned by `registry-bootstrap`. Direct edits will be overwritten. To change ownership metadata, go to the upstream automation. --- ## R6: Secrets stay out of git No credentials, tokens, API keys, or passwords in any YAML file. The TruffleHog pre-commit hook will block the commit. If a secret is accidentally committed, it must be force-purged from history — this requires platform-team involvement. --- ## R7: `nameOverride` is exceptional, not routine Most PRs should not include `nameOverride`. When reviewing, flag any `nameOverride` that lacks a comment explaining why the auto-generated name was insufficient. --- ## R8: One incubator file per cluster, one values file per cluster The 1:1 mapping between incubator files and values files is structural. Do not create multiple incubator files for the same cluster or share a values file across clusters. --- ## R9: Cluster folder/file names are routing keys The cluster name in the values file (`clusterSpec.destination.name`) must match the incubator file name and the `helm-overrides/` folder name in the sister repo. These names are used by ArgoCD for cluster routing — a mismatch means tools deploy to the wrong cluster or fail silently. --- ## R10: Pre-commit hooks must pass Run `pre-commit run --all-files` before pushing. Never use `--no-verify` to skip hooks. If a hook fails, fix the root cause. The hooks are: TruffleHog (secrets scan), CAC validate (config validation), Yaak (additional linting). --- ## R11: Branch protection trumps everything All changes go via PR with required review. Direct pushes to `main` are blocked at the GitHub org level. No exceptions for "quick fixes" — the blast radius of a bad merge is immediate cluster-wide impact. --- ## R12: AppProject wildcards are dangerous The `sre` and `sec` projects currently allow `*` for source repos and destinations. Widening or modifying AppProject scope requires auditing every Application that references the project. A misconfigured project could allow unauthorized deployments. --- ## How to cite these rules In PR reviews or agent halt messages, cite as: *"Blocked by R3 (SANCTITY_RULES.md) — chartDir must exist in devops-infra-helm-charts before adding appSpec."*