# Agent Guide This file defines repository-wide rules for agents working on `self-hosted-services`. Follow it for every task in this repository. ## 1. How to Use This Guide The requirement words in this document have consistent meanings: - **MUST** and **MUST NOT** are mandatory. - **SHOULD** and **SHOULD NOT** are the default. Deviate only when the task requires it, and explain why. - **MAY** is optional. When rules appear to conflict, apply them in this order: 1. Protect production systems, credentials, and user data. 2. Follow the user's explicit scope and approvals. 3. Preserve tenant isolation and repository architecture. 4. Follow the implementation and validation standards below. If a higher-priority rule prevents a lower-priority requirement, stop at the safe boundary and report what remains. ### 1.1 Scoped Guides Read the nearest scoped guide before changing files in these areas: - [`charts/services/AGENTS.md`](charts/services/AGENTS.md): Helm, Kubernetes, application integration, secrets, ingress, and observability. - [`roles/AGENTS.md`](roles/AGENTS.md): Ansible role design and validation. - [`scripts/AGENTS.md`](scripts/AGENTS.md): Python and CI-oriented scripting. Scoped guides supplement this file. Repository-wide safety and workflow rules continue to apply; this root guide takes precedence if instructions conflict. ## 2. Safety Boundaries ### 2.1 Production Commands - You MUST NOT run `kubectl`, `ansible-playbook`, or any `helm` command that connects to or mutates a cluster without explicit user permission. These commands can affect live infrastructure. - You MAY run local, non-mutating Helm validation commands without explicit permission, including `helm lint`, `helm template`, and `helm unittest`. - Permission to inspect or edit the repository does not imply permission to deploy, reconcile, or mutate a cluster. ### 2.2 Sensitive Files and Secrets - You MUST NOT read or modify any file whose name contains `inventory`, such as `inventory_home.yml`. These files contain sensitive production details and credentials. - You MUST NOT commit real secrets. - You MAY commit clearly identified dummy or template secrets used only for tests, such as `molecule/default/sample_secrets.yml`. ## 3. Working in the Repository ### 3.1 Scope and Git Workflow - You MUST use a dedicated git worktree for each new task by default. If the user explicitly asks you to make the change directly on a branch, do not create or use a worktree. The user may override the worktree default at any time. - You MUST keep each change focused on one feature or fix. Do not include opportunistic cleanup or unrelated edits. - If a refactor is necessary, perform it as a separate step and commit before implementing the feature that depends on it. - Preserve existing user changes and do not stage or commit them as part of your work. ### 3.2 Commit Messages - All commits MUST follow the Conventional Commits format: `[optional scope]: `. - The type MUST be one of `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `style`, or `test`. - Every commit MUST include a body that explains why the change is needed. - Breaking changes MUST use `!` after the type or scope and include a `BREAKING CHANGE:` footer that describes the migration required. ### 3.3 Continuous Improvement When a task reveals a durable repository pattern or pitfall, you SHOULD update the applicable guide. Unless guide maintenance is part of the requested task, leave that change unstaged and uncommitted for user review. ## 4. Project Architecture ### 4.1 Opinionated Configuration - You SHOULD prefer a robust, opinionated setup over a broadly configurable framework. - You MUST keep configuration knobs to a minimum, especially in `charts/services/values.yaml`. - All applications MUST be part of the `charts/services` chart. ### 4.2 Multitenancy - Only the primary tenant (`.Values.primaryTenant: true`) MAY deploy system charts and core infrastructure. - You MUST deploy application charts and isolated service instances, including `PostgresCluster` and MinIO `tenant` resources, once per tenant. ### 4.3 Namespace Placement Use the following rules when choosing a namespace for a resource or Helm release: - **`kube-system`:** Use only for Kubernetes components, node-level daemons, and cluster-wide add-ons that are part of the cluster itself. This includes cert-manager, trust-manager, External Secrets, device plugins, node feature detection, node problem detection, descheduler, and similar system components. Do not place shared application services here. - **`platform`:** Use for shared services and operators owned by the primary tenant. This includes ingress, GitOps, observability, backup, security, shared storage, and operators that manage shared or tenant resources, such as the MinIO Operator and PGO. The `platform` namespace is shared by multiple tenants, but MUST be created and managed only by the primary tenant. - **Application namespace:** Use `.Values.applicationsNamespace` for tenant-owned workloads and isolated service instances. This includes application charts, Redis, MinIO `tenant` resources, `PostgresCluster` resources, and their Secrets, ConfigMaps, Services, and monitoring objects. These resources MUST remain isolated per tenant. When a HelmChart deploys a platform service, its `metadata.namespace` and `spec.targetNamespace` MUST both be `platform`. When it deploys a system component, both MUST normally be `kube-system`. Keep the HelmChart custom resource in the same namespace as the release unless the controller requires another placement and the reason is documented. A controller's namespace and the namespace of the resources it manages are separate decisions. Before moving a resource between namespaces, update all namespaced support objects and references, including Secrets, ConfigMaps, ServiceAccounts, monitoring objects, service DNS names, and Traefik middleware names. Kubernetes objects cannot be renamed between namespaces. ### 4.4 Shared Services You MUST use the following platform services whenever the application supports them, except where a scoped guide gives more specific implementation details: - **Database:** PostgreSQL, not an embedded database such as SQLite. - **Cache and sessions:** Redis. - **Object storage:** MinIO through its S3-compatible API. - **Multimedia PVCs:** MUST NEVER be backed up by Velero. - **SSO:** Authentik, preferably through OAuth/OIDC. - **Outbound email:** the shared `smtp` secret, backed by AWS SES by default. - **Metrics:** you SHOULD enable metrics when supported. - **VPN routing:** route all pod egress through the central `gluetun` service. ## 5. Validation Use `.woodpecker/lint.yaml` as the source of truth for linting and validation. Do not duplicate its complete tool list in agent guides. Follow any additional validation requirements in the applicable scoped guide. ## 6. Definition of Done A task is complete only when: - The requested implementation is complete and follows every applicable agent guide. - Targeted validation for the changed behavior passes. - All additional validation required by the applicable scoped guide passes, or each skipped check is reported with its reason. - The final diff has been reviewed for unrelated changes. - The diff contains no real secrets, sensitive inventory data, or unexpected generated files. - No production-affecting command was run without explicit user approval.