Customizing Validation Rules
Relevant source files
The following files were used as context for generating this wiki page:
The MCB project employs a robust validation system designed to enforce architectural boundaries, code quality standards, and organizational consistency. Customizing these rules involves modifying TOML configuration files or defining declarative YAML rules that target specific AST nodes or patterns across multiple programming languages. This system ensures that the project's Clean Architecture principles are maintained throughout the development lifecycle.
Sources: config/mcb-validate.toml, AGENTS.md:315-325, crates/mcb-validate/rules/schema.json
Configuration Hierarchy
Validation settings are managed through a hierarchical configuration approach. Default rules are embedded in the binary, while project-specific overrides and runtime adjustments are applied through localized files and environment variables.
- Default Configuration:
config/mcb-validate.tomlprovides the baseline settings for all validators, including thresholds for file lengths and allowed magic numbers. - Internal Overrides:
config/mcb-validate-internal.tomlcontains project-specific adjustments, such as defining specific layer boundaries for the MCB workspace. - Runtime Overrides: Users can use
MCB_VALIDATE__*environment variables to override settings at execution time.
Sources: config/mcb-validate.toml:1-10, config/mcb-validate-internal.toml:1-5
Configuration Data Flow
The following diagram illustrates how the ValidateArgs are processed to resolve the workspace and run the validation engine.
The validate command resolves the workspace root, initializes a ValidationConfig, and executes the registered validators. Sources: crates/mcb/src/cli/validate.rs:90-115
Declarative Rule Definition
MCB supports declarative rules defined in YAML format. These rules must adhere to a specific JSON schema and can leverage various execution engines, such as Tree-sitter for AST analysis or Regex for pattern scanning.
Rule Schema Structure
Every custom rule must include mandatory metadata and engine-specific configurations.
| Field | Type | Description |
|---|---|---|
schema | String | Version identifier (e.g., rule/v1, rule/v2). |
id | String | Unique identifier matching ^[A-Z]{2,8}\d{3,4}$. |
category | Enum | Grouping such as architecture, quality, or solid. |
severity | Enum | error, warning, or info. |
engine | Enum | The execution engine: ast, regex, path, or rust-rule-engine. |
Sources: crates/mcb-validate/rules/schema.json:10-80
Engine Types
The system supports multiple engines for rule execution:
- AST Engine: Uses
selectorsandast_query(Tree-sitter) to match specific code structures like function definitions or trait implementations. - Regex Engine: Scans file contents for specific patterns defined in the
config. - Path Engine: Validates file locations and naming conventions relative to the workspace root.
Sources: crates/mcb-validate/rules/schema.json:76-85, crates/mcb-validate/src/engines/validator_engine.rs:136-150
Architecture and Layer Boundaries
A primary use case for customizing rules is enforcing Clean Architecture boundaries. This is configured in the rules.architecture and rules.clean_architecture sections of the TOML files.
This structure defines which internal crates are permitted as dependencies for each architectural layer. Sources: config/mcb-validate.toml:21-31, config/mcb-validate-internal.toml:12-20
Example: Internal Layer Dependencies
In mcb-validate-internal.toml, the project defines specific internal dependencies:
- Application: Allowed to depend on
mcb-domainandmcb-utils. - Server: Allowed to depend on
mcb-domain,mcb-infrastructure, andmcb-utils.
Sources: config/mcb-validate-internal.toml:16-20
Rule Validation Logic
The ValidatorEngine ensures that custom rule definitions are structurally sound before execution. It validates fields such as the rule ID length, name length, and ensures the provided category and severity are within the allowed set.
// crates/mcb-validate/src/engines/validator_engine.rs:43-60
pub fn validate_rule_definition(&self, rule_definition: &Value) -> Result<()> {
let rule_config: RuleConfigValidation = serde_json::from_value(rule_definition.clone())
.map_err(|e| crate::ValidationError::Parse {
file: "rule_definition".into(),
message: format!("Invalid rule structure: {e}"),
})?;
validator::Validate::validate(&rule_config)
.map_err(|e| crate::ValidationError::Config(format!("Validation error: {e:?}")))?;
if let Some(ref category) = rule_config.category {
validate_category(category)?;
}
Ok(())
}
Sources: crates/mcb-validate/src/engines/validator_engine.rs:43-73
Summary of Customizable Parameters
The following table summarizes key validation parameters found in the default configuration:
| Section | Parameter | Default / Example | Description |
|---|---|---|---|
general | exclude_patterns | ["target/", "tests/fixtures/"] | Paths ignored by all validators. |
quality | max_file_lines | 500 | Maximum allowed lines per source file. |
solid | max_function_params | 5 | Maximum parameters allowed in a function. |
organization | magic_number_allowlist | [0, 1, 2, 10, 100, ...] | Numbers permitted without being labeled as "magic". |
naming | struct_pattern | ^[A-Z][a-zA-Z0-9]*$ | Regex pattern for struct names. |
Sources: config/mcb-validate.toml:12-110, config/mcb-validate-internal.toml:22-100
Customizing validation rules in MCB allows developers to tailor the architectural guardrails to the specific needs of their project while leveraging a standardized declarative framework for multi-language code analysis.