25 KiB
Guardian v0.6.0 - Configuration & Presets Specification
Version: 0.6.0 Target Release: Q1 2026 (January-February) Status: 📋 Specification Priority: 🔥 CRITICAL
📋 Table of Contents
- Overview
- Goals & Non-Goals
- Configuration File Format
- Preset System
- Rule Configuration
- Layer Customization
- Ignore & Exclude Patterns
- CLI Integration
- Migration Guide
- Implementation Plan
- Testing Strategy
Overview
Problem Statement
Currently, Guardian uses hardcoded rules and layer paths. This prevents:
- ❌ Customization for different project structures
- ❌ Disabling specific rules
- ❌ Per-file or per-directory overrides
- ❌ Team-specific configurations
- ❌ Framework-specific presets (NestJS, Express, etc.)
Without configuration support, Guardian cannot scale to enterprise adoption.
Solution
Add comprehensive configuration system with:
- ✅ Multiple file format support
- ✅ Zero-config presets
- ✅ Rule-level customization
- ✅ Custom layer paths
- ✅ Ignore patterns
- ✅ CLI overrides
Success Criteria
- Support 5+ configuration file formats
- Provide 4+ built-in presets
- Enable/disable any rule via config
- Custom layer path mapping
- Per-file/directory ignore patterns
- CLI can override any config option
- 100% backward compatible (default config)
- Complete documentation with examples
- 95%+ test coverage
Goals & Non-Goals
Goals
✅ Configuration Discovery
- Support multiple file formats
- Auto-discover config in project root
- Clear precedence order
✅ Zero-Config Experience
- Works without config (sensible defaults)
- Presets for common architectures
✅ Flexibility
- Enable/disable any rule
- Custom severity levels
- Per-file ignores
✅ Developer Experience
guardian initcommand- Config validation
- Helpful error messages
Non-Goals
❌ Remote Configuration
- No fetching config from URLs (v1.0+ maybe)
❌ Shareable Config Packages
- No
@company/guardian-configpackages (v0.7+ maybe)
❌ GUI Config Editor
- CLI/text-based only (v1.0+ maybe)
Configuration File Format
Supported File Formats
Guardian will discover configuration in this order:
guardian.config.js(ES modules) - Recommendedguardian.config.cjs(CommonJS)guardian.config.mjs(ES modules, explicit).guardianrc(JSON).guardianrc.json(JSON, explicit).guardianrc.js(JS)package.json(inguardianfield)
Precedence: First found wins.
Configuration Schema
interface GuardianConfig {
// Preset (optional, zero-config)
preset?: 'clean-architecture' | 'ddd' | 'hexagonal' | 'onion' | 'minimal' | string
// Extends another config (optional)
extends?: string | string[]
// Root directory (optional, default: process.cwd())
root?: string
// File includes (optional, default: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'])
include?: string[]
// File excludes (optional)
exclude?: string[]
// Rule configuration
rules?: {
[ruleName: string]: RuleConfig
}
// Layer path mapping
layers?: {
domain?: string | string[]
application?: string | string[]
infrastructure?: string | string[]
shared?: string | string[]
}
// Per-rule ignore patterns
ignore?: {
[ruleName: string]: IgnorePattern
}
// Output format (optional, default: 'text')
format?: 'text' | 'json' | 'markdown' | 'ai-prompt'
// Fail on severity (optional, default: 'error')
failOn?: 'error' | 'warning' | 'off'
}
type RuleConfig = 'error' | 'warn' | 'off' | [RuleSeverity, RuleOptions]
type RuleSeverity = 'error' | 'warn' | 'off'
type RuleOptions = Record<string, unknown>
interface IgnorePattern {
[filePattern: string]: unknown[] // Specific values to ignore
}
Example: guardian.config.js (Recommended)
// guardian.config.js
export default {
// Use built-in preset
preset: 'clean-architecture',
// Custom layer paths
layers: {
domain: 'src/core/domain',
application: 'src/core/application',
infrastructure: 'src/adapters',
shared: 'src/shared',
},
// Rule customization
rules: {
'hardcode/magic-numbers': 'error',
'hardcode/magic-strings': 'warn',
'architecture/layer-violation': 'error',
'architecture/framework-leak': 'error',
'architecture/entity-exposure': 'error',
'circular-dependency': 'error',
'naming-convention': 'warn',
'dependency-direction': 'error',
'repository-pattern': 'error',
},
// Exclusions
exclude: [
'**/*.test.ts',
'**/*.spec.ts',
'scripts/**',
'migrations/**',
'node_modules/**',
'dist/**',
],
// Per-rule ignores
ignore: {
'hardcode/magic-numbers': {
'src/config/constants.ts': [3000, 8080, 5000], // Allow these specific values
'src/database/migrations/**': '*', // Ignore all in migrations
},
'naming-convention': {
'src/legacy/**': '*', // Ignore all legacy code
},
},
// Output format
format: 'text',
// Fail on errors only (warnings don't fail CI)
failOn: 'error',
}
Example: .guardianrc (JSON)
{
"preset": "clean-architecture",
"rules": {
"hardcode/magic-numbers": "error",
"hardcode/magic-strings": "warn"
},
"exclude": ["**/*.test.ts", "**/*.spec.ts"]
}
Example: package.json
{
"name": "my-app",
"version": "1.0.0",
"guardian": {
"preset": "clean-architecture",
"rules": {
"hardcode/magic-numbers": "error"
}
}
}
Preset System
Built-in Presets
1. clean-architecture (Default)
Enforces Clean Architecture principles:
// Equivalent to:
{
rules: {
'architecture/layer-violation': 'error',
'architecture/framework-leak': 'error',
'architecture/entity-exposure': 'error',
'dependency-direction': 'error',
'circular-dependency': 'error',
'hardcode/magic-numbers': 'error',
'hardcode/magic-strings': 'error',
'naming-convention': 'warn',
'repository-pattern': 'error',
},
layers: {
domain: 'src/domain',
application: 'src/application',
infrastructure: 'src/infrastructure',
shared: 'src/shared',
}
}
When to use: Most TypeScript projects following Clean Architecture
2. ddd (Domain-Driven Design)
All DDD pattern detectors enabled:
// Equivalent to:
{
extends: 'clean-architecture',
rules: {
// All v0.11-v0.32 DDD features enabled
'aggregate-boundaries': 'error',
'anemic-domain-model': 'warn',
'domain-events': 'error',
'value-object-immutability': 'error',
// ... all 30+ DDD rules
}
}
When to use: Projects strictly following DDD
3. hexagonal (Ports & Adapters)
Validates hexagonal architecture:
// Equivalent to:
{
rules: {
'architecture/layer-violation': 'error',
'port-adapter-pattern': 'error', // v0.17.0
'dependency-direction': 'error',
},
layers: {
domain: 'src/domain',
application: 'src/application', // Ports here
infrastructure: 'src/adapters', // Adapters here
}
}
When to use: Projects using Ports & Adapters pattern
4. minimal (Prototyping)
Only critical rules for fast iteration:
// Equivalent to:
{
rules: {
'hardcode/magic-numbers': 'warn',
'circular-dependency': 'error',
'architecture/framework-leak': 'warn',
}
}
When to use: Prototypes, MVPs, learning projects
5. nestjs-clean-architecture
NestJS-specific preset:
// Equivalent to:
{
extends: 'clean-architecture',
layers: {
domain: 'src/domain',
application: 'src/application',
infrastructure: 'src/infrastructure',
},
ignore: {
'naming-convention': {
'**/*.module.ts': '*', // NestJS modules
'**/*.controller.ts': '*', // Already has suffix
},
'architecture/framework-leak': {
'src/infrastructure/**': ['@nestjs/*'], // Allow NestJS in infra
}
}
}
When to use: NestJS projects
6. express-clean-architecture
Express-specific preset:
// Equivalent to:
{
extends: 'clean-architecture',
ignore: {
'architecture/framework-leak': {
'src/infrastructure/http/**': ['express'],
}
}
}
When to use: Express projects
Custom Presets
Users can create custom presets:
// guardian.config.js
export default {
preset: './presets/my-company-preset.js'
}
// presets/my-company-preset.js
export default {
extends: 'clean-architecture',
rules: {
// Company-specific rules
}
}
Future (v0.7+): Shareable preset packages
npm install @mycompany/guardian-preset
export default {
preset: '@mycompany/guardian-preset'
}
Rule Configuration
Available Rules
| Rule ID | Default | Description |
|---|---|---|
hardcode/magic-numbers |
error |
Detect magic numbers |
hardcode/magic-strings |
error |
Detect magic strings |
architecture/layer-violation |
error |
Layer dependency violations |
architecture/framework-leak |
error |
Framework imports in domain |
architecture/entity-exposure |
error |
Domain entities in API |
circular-dependency |
error |
Circular imports |
naming-convention |
warn |
File naming conventions |
dependency-direction |
error |
Wrong dependency direction |
repository-pattern |
error |
Repository pattern violations |
Future rules (v0.11+):
aggregate-boundaries(v0.11)anemic-domain-model(v0.12)domain-events(v0.13)value-object-immutability(v0.14)- ... (25+ more)
Rule Severity Levels
rules: {
'hardcode/magic-numbers': 'error', // Fail CI, block PR
'naming-convention': 'warn', // Show warning, don't fail
'some-future-rule': 'off', // Completely disabled
}
Rule Options (Advanced)
Some rules accept options:
rules: {
'hardcode/magic-numbers': ['error', {
allowedNumbers: [-1, 0, 1, 2, 10, 100, 1000],
ignoreEnums: true,
ignoreReadonly: true,
}],
'naming-convention': ['warn', {
useCaseVerbs: ['Create', 'Update', 'Delete', 'Get', 'List'],
entityPattern: /^[A-Z][a-zA-Z]+$/,
}],
'circular-dependency': ['error', {
maxDepth: 5, // Only report cycles up to depth 5
}],
}
Layer Customization
Default Layer Paths
layers: {
domain: 'src/domain',
application: 'src/application',
infrastructure: 'src/infrastructure',
shared: 'src/shared',
}
Custom Paths (Single)
layers: {
domain: 'src/core/domain',
application: 'src/core/application',
infrastructure: 'src/adapters',
shared: 'src/common',
}
Multiple Paths per Layer
layers: {
domain: ['src/core/domain', 'src/modules/*/domain'],
application: ['src/core/application', 'src/modules/*/application'],
infrastructure: ['src/adapters', 'src/modules/*/adapters'],
}
Monorepo Support
// Root guardian.config.js
layers: {
domain: 'packages/*/src/domain',
application: 'packages/*/src/application',
infrastructure: 'packages/*/src/infrastructure',
}
Ignore & Exclude Patterns
Global Excludes
exclude: [
'**/*.test.ts',
'**/*.spec.ts',
'**/__tests__/**',
'scripts/**',
'migrations/**',
'node_modules/**',
'dist/**',
'build/**',
]
Per-Rule Ignores
Ignore Specific Values
ignore: {
'hardcode/magic-numbers': {
'src/config/constants.ts': [3000, 8080, 5000],
'src/config/defaults.ts': [10, 20, 30],
}
}
Ignore All Violations
ignore: {
'naming-convention': {
'src/legacy/**': '*', // Ignore all naming in legacy
}
}
Ignore Entire Directories
ignore: {
'hardcode/magic-numbers': {
'migrations/**': '*',
'scripts/**': '*',
}
}
Pattern Syntax
Supports glob patterns:
*- matches any characters except/**- matches any characters including/?- matches single character[abc]- matchesa,b, orc{a,b}- matchesaorb
CLI Integration
Commands
guardian init
Generate configuration file:
# Interactive mode
guardian init
# With preset
guardian init --preset clean-architecture
# Specific format
guardian init --format js
guardian init --format json
# Output to custom location
guardian init --output custom-config.js
Interactive prompts:
? Which preset would you like to use? (Use arrow keys)
❯ clean-architecture (Recommended)
ddd (Domain-Driven Design)
hexagonal (Ports & Adapters)
minimal (Prototyping)
nestjs-clean-architecture
express-clean-architecture
custom (Configure manually)
? Where are your domain files? (src/domain)
? Where are your application files? (src/application)
? Where are your infrastructure files? (src/infrastructure)
? Configuration file format? (Use arrow keys)
❯ JavaScript (guardian.config.js) - Recommended
JSON (.guardianrc)
package.json
✅ Created guardian.config.js
guardian check (with config)
# Use config from default locations
guardian check ./src
# Specify config file
guardian check ./src --config custom-config.js
# Override rules via CLI
guardian check ./src --rule hardcode/magic-numbers=off
guardian check ./src --rule naming-convention=error
# Override preset
guardian check ./src --preset minimal
# Override fail-on
guardian check ./src --fail-on warning
guardian validate-config
Validate configuration file:
guardian validate-config
guardian validate-config --config custom-config.js
# Output:
# ✅ Configuration is valid
# or
# ❌ Configuration errors:
# - Unknown rule: 'invalid-rule'
# - Invalid severity: 'critical' (must be error/warn/off)
CLI Overrides
CLI options take precedence over config file:
// guardian.config.js
{
rules: {
'hardcode/magic-numbers': 'error'
}
}
# Override to 'off' for this run
guardian check ./src --rule hardcode/magic-numbers=off
Precedence order:
- CLI flags (highest)
- Config file
- Preset
- Default config (lowest)
Migration Guide
From No Config → With Config
Before (v0.5.1):
# All rules enabled, hardcoded paths
guardian check ./src
After (v0.6.0):
# Generate config
guardian init --preset clean-architecture
# Customize guardian.config.js
# Run with config
guardian check ./src
Backward Compatibility
v0.6.0 is 100% backward compatible:
# This still works exactly the same
guardian check ./src
# Default config is applied automatically
Default config (when no config file found):
{
preset: 'clean-architecture',
layers: {
domain: 'src/domain',
application: 'src/application',
infrastructure: 'src/infrastructure',
shared: 'src/shared',
},
rules: {
'hardcode/magic-numbers': 'error',
'hardcode/magic-strings': 'error',
'architecture/layer-violation': 'error',
'architecture/framework-leak': 'error',
'architecture/entity-exposure': 'error',
'circular-dependency': 'error',
'naming-convention': 'warn',
'dependency-direction': 'error',
'repository-pattern': 'error',
}
}
Implementation Plan
Phase 1: Core Configuration (Week 1-2)
Tasks:
- Create
GuardianConfigTypeScript interface - Implement config file discovery
- Implement config parser (JS, JSON)
- Implement config validator
- Add config merging (extends, overrides)
- Update
AnalyzeProjectto accept config - Tests for config loading
Deliverable: Config files are discovered and parsed
Phase 2: Rule Configuration (Week 2-3)
Tasks:
- Implement rule severity system (error/warn/off)
- Update each detector to check rule config
- Implement per-rule options
- Tests for rule configuration
Deliverable: Rules can be enabled/disabled/configured
Phase 3: Preset System (Week 3-4)
Tasks:
- Implement preset loader
- Create built-in presets (clean-architecture, ddd, etc.)
- Implement preset extends
- Implement custom preset loading
- Tests for preset system
Deliverable: Presets work and can be extended
Phase 4: Ignore Patterns (Week 4-5)
Tasks:
- Implement ignore pattern matching
- Update detectors to check ignore patterns
- Add global exclude support
- Tests for ignore patterns
Deliverable: Files and values can be ignored
Phase 5: CLI Integration (Week 5-6)
Tasks:
- Implement
guardian initcommand - Add
--configflag - Add
--ruleoverride flag - Add
--presetoverride flag - Implement
guardian validate-config - Tests for CLI integration
Deliverable: CLI fully supports configuration
Phase 6: Documentation & Testing (Week 6-7)
Tasks:
- Write configuration documentation
- Create example configs for each preset
- Add migration guide
- Comprehensive integration tests
- Update README
Deliverable: Complete docs and 95%+ coverage
Phase 7: Beta Testing & Release (Week 7-8)
Tasks:
- Beta release (v0.6.0-beta.1)
- Community testing
- Bug fixes
- Final release (v0.6.0)
Deliverable: Stable v0.6.0 release
Testing Strategy
Unit Tests
describe('ConfigLoader', () => {
it('should discover guardian.config.js', async () => {
// Test config file discovery
})
it('should parse JavaScript config', async () => {
// Test JS config parsing
})
it('should parse JSON config', async () => {
// Test JSON config parsing
})
it('should merge configs with extends', async () => {
// Test config merging
})
it('should validate config schema', async () => {
// Test validation
})
})
describe('PresetLoader', () => {
it('should load built-in preset', async () => {
// Test preset loading
})
it('should extend preset', async () => {
// Test preset extending
})
})
describe('RuleConfiguration', () => {
it('should disable rule when set to off', async () => {
// Test rule disabling
})
it('should apply rule options', async () => {
// Test rule options
})
})
Integration Tests
describe('Configuration Integration', () => {
it('should run with custom config', async () => {
// Create temp config file
// Run guardian check
// Verify rules are applied
})
it('should apply preset correctly', async () => {
// Test preset application
})
it('should ignore files matching pattern', async () => {
// Test ignore patterns
})
it('should override config from CLI', async () => {
// Test CLI overrides
})
})
Test Coverage Goals
- Configuration loading: 100%
- Preset system: 100%
- Rule configuration: 100%
- Ignore patterns: 95%+
- CLI integration: 95%+
- Overall: 95%+
Examples
Example 1: Minimal Config
// guardian.config.js
export default {
preset: 'clean-architecture',
}
Example 2: Custom Paths
// guardian.config.js
export default {
preset: 'clean-architecture',
layers: {
domain: 'src/core/domain',
application: 'src/core/application',
infrastructure: 'src/adapters',
},
}
Example 3: Rule Customization
// guardian.config.js
export default {
preset: 'clean-architecture',
rules: {
'hardcode/magic-numbers': 'warn', // Downgrade to warning
'naming-convention': 'off', // Disable completely
},
}
Example 4: Ignore Patterns
// guardian.config.js
export default {
preset: 'clean-architecture',
ignore: {
'hardcode/magic-numbers': {
'src/config/**': '*', // Ignore all hardcode in config
'src/constants.ts': [3000, 8080], // Allow specific values
},
'naming-convention': {
'src/legacy/**': '*', // Ignore legacy code
},
},
}
Example 5: NestJS Project
// guardian.config.js
export default {
preset: 'nestjs-clean-architecture',
exclude: [
'**/*.spec.ts',
'test/**',
],
}
Example 6: Monorepo
// guardian.config.js (root)
export default {
preset: 'clean-architecture',
layers: {
domain: 'packages/*/src/domain',
application: 'packages/*/src/application',
infrastructure: 'packages/*/src/infrastructure',
},
exclude: [
'packages/legacy/**',
],
}
API Changes
Before (v0.5.1)
// No configuration support
const result = await analyzeProject({
rootDir: './src',
exclude: ['node_modules'],
})
After (v0.6.0)
import { loadConfig } from '@samiyev/guardian'
// Load config
const config = await loadConfig('./guardian.config.js')
// Use config
const result = await analyzeProject({
rootDir: './src',
config, // New: Pass config
})
// Or auto-discover:
const result = await analyzeProject({
rootDir: './src',
// Config auto-discovered if not provided
})
Documentation Updates
New Documentation Pages
-
Configuration Guide
- How to create config
- All options explained
- Examples for each preset
-
Preset Reference
- Description of each preset
- When to use which preset
- How to customize presets
-
Rule Reference
- Complete list of rules
- Rule options
- Examples for each rule
-
Migration Guide
- From v0.5.x to v0.6.0
- Adding config to existing projects
Updated Pages
- README.md - Add configuration section
- Quick Start - Show
guardian init - CLI Reference - New commands and flags
Success Metrics
Release Criteria
- All tests passing (95%+ coverage)
- Documentation complete
- 5+ example configs
- Beta tested by 10+ users
- Zero critical bugs
- Backward compatible
Adoption Metrics (3 months post-release)
- Target: 50%+ of users create config files
- Target: 100+ GitHub repos with guardian.config.js
- Target: <5 config-related issues on GitHub
Future Enhancements (Post-v0.6.0)
v0.7.0 - Shareable Configs
npm install @mycompany/guardian-config
export default {
extends: '@mycompany/guardian-config'
}
v0.8.0 - Remote Configs
export default {
extends: 'https://example.com/guardian-config.js'
}
v1.0.0 - GUI Config Editor
guardian config-editor
# Opens web-based config editor
Questions & Answers
Q: Will this be a breaking change?
A: No, v0.6.0 is 100% backward compatible. If no config file exists, Guardian uses the same default behavior as v0.5.1.
Q: Can I migrate incrementally?
A: Yes! Start with preset: 'clean-architecture' and customize one rule at a time.
Q: Will presets be updateable?
A: Presets are versioned with Guardian. When you update Guardian, presets update too. You can pin to a specific preset version in future versions.
Q: Can I use TypeScript for config?
A: Yes, in v0.7.0+ we'll add guardian.config.ts support. For v0.6.0, use .js with JSDoc types.
Timeline
| Week | Phase | Deliverable |
|---|---|---|
| 1-2 | Core Configuration | Config loading works |
| 2-3 | Rule Configuration | Rules configurable |
| 3-4 | Preset System | Presets work |
| 4-5 | Ignore Patterns | Ignores work |
| 5-6 | CLI Integration | CLI supports config |
| 6-7 | Documentation | Complete docs |
| 7-8 | Beta & Release | v0.6.0 stable |
Target Release Date: End of Q1 2026 (February-March)
Feedback & Questions
- 📧 Email: fozilbek.samiyev@gmail.com
- 🐙 GitHub: https://github.com/samiyev/puaros/issues
- 💬 Discuss: https://github.com/samiyev/puaros/discussions
Status: This specification is ready for implementation.
Next Steps:
- Review and approve this spec
- Create implementation tasks in GitHub
- Start Phase 1 development
- Weekly progress updates