# Module Import Boundaries ## Intent https://github.com/external-secrets/external-secrets/issues/5494 introduced the split of our go module into multiple go modules. The module structure has been exercised and can now be moved to a design document. ## Principles - Packages in `apis` are for CRDs and a limited set of interfaces. They may import the standard library, packages in the `apis` module and an explicit allowlist of API dependencies (for example, k8s.io modules). - Packages in `runtime` are common utilities. They contain shared code (validation utilities, webhook helpers, metrics/logging tooling, ...). They may import the standard library, packages in `apis` or `runtime`, and an explicit allowlist of runtime dependencies. As the dependencies are included in provider modules, the addition of a module into a `runtime` package needs to be carefully analysed. - Packages in `pkg` are for the core orchestration. It's where the controllers and binary reside. They can depend on `apis` and `runtime`. - Packages in `e2e` are for the e2e testing, and can require any of the above packages. They are built in isolation, so they should not leak dependencies everywhere. - Transitive dependencies are not evaluated: If some module imports the whole world, then we will have to deal with it. ## Enforcement In a first stage, we use code reviews to highlight discrepancies and preserve the module layout expressed above. In a second stage, we enable golangci-lint's existing `depguard` linter for `apis` and `runtime`; `pkg` and `e2e` remain review-only. It defines strict rules selected by path like `**/apis/**/*.go` or `**/runtime/**/*.go`. Each rule allows `$gostd`, the module's own package prefix, and the package prefixes belonging to its allowed current direct dependencies. Depguard analyzes import declarations rather than the module graph, so it checks only direct imports. The file globs include tests. An import such as an AWS or Oracle SDK from a runtime test therefore fails the existing `make lint` and `make reviewable` gates without constraining dependencies loaded transitively by an allowed package. The existing `go mod tidy` and `make check-diff` flow remains responsible for removing stale `go.mod` requirements. No new command, dependency, or CI job is needed.