Naming Rules
Overview
In Clean Architecture, domain and usecase layers should not contain technology-specific implementation names.
For example, symbols like AwsClient or RedisQueue inside a usecase violate layer responsibilities.
mille’s naming convention check lets you define forbidden keywords per layer, scanning file names, symbol names, variable names, comments, and string literals.
[[layers]] Naming Options
| Key | Default | Description |
|---|---|---|
name_deny | [] | Forbidden keywords (case-insensitive, partial match) |
name_allow | [] | Substrings stripped before name_deny check (suppresses false positives) |
name_targets | ["file", "symbol", "variable", "comment", "string_literal"] | Which targets to check. Defaults to all |
name_deny_ignore | [] | Glob patterns for files excluded from naming checks |
Basic Example
[[layers]]name = "domain"paths = ["src/domain/**"]dependency_mode = "opt-in"allow = []external_mode = "opt-in"external_allow = ["serde"]
# Flag infrastructure-specific technology names in the domain layername_deny = ["aws", "gcp", "azure", "redis", "kafka", "mysql", "postgres"]Matching Rules
- Case-insensitive:
AWS=aws=Aws - Partial match:
ManageGcpResourcematchesgcp - First match only: one violation reported per name per layer
name_allow — Suppressing False Positives
Partial matching can cause unintended matches:
"ImportCategory" → matches "go" (because "cate_go_ry" contains "go")Register substrings in name_allow to strip them before checking:
name_deny = ["go", "aws"]name_allow = ["category", "algorithm", "cargo"]When checking ImportCategory, "category" is stripped first → "import" remains → no match for "go".
name_targets — Narrowing Check Scope
By default, all 5 target types are checked. You can narrow the scope:
# Only check symbol and file names (allow comments and variables)name_targets = ["file", "symbol"]| Target | What is checked |
|---|---|
file | File basename (without extension) |
symbol | Function, class, struct, enum, trait, interface, type alias names |
variable | Variable, const, let, static declaration names |
comment | Inline comment content |
string_literal | String literal content |
name_deny_ignore — Excluding Specific Files
Exclude files from naming checks using glob patterns (e.g., test files):
name_deny = ["aws", "gcp"]name_deny_ignore = ["**/test_*.rs", "tests/**", "**/*_test.go"]Severity
The default severity for naming violations is "error". For gradual adoption, set it to "warning":
[severity]naming_violation = "warning"See Severity for details.
Supported Languages
All 8 languages (Rust, TypeScript/JavaScript, Python, Go, Java, Kotlin, PHP, C) support all targets: symbols, variables, comments, string literals, and file names.
How to Fix Violations
When a naming violation is detected, the recommended fix is architectural — not just renaming:
- Abstraction: Define a
MessageQueuetrait in domain, implementRedisQueuein infrastructure - Dependency Injection: Wire concrete implementations in the main layer
- Move to infrastructure: Relocate technology-specific logic to the infrastructure layer
// ❌ Technology name leaks into domainstruct RedisUserRepository { ... }
// ✅ Domain only defines abstract interfacestrait UserRepository { ... }// Infrastructure provides the implementationstruct RedisUserRepository { ... }