Overlays guide
Experimental feature. Overlays are functional but under active development. APIs may change. Most solo developers can skip this feature entirely.
Solo developer? You can skip this page unless you’re using external rule Aligns. Overlays are for advanced customization of third-party rules.
Supported selectors: rule[id=...] and sections[index]. Property/heading
selectors are deprecated. Use set: { key: null } to remove properties
(remove is deprecated). Overlay conflicts fail by default; use
--allow-overlay-conflicts to allow last-writer-wins.
Overlays let you customize third-party Aligns without forking. Change severity, add check inputs, or remove autofix while preserving upstream updates.
Common use cases:
- Severity upgrade - Make warnings errors
- Temporary migration - Relax rules during refactoring
- Threshold adjustment - Project-specific complexity limits
- Autofix removal - Keep check but disable risky fixes
- Gradual rollout - Progressive rule adoption
Each is covered in Scenarios with full configurations.
See it in action: Check out the overlays example for a working demonstration.
Real-world scenarios: See 5 complete examples below for severity upgrades, temporary migrations, threshold adjustments, autofix removal, and gradual rollouts.
Quick start (60 seconds)
Scenario: You use @acme/standards but want to treat one check as an error.
# .aligntrue/rules
sources:
- git: https://github.com/acme/standards
ref: v1.2.0
overlays:
overrides:
- selector: "rule[id=no-console-log]"
set:
severity: "error"Run sync:
aligntrue sync
# Output:
# ✓ Applied 1 overlay to @acme/standards
# ✓ Lockfile updated with overlay hashResult: no-console-log now fails CI instead of warning, with your customization preserved when upstream changes.
Overlays apply during sync: they adjust the in-memory IR and the generated exports/lock hashes. The .aligntrue/rules/*.md files you author stay untouched by overlays.
On this page: When to Use · Overlay Anatomy · Selectors · Scenarios · Performance
When to use overlays vs plugs vs forks
Decision tree
Need to customize a third-party align?
│
├─ Change exists in align definition? (severity, inputs, autofix)
│ ├─ YES → Use overlay (this guide)
│ └─ NO → Continue...
│
├─ Customization is stack-specific? (test commands, paths)
│ ├─ YES → Use plug (see plugs guide)
│ └─ NO → Continue...
│
└─ Need to change check logic or add new checks?
└─ YES → Fork align or create custom alignWhen to use overlays
✅ Change severity: Warning → error, or disable a check
✅ Add check inputs: Pass project-specific config to checks
✅ Remove autofix: Keep check but disable automatic fixes
✅ Temporary adjustments: Override during migration, restore later
❌ Don’t use overlays for:
- Changing check logic (fork instead)
- Adding new checks (create custom align)
- Stack-specific values (use plugs)
When to use plugs
✅ Stack-specific values: Test commands, file paths, URLs
✅ Template slots: Fill variables in rules
✅ Project metadata: Author names, organization names
See Plugs Guide for plug documentation.
When to fork
✅ Major changes: Rewrite check logic, change structure
✅ Divergent requirements: Your needs differ fundamentally
✅ No upstream updates needed: You maintain your version
Overlay anatomy
Basic overlay
overlays:
overrides:
- selector: "rule[id=no-console-log]"
set:
severity: "error" # Change severityAdvanced overlay
overlays:
overrides:
- selector: "rule[id=max-complexity]"
set:
severity: "warning"
"check.inputs.threshold": 15 # Nested property with dot notation
remove:
- "autofix" # Disable autofixNote: Track metadata like reason, expires, and owner via YAML comments.
Selector strategies
Discover selectors quickly
Run the CLI helper to list rule IDs and section indexes from your current IR:
aligntrue override selectorsSample output:
Selector inventory (.aligntrue/rules)
Found 3 sections. Use these selectors in overlays:
1. TypeScript strict mode
• sections[0]
• rule[id=typescript-strict-mode]
Treat all TypeScript files as strict mode
2. Testing coverage baseline
• sections[1]
• rule[id=testing-coverage-baseline]
Top-level property selectors:
• profile.id
• profile.versionUse sections[index] when a section does not have a fingerprint field.
Use rule[id=...] when fingerprints exist (they map to the fingerprint in .aligntrue/rules).
By rule ID
Applies to one specific rule by its unique ID:
overlays:
overrides:
- selector: "rule[id=no-console-log]"
set:
severity: "error"Use when: Most rules are fine, one needs adjustment.
By property path
Modify nested properties using dot notation:
overlays:
overrides:
- selector: "profile.version"
set:
value: "2.0.0"Use when: Changing configuration or metadata fields.
By array index
Target specific array elements:
overlays:
overrides:
- selector: "rules[0]"
set:
severity: "warn"Use when: Modifying rules by position (less common, prefer rule ID).
Note: Scope-based selectors (e.g., tests/**) are not yet implemented. Use hierarchical configs with scopes for path-based customization.
Override capabilities
Set operation
Use set to modify properties (supports dot notation for nested paths):
overlays:
overrides:
- selector: "rule[id=no-console-log]"
set:
severity: "error" # Simple property
"check.inputs.maxLength": 120 # Nested property
autofix: false # Disable autofixSeverity values: "off", "info", "warning", "error"
Remove operation
Use remove to delete properties:
overlays:
overrides:
- selector: "rule[id=max-complexity]"
remove:
- "autofix" # Remove autofix
- "tags" # Remove tags arrayCombined operations
Apply both set and remove in one overlay:
overlays:
overrides:
- selector: "rule[id=line-length]"
set:
severity: "warning"
"check.inputs.threshold": 120
remove:
- "autofix"Advanced patterns
Multiple overlays
Apply multiple overlays to different rules:
overlays:
overrides:
- selector: "rule[id=no-console-log]"
set:
severity: "error"
- selector: "rule[id=max-complexity]"
set:
"check.inputs.threshold": 15
- selector: "rule[id=prefer-const]"
remove:
- "autofix"Order: Overlays apply in definition order. Last matching overlay wins if multiple target the same rule.
Temporary overrides
Use YAML comments to track temporary overlays:
overlays:
overrides:
# TEMPORARY: Migration to new API in progress
# Expires: 2025-12-31
# Owner: platform-team
- selector: "rule[id=no-deprecated-api]"
set:
severity: "warning"Use aligntrue override status to review all active overlays.
Migration workflow
Gradually adopt stricter rules:
# Week 1: Disable new check
overlays:
overrides:
- selector: "rule[id=new-security-rule]"
set:
severity: "off"
# Week 2: Enable as warning
overlays:
overrides:
- selector: "rule[id=new-security-rule]"
set:
severity: "warning"
# Week 3: Remove overlay (use upstream default: error)
overlays:
overrides: []Scenario-based examples
More examples: See SCENARIOS.md in the overlays example for detailed scenarios with expected outputs.
Scenario 1: Solo developer - Temporarily disable strict rule
Goal: Disable strict TypeScript rule during refactoring, re-enable after.
Setup:
sources:
- git: https://github.com/org/typescript-standards
ref: v1.0.0
# Temporarily downgrade severity during refactoring
overlays:
overrides:
# TEMPORARY: Refactoring legacy code
# Expires: 2025-12-31
# Will re-enable after refactor complete
- selector: "rule[id=strict-null-checks]"
set:
severity: "warn" # Downgrade from errorWorkflow:
# 1. Add overlay
aligntrue sync
# 2. Refactor code with warnings instead of errors
# ... refactoring work ...
# 3. Remove overlay when done
aligntrue override remove 'rule[id=strict-null-checks]'
aligntrue syncScenario 2: Solo developer - Adjust complexity threshold
Goal: Increase complexity threshold for specific project needs.
Setup:
sources:
- git: https://github.com/org/code-quality-align
ref: v2.0.0
overlays:
overrides:
# Project has complex domain logic, increase threshold
# Reviewed: 2025-10-01
- selector: "rule[id=max-complexity]"
set:
"check.inputs.threshold": 15 # Default is 10
"check.inputs.excludeComments": trueResult: Complexity check allows up to 15 instead of 10.
Scenario 3: Team - Enforce stricter severity
Goal: Team wants stricter enforcement than upstream defaults.
Setup:
sources:
- git: https://github.com/community/typescript-align
ref: v1.0.0
overlays:
overrides:
# Team policy: No console.log in production
# Approved: 2025-10-15
# Owner: platform-team
- selector: "rule[id=no-console-log]"
set:
severity: "error" # Upgrade from warning
# Team policy: No any types
# Approved: 2025-10-15
# Owner: platform-team
- selector: "rule[id=no-any-type]"
set:
severity: "error" # Upgrade from warningWorkflow:
# 1. Team lead adds overlays
# 2. Commit to git
git add .aligntrue/rules
git commit -m "chore: Enforce stricter console.log and any-type rules"
# 3. Team members pull and sync
git pull
aligntrue sync
# 4. CI validates with stricter rules
aligntrue check --ciScenario 4: Team - Disable risky autofix
Goal: Keep check but disable autofix that conflicts with framework.
Setup:
sources:
- git: https://github.com/org/react-standards
ref: v2.0.0
overlays:
overrides:
# Autofix conflicts with React hooks dependencies
# Issue: #123
# Owner: frontend-team
- selector: "rule[id=prefer-const]"
remove:
- "autofix"Result: Check still runs, but doesn’t auto-fix (manual fixes only).
Scenario 5: Team - Gradual rollout of new rule
Goal: Roll out new security rule gradually across team.
Week 1 - Disable:
overlays:
overrides:
# ROLLOUT: Week 1 - Disabled
# New security rule, giving team time to review
- selector: "rule[id=new-security-check]"
set:
severity: "off"Week 2 - Warning:
overlays:
overrides:
# ROLLOUT: Week 2 - Warning
# Team reviewing violations
- selector: "rule[id=new-security-check]"
set:
severity: "warn"Week 3 - Error:
overlays:
overrides:
# ROLLOUT: Week 3 - Error
# All violations fixed, enforcing now
- selector: "rule[id=new-security-check]"
set:
severity: "error"Week 4 - Remove overlay:
# Remove overlay, use upstream default (error)
overlays:
overrides: []Scenario 6: Fork-safe customization
Goal: Customize third-party align without forking, preserve updates.
Setup:
sources:
- git: https://github.com/thirdparty/standards
ref: v3.0.0
overlays:
overrides:
# Customize for our needs
- selector: "rule[id=line-length]"
set:
"check.inputs.maxLength": 120 # We use 120, they use 80
- selector: "rule[id=max-complexity]"
set:
"check.inputs.threshold": 15 # We allow 15, they allow 10
- selector: "rule[id=prefer-const]"
remove:
- "autofix" # Conflicts with our frameworkOverlay workflow:
# 1. Review current overlays
aligntrue override status # Check overlay health
# 2. Sync with overlays applied
aligntrue sync
# 3. Overlays are applied on each syncResult: Overlays automatically apply to your rules on each sync.
Conflict resolution
What causes conflicts?
Stale selectors: Upstream renamed or removed a rule.
# Upstream renamed "no-console-log" → "no-console-statements"
overlays:
overrides:
- selector: "rule[id=no-console-log]" # ❌ No longer exists
set:
severity: "error"Resolution: Run aligntrue override status to detect stale selectors, update to new rule ID.
Duplicate overlays: Multiple overlays target same rule.
overlays:
overrides:
- selector: "rule[id=no-console-log]"
set:
severity: "error"
- selector: "rule[id=no-console-log]"
set:
severity: "warning" # ❌ Conflicts with aboveResolution: Last matching overlay wins. Consolidate into single overlay or remove duplicate.
Handling upstream changes
When upstream changes may conflict with your overlay:
# Check overlay health after update
aligntrue sync
aligntrue override status
# Shows if overlays still match rules
# View overlay effects
aligntrue override diff 'rule[id=no-console-log]'
# Shows: original IR → modified IR with overlay appliedIf rule ID changed upstream:
- Remove old overlay:
aligntrue override remove 'rule[id=old-name]' - Add new overlay:
aligntrue override add --selector 'rule[id=new-name]' --set severity=error
If overlay now redundant (upstream matches your override):
- Verify match:
aligntrue override diff - Remove overlay:
aligntrue override remove 'rule[id=rule-name]'
Team workflows
Overlay approval
Team mode tracks overlays in lockfile for review:
// .aligntrue/lock.json
{
"dependencies": {
"acme-standards": {
"content_hash": "sha256:upstream...",
"overlay_hash": "sha256:local-mods...",
"final_hash": "sha256:combined..."
}
}
}See Team Mode Guide for team mode workflows.
Overlay dashboard
Audit all overlays:
aligntrue override status
# Output:
# Overlays (3 active, 1 stale)
#
# ✓ rule[id=no-console-log]
# Set: severity=error
# Healthy: yes
#
# ✓ rule[id=max-complexity]
# Set: check.inputs.threshold=15
# Healthy: yes
#
# ❌ rule[id=old-rule-name]
# Set: severity=off
# Healthy: stale (no match in IR)Overlay hashing and lockfile
Triple-hash lockfile
Overlays are deterministic and hashed separately:
{
"spec_version": "1",
"generated_at": "2025-10-31T12:00:00Z",
"dependencies": {
"@acme/standards": {
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/acme/standards",
"ref": "v1.2.0",
"commit": "abc123"
},
"base_hash": "sha256:upstream-content-hash",
"overlay_hash": "sha256:overlay-modifications-hash",
"result_hash": "sha256:combined-hash"
}
}
}base_hash: Upstream align content
overlay_hash: Your overlay modifications
result_hash: Combined result after overlays applied
Drift detection
Detect overlay staleness:
aligntrue drift
# Output:
# Drift detected (2 categories)
#
# Overlay drift:
# rule[id=no-console-log]
# - overlay_hash changed (local modifications)
# - Recommendation: Review overlay changes
#
# Upstream drift:
# @acme/standards
# - base_hash changed (upstream updated)
# - Recommendation: Run aligntrue sync to apply latestSee Drift Detection for full drift capabilities.
CLI commands
Add overlay
# Add overlay to change severity
aligntrue override add \
--selector 'rule[id=no-console-log]' \
--set severity=error
# Add overlay with nested property (dot notation)
aligntrue override add \
--selector 'rule[id=max-complexity]' \
--set check.inputs.threshold=15
# Remove property
aligntrue override add \
--selector 'rule[id=prefer-const]' \
--remove autofix
# Combined set and remove
aligntrue override add \
--selector 'rule[id=line-length]' \
--set severity=warning \
--set check.inputs.max=120 \
--remove autofixView overlays
# Dashboard of all overlays
aligntrue override status
# JSON output for CI
aligntrue override status --jsonDiff overlays
# Show effect of specific overlay
aligntrue override diff 'rule[id=no-console-log]'
# Show all overlay effects
aligntrue override diffRemove overlay
# Interactive removal (select from list)
aligntrue override remove
# Direct removal by selector
aligntrue override remove 'rule[id=no-console-log]'
# Skip confirmation
aligntrue override remove 'rule[id=no-console-log]' --forceIntegration with other commands
# Sync applies overlays automatically
aligntrue sync
# Check overlay status anytime
aligntrue override statusSee CLI Reference for complete command documentation.
Best practices
Keep overlays minimal
Only override what you must. Fewer overlays = easier updates.
❌ Bad: Override many rules:
overlays:
overrides:
- selector: "rule[id=check-1]"
set: { severity: "error" }
- selector: "rule[id=check-2]"
set: { severity: "error" }
# ... 20 more overlays✅ Good: Fork and customize:
# Create your own align based on upstream
# Maintain in your repo, or request changes upstreamDocument reasons
Always explain why using YAML comments:
overlays:
overrides:
# CLI tool requires console output for user feedback
# Owner: cli-team
- selector: "rule[id=no-console-log]"
set:
severity: "off"Track expiration
For temporary overrides, use YAML comments:
overlays:
overrides:
# TEMPORARY: Gradual rollout
# Expires: 2025-12-31
- selector: "rule[id=new-rule]"
set:
severity: "warning"Use aligntrue override status to review active overlays regularly.
Review regularly
Audit overlays monthly:
# Check all overlays health
aligntrue override status
# View overlay effects
aligntrue override diff
# Detect drift
aligntrue driftFor solo developers
- Use for experimentation - Try different severity levels
- Temporary adjustments - Disable strict rules during refactoring
- Document decisions - Add comments explaining why
- Clean up - Remove overlays when no longer needed
For teams
- Require approval - PR review for overlay changes
- Document ownership - Add owner comments
- Set expiration dates - Review temporary overlays
- Audit regularly - Monthly overlay review
- Validate in CI - Run
aligntrue override statusin CI
Troubleshooting
Overlay not applied
Symptom: Overlay defined but check still uses upstream settings.
Diagnosis:
aligntrue override status
# Look for "Healthy: no" entriesCommon causes:
- Typo in rule ID
- Rule no longer exists in upstream
- Selector too specific (no matches)
Fix: Run aligntrue override status for health status and detailed errors.
Overlay conflicts
Symptom: Multiple overlays target same rule.
Diagnosis:
aligntrue override status
# Lists all active overlays
aligntrue override diff
# Shows combined effectFix: Consolidate overlays into single definition. Last overlay wins if multiple target same rule.
Overlays not applying
Symptom: Overlays don’t apply to synced content.
Diagnosis:
aligntrue override status
# Shows health after update
aligntrue override diff
# Shows current effectsFix: Update selectors to match new upstream rule IDs. Run aligntrue override remove for stale overlays and re-add with correct selectors.
See Troubleshooting Overlays for comprehensive troubleshooting.
Verifying overlay application
Understanding what overlays affect
Overlays modify the IR during sync (in memory) and affect behavior of checks and linting, even if the changes aren’t visible in markdown exports. The source files you author in .aligntrue/rules/*.md remain unchanged.
Example:
- Overlay changes
severity: "warning"→severity: "error" - In-memory IR at sync time now uses
severity: error(source file stays the same) - Check behavior changes (errors fail CI instead of warnings)
- Exported AGENTS.md still shows
## Rule Name(no severity indicator)
This is correct behavior. Severity affects behavior. Markdown format doesn’t include machine metadata by design.
Verifying overlays are applied
Use these commands to confirm overlays are working:
# 1. Check that overlay is active and healthy
aligntrue override status
# Shows: ✓ rule[id=your-rule-id]
# Set: severity="error"
# Healthy: yes
# 2. View the effect of the overlay
aligntrue override diff
# Shows: Original → Modified with overlay applied
# 3. Check CLI output during sync
aligntrue sync
# Output shows: ✓ Applied 1 overlay to rulesOverlay effects not visible in exports
If you don’t see severity changes in AGENTS.md or other exports, this is expected. Here’s why:
- Source stays unchanged:
.aligntrue/rules/*.mdremains the authored source; overlays do not rewrite these files. - IR is in memory: Overlays apply during sync to the in-memory IR and exports/lock hashes.
- Exports are simplified: Markdown formats prioritize readability.
- Verification: Use
aligntrue override diff/statusto confirm, and use inline content mode if you need metadata in exports.
To verify overlays are affecting checks:
# 1. Add overlay to make rule an error
aligntrue override add --selector 'rule[id=my-rule]' --set severity=error
# 2. Sync
aligntrue sync
# 3. Check IR (should now have severity=error)
aligntrue override diff 'rule[id=my-rule]'
# 4. Run checks (check behavior will change)
aligntrue check
# 5. Confirm via CLI output
# (checks will now use error severity from IR, affecting results)Overlays are working correctly if:
- ✅
aligntrue override statusshows “Healthy: yes” - ✅
aligntrue override diffshows the change applied - ✅ Exports/lock hashes reflect the overlay (or inline content mode shows metadata)
- ✅ Check behavior changes as expected
Overlay metadata visibility
Overlays modify the IR (intermediate representation) metadata during sync, but this metadata is not visible in all export formats. Understanding where overlay changes appear helps avoid confusion.
Where overlay changes are visible
| Location | Visibility | Notes |
|---|---|---|
| Lockfiles (team mode) | Always visible | overlay_hash and modified values stored |
aligntrue override status | Always visible | Shows active overlays and their effects |
aligntrue override diff | Always visible | Shows before/after comparison |
| Inline content mode exports | Visible in rendered content | Full rule content includes metadata |
| JSON/structured exports | Visible in metadata fields | Machine-readable format preserves all fields |
Where overlay changes are NOT visible
| Location | Visibility | Reason |
|---|---|---|
| Link-based AGENTS.md | Not visible | Links point to files, don’t include metadata |
| Link-based exports | Not visible | Markdown links don’t render metadata |
Why link-based exports don’t show metadata
When using the default content_mode: auto or content_mode: links, AGENTS.md contains markdown links to rule files:
## General
- testing (./.aligntrue/rules/testing.md): Testing standards
- security (./.aligntrue/rules/security.md): Security guidelinesThese links point to the canonical rules but don’t embed metadata like severity. The overlay still affects:
- Check behavior - The in-memory IR has the modified severity (even if exports omit metadata)
- Lockfile hashes - Team mode tracks the overlay
- CLI commands -
aligntrue override statusshows the change
Verifying overlays in link-based exports
If you’re using link-based exports and want to verify overlays:
# 1. Confirm overlay is active
aligntrue override status
# Shows: ✓ rule[id=security] Set: severity="error" Healthy: yes
# 2. View the effect
aligntrue override diff 'rule[id=security]'
# Shows: severity: "warning" → severity: "error"
# 3. If you need metadata in exports, use inline mode
aligntrue sync --content-mode inlineUsing inline mode to see metadata
If you need metadata visible in exports, use inline content mode:
aligntrue sync --content-mode inlineOr configure in .aligntrue/config.yaml:
sync:
content_mode: inlineThis embeds full rule content including metadata in AGENTS.md.
Scenarios
Real-world examples showing how to use overlays for fork-safe customization:
- Severity upgrade - Make warnings errors
- Temporary migration - Disable strict rules during refactor
- Threshold adjustment - Project-specific complexity limits
- Autofix removal - Keep check but disable risky autofix
- Gradual rollout - Progressive rule adoption
Severity upgrade
Problem: An upstream align has a rule with severity: warning but your team wants to enforce it as an error. For example, upstream has no-console-log as a warning, but your team requires it to be an error in production code. You don’t want to fork the align just to change severity.
Solution: Use overlays to upgrade severity without forking the upstream align.
Configuration:
version: "1"
mode: solo
sources:
- type: local
path: "upstream-align.yaml"
overlays:
overrides:
- selector: "rule[id=no-console-log]"
set:
severity: "error"
- selector: "rule[id=no-any]"
set:
severity: "error"
- selector: "rule[id=prefer-const]"
set:
severity: "error"
exporters:
- agents-md
- cursorExpected outcome: Upstream align unchanged, your exports show severity: error, no align forking required, and easy to revert if needed.
Keywords: make warnings errors, upgrade severity, stricter rules, team standards, enforce warnings, error enforcement
Temporary migration
Problem: You’re doing a major refactoring and need to temporarily disable strict rules. Normally strict-null-checks is an error, but during migration you need to downgrade it to a warning. After migration completes, you’ll restore it to error. You want to track this as a temporary override.
Solution: Use overlays to temporarily relax rules with documented removal dates.
Configuration:
version: "1"
mode: solo
sources:
- type: local
path: "strict-align.yaml"
overlays:
overrides:
- selector: "rule[id=strict-null-checks]"
set:
severity: "warn"
- selector: "rule[id=no-explicit-any]"
set:
severity: "warn"
- selector: "rule[id=no-unsafe-assignment]"
set:
severity: "warn"
exporters:
- agents-md
- cursorExpected outcome: Strict rules temporarily relaxed, migration can proceed without breaking CI, overrides documented with removal date, and easy to restore strict rules later.
Keywords: disable strict rules, temporary relaxation, during refactor, migration period, gradual adoption, technical debt
Threshold adjustment
Problem: An upstream align has complexity thresholds that don’t fit your project. Upstream has max-complexity threshold at 10, but your legacy code needs a threshold of 20 while new code keeps 10. You need different thresholds without forking.
Solution: Use overlays to adjust thresholds for your project’s needs.
Configuration:
version: "1"
mode: solo
sources:
- type: local
path: "quality-align.yaml"
overlays:
overrides:
- selector: "rule[id=max-complexity]"
set:
check.inputs.threshold: 20
- selector: "rule[id=max-lines]"
set:
check.inputs.max: 500
- selector: "rule[id=max-params]"
set:
check.inputs.max: 6
- selector: "rule[id=max-depth]"
set:
check.inputs.max: 4
exporters:
- agents-md
- cursorExpected outcome: Complexity threshold adjusted for your project, line length limits customized, other rule parameters tuned, and no align forking required.
Keywords: complexity threshold, adjust limits, project-specific thresholds, tune parameters, code quality metrics
Autofix removal
Problem: An upstream rule has an autofix that’s too aggressive for your codebase. The prefer-const rule with autofix sometimes breaks code in complex scenarios. You want the warning but not the automatic changes.
Solution: Use overlays to remove autofix while keeping the check.
Configuration:
version: "1"
mode: solo
sources:
- type: local
path: "autofix-align.yaml"
overlays:
overrides:
- selector: "rule[id=prefer-const]"
remove: ["autofix"]
- selector: "rule[id=no-var]"
remove: ["autofix"]
- selector: "rule[id=arrow-body-style]"
remove: ["autofix"]
- selector: "rule[id=prefer-template]"
remove: ["autofix"]
exporters:
- agents-md
- cursorExpected outcome: Rule still checks for issues, autofix removed from exports, manual fixes only, and safer for complex codebases.
Keywords: disable autofix, keep check but remove autofix, risky autofix, manual fix only, safe refactoring
Gradual rollout
Problem: You’re rolling out new strict rules gradually over three weeks. Week 1: new rules as info, Week 2: upgrade to warnings, Week 3: upgrade to errors. You need to track rollout progress and control the phase.
Solution: Use overlays to control rollout phase with documented progression.
Configuration:
version: "1"
mode: team
sources:
- type: local
path: "new-standards-align.yaml"
overlays:
overrides:
# Phase 1: Info level (Week 1 - current)
- selector: "rule[id=strict-type-checking]"
set:
severity: "info"
- selector: "rule[id=no-implicit-any]"
set:
severity: "info"
# Phase 2: Warning level (Week 2 - uncomment when ready)
# - selector: "rule[id=strict-type-checking]"
# set:
# severity: "warn"
#
# - selector: "rule[id=no-implicit-any]"
# set:
# severity: "warn"
# Phase 3: Error level (Week 3 - uncomment when ready)
# - selector: "rule[id=strict-type-checking]"
# set:
# severity: "error"
#
# - selector: "rule[id=no-implicit-any]"
# set:
# severity: "error"
exporters:
- agents-md
- cursorExpected outcome: Rules rolled out gradually, team has time to adapt, clear progression path, and easy to track phases.
Keywords: progressive rule adoption, phased rollout, gradual enforcement, staged deployment, incremental adoption
Performance characteristics
Overlay application:
- O(n × m) where n = number of overlays, m = number of rules (typically < 100)
- Applied once during bundle merge, before export
- Selector matching uses fast string/regex operations
- No runtime overhead after application
Memory usage:
- Minimal overhead: ~200 bytes per overlay
- Applied overlays cached in memory during sync
- Tracked in lockfile for team mode drift detection
Best practices:
- Keep overlay count under 30 for optimal performance
- Use specific selectors over broad patterns
- Document temporary overlays with removal dates
- Run
aligntrue override statusto check health
Related documentation
- Customization Overview - When to use overlays vs plugs vs scopes
- CLI Reference - Complete CLI reference
- Plugs Guide - Stack-specific customization
- Scopes Guide - Path-based rule application
- Team Mode Guide - Overlay policies and approval workflows
- Drift Detection - Detect overlay staleness
- Solo Developer Guide - Solo workflow with overlays
- Team Guide - Team collaboration with overlays
Summary
Overlays let you customize without forking:
- Quick: Add overlay in 60 seconds
- Safe: Preserve upstream updates
- Flexible: Change severity, inputs, autofix
- Auditable: Dashboard and drift detection
- Team-ready: Approval policies and expiration tracking
When in doubt:
- Use overlays for align-level customization (severity, inputs)
- Use plugs for stack-specific values (test commands, paths)
- Use scopes for path-based rules (monorepo)
- Fork when you need fundamental changes
Start with overlays, graduate to forks only when necessary.