- Prefer ASCII unless the file already uses Unicode or a Unicode character is necessary.
- Do not introduce new tools, frameworks, or abstractions unless the repo already uses them.
- Keep diffs minimal and avoid unrelated cleanup.
### Terraform / HCL
- Use 2-space indentation.
- Keep `terraform {}` blocks first, then providers, locals, variables, resources, and outputs in a logical order.
- Name variables, locals, and resources in `snake_case`.
- Keep descriptions on variables and outputs.
- Mark sensitive values with `sensitive = true`.
- Use aligned `=` formatting when practical; run `terraform fmt` instead of hand-formatting.
- Prefer explicit `depends_on` only when required.
- Keep logic in `locals` if it is reused or non-trivial.
### Ansible / YAML
- Use 2-space YAML indentation.
- Use descriptive task names in sentence case (e.g. `Install k3s server`).
- Keep tasks idempotent; use `changed_when: false` and `failed_when: false` for probes and checks.
- Use `command`/`shell` only when a dedicated module is not a better fit.
- Use `shell` only when you need pipes, redirection, heredocs, or shell expansion.
- Prefer `when` guards and `default(...)` filters over duplicating tasks.
- Keep role names and file names kebab-case; keep variables snake_case.
- For multi-line shell snippets in workflows or tasks, use `set -e` or `set -euo pipefail` when the command sequence should fail fast.
### Kubernetes / Flux YAML
- Keep one Kubernetes object per file unless the repo already groups a small set of tightly related objects.
- Use kebab-case filenames that match the repo pattern (`helmrelease-*.yaml`, `kustomization-*.yaml`, `*-externalsecret.yaml`).
- Keep addon manifests under `infrastructure/addons/<addon>/` with a nested `kustomization.yaml`.
- Keep Flux graph objects in `clusters/prod/flux-system/`.
- Quote strings that contain `:`, `*`, cron expressions, or shell-sensitive characters.
- Preserve existing labels/annotations unless the change specifically needs them.
### Python
- Follow PEP 8 style and keep imports ordered: stdlib, third-party, local.
- Use `snake_case` for functions and variables.
- Keep scripts small and explicit; exit non-zero on failure.
- Prefer clear subprocess error handling over silent failures.
## Editing Practices
- Read the target file and adjacent patterns before editing.
- Preserve user changes; do not overwrite unrelated diffs.
- Prefer `apply_patch` for small single-file edits.
- Use scripting only when it is cleaner than repeated manual edits.
- Keep comments minimal and only add them for non-obvious logic.
## Secrets / Security
- Never commit tokens, passwords, kubeconfigs, private keys, or generated secrets.
- Use Gitea secrets, Doppler, or External Secrets for runtime secrets.
- Avoid printing secret values in logs, comments, or commit messages.
- If you must inspect a secret locally, only verify shape/length or compare values indirectly.
## Workflow Expectations
- Read the target file and nearby patterns before editing.
- Check `git status` before and after your changes.
- Run the narrowest relevant validation command after edits.
- If you make a live-cluster workaround, also update the declarative manifests so Flux can own it.
- Do not overwrite user changes you did not make.
- If a change spans Terraform + Ansible + Flux, update and verify each layer separately.
## CI / Workflow Notes
- CI currently uses `.gitea/workflows/deploy.yml`, `.gitea/workflows/destroy.yml`, and `.gitea/workflows/dashboards.yml` as the canonical automation references.
- The workflows run `terraform fmt -check -recursive`, `terraform validate`, Terraform plan/apply, Ansible bootstrap, and targeted Flux bootstrap steps.
- If you change workflow behavior, keep the repo docs and the workflow commands in sync.
## Cursor / Copilot Rules
- No `.cursor/rules/`, `.cursorrules`, or `.github/copilot-instructions.md` files were present when this file was created.
- If those files are added later, mirror their guidance here and treat them as authoritative.