Configure domains
Domains are named groups of source paths with their own coverage minimums. They work the same way for all sorts of languages — Python, TypeScript, Java, Rust, Go, and the rest. They are not language constructs and do not wrap packages, modules, or crates — they match directories and files in your repo so auth can require 90% while utilities stay at 60%.
Domain Configuration
Section titled “Domain Configuration”Each domain has a name, match patterns, and a minimum coverage threshold:
policy: domains: - name: core match: ["src/core/**"] min: 85 - name: api match: ["src/api/**"] min: 80policy: domains: - name: core match: ["./internal/core/..."] min: 85 - name: api match: ["./internal/api/..."] min: 80Match Patterns
Section titled “Match Patterns”match accepts either dialect. coverctl picks the resolver from the pattern shape and the project’s language:
| Dialect | When to use | Examples |
|---|---|---|
| Path globs | Python, JavaScript/TypeScript, Rust, Java, C#, and most non-Go trees | src/api/**, lib/**, app/services/** |
| Go package paths | Go modules (go.mod present) |
./internal/auth/..., ./pkg/utils, ./cmd/... |
Path globs
Section titled “Path globs”| Pattern | Matches |
|---|---|
src/core/** |
Everything under src/core/ |
src/api/** |
Everything under src/api/ |
lib/** |
Everything under lib/ |
src/*/service/** |
service trees one level under src/ |
Go package paths
Section titled “Go package paths”| Pattern | Matches |
|---|---|
./internal/core/... |
All packages under internal/core/ |
./cmd/... |
All packages under cmd/ |
./pkg/utils |
Only the pkg/utils package |
./internal/*/service |
service packages one level deep |
Examples
Section titled “Examples”domains: - name: core match: ["src/core/**"] min: 85
- name: api match: - "src/api/**" - "src/handlers/**" min: 80
- name: utils match: ["src/utils/**"] min: 70domains: - name: core match: ["./internal/core/..."] min: 85
- name: api match: - "./internal/api/..." - "./internal/handlers/..." min: 80
- name: utils match: - "./pkg/utils" - "./pkg/helpers" min: 70Language-specific starter configs (including language: and profile:) are in Quick start.
Excluding Files
Section titled “Excluding Files”Use the exclude field to skip files from coverage analysis:
exclude: - "**/generated/**" - "**/mocks/**" - "**/*_test.go" - "**/testdata/**" - "**/migrations/**"Glob Patterns
Section titled “Glob Patterns”| Pattern | Matches |
|---|---|
**/generated/** |
Any file under a generated directory |
**/*_mock.go |
Any file ending in _mock.go |
src/legacy/* |
Files directly in src/legacy/ |
Auto-Detection
Section titled “Auto-Detection”coverctl can automatically detect domains from your project structure:
# Preview detected domainscoverctl detect --dry-run
# Write configcoverctl detectDetection follows the layout of the detected language, not a single package model:
| Language family | Typical detected match shapes |
|---|---|
| Go | ./internal/..., ./cmd/..., ./pkg/... |
| Python / JS / TS / Rust / … | src/**, src/api/**, lib/**, crate/layout-specific globs |
Go layout heuristics (when go.mod is present)
Section titled “Go layout heuristics (when go.mod is present)”| Directory | Detected Domain |
|---|---|
cmd/ |
CLI entry points |
internal/core/ |
Core business logic |
internal/domain/ |
Domain layer |
internal/application/ |
Application services |
internal/infrastructure/ |
Infrastructure adapters |
internal/api/ |
API layer |
pkg/ |
Public packages |
Directories named generated, mocks, testdata, or vendor are automatically excluded. For other languages, run coverctl detect --dry-run to see the proposed globs for your tree.
Domain Overlap
Section titled “Domain Overlap”When a file matches multiple domains, it’s assigned to the first matching domain. Order your domains from most specific to least specific:
domains: - name: core-critical match: ["src/core/critical/**"] min: 95
- name: core match: ["src/core/**"] min: 85domains: - name: core-critical match: ["./internal/core/critical/..."] min: 95
- name: core match: ["./internal/core/..."] min: 85Code Annotations
Section titled “Code Annotations”With annotations.enabled: true, you can override domain assignment in source comments (language comment syntax varies; Go shown):
// coverctl:domain=criticalpackage validator
func Validate() error { // This file belongs to "critical" domain}Ignoring Files
Section titled “Ignoring Files”// coverctl:ignorepackage generated
// This file is excluded from coverageBest Practices
Section titled “Best Practices”- Start with auto-detection: Use
coverctl detect --dry-runto see suggested domains for your language - Group by criticality: Higher thresholds for core business logic — names are labels, not package wrappers
- Use meaningful names: Domain names appear in reports and agent tool output
- Keep excludes minimal: Only exclude truly non-testable code
- Review overlaps: Check for unintended domain assignments