Skip to content

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

KeyDefaultDescription
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 layer
name_deny = ["aws", "gcp", "azure", "redis", "kafka", "mysql", "postgres"]

Matching Rules

  • Case-insensitive: AWS = aws = Aws
  • Partial match: ManageGcpResource matches gcp
  • 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"]
TargetWhat is checked
fileFile basename (without extension)
symbolFunction, class, struct, enum, trait, interface, type alias names
variableVariable, const, let, static declaration names
commentInline comment content
string_literalString 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:

  1. Abstraction: Define a MessageQueue trait in domain, implement RedisQueue in infrastructure
  2. Dependency Injection: Wire concrete implementations in the main layer
  3. Move to infrastructure: Relocate technology-specific logic to the infrastructure layer
// ❌ Technology name leaks into domain
struct RedisUserRepository { ... }
// ✅ Domain only defines abstract interfaces
trait UserRepository { ... }
// Infrastructure provides the implementation
struct RedisUserRepository { ... }