Skip to Content

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 hash

Result: 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 align

When 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 severity

Advanced overlay

overlays: overrides: - selector: "rule[id=max-complexity]" set: severity: "warning" "check.inputs.threshold": 15 # Nested property with dot notation remove: - "autofix" # Disable autofix

Note: 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 selectors

Sample 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.version

Use 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 autofix

Severity 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 array

Combined 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 error

Workflow:

# 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 sync

Scenario 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": true

Result: 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 warning

Workflow:

# 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 --ci

Scenario 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 framework

Overlay workflow:

# 1. Review current overlays aligntrue override status # Check overlay health # 2. Sync with overlays applied aligntrue sync # 3. Overlays are applied on each sync

Result: 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 above

Resolution: 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 applied

If rule ID changed upstream:

  1. Remove old overlay: aligntrue override remove 'rule[id=old-name]'
  2. Add new overlay: aligntrue override add --selector 'rule[id=new-name]' --set severity=error

If overlay now redundant (upstream matches your override):

  1. Verify match: aligntrue override diff
  2. 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 latest

See 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 autofix

View overlays

# Dashboard of all overlays aligntrue override status # JSON output for CI aligntrue override status --json

Diff overlays

# Show effect of specific overlay aligntrue override diff 'rule[id=no-console-log]' # Show all overlay effects aligntrue override diff

Remove 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]' --force

Integration with other commands

# Sync applies overlays automatically aligntrue sync # Check overlay status anytime aligntrue override status

See 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 upstream

Document 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 drift

For solo developers

  1. Use for experimentation - Try different severity levels
  2. Temporary adjustments - Disable strict rules during refactoring
  3. Document decisions - Add comments explaining why
  4. Clean up - Remove overlays when no longer needed

For teams

  1. Require approval - PR review for overlay changes
  2. Document ownership - Add owner comments
  3. Set expiration dates - Review temporary overlays
  4. Audit regularly - Monthly overlay review
  5. Validate in CI - Run aligntrue override status in CI

Troubleshooting

Overlay not applied

Symptom: Overlay defined but check still uses upstream settings.

Diagnosis:

aligntrue override status # Look for "Healthy: no" entries

Common causes:

  1. Typo in rule ID
  2. Rule no longer exists in upstream
  3. 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 effect

Fix: 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 effects

Fix: 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 rules

Overlay 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/*.md remains 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/status to 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 status shows “Healthy: yes”
  • aligntrue override diff shows 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

LocationVisibilityNotes
Lockfiles (team mode)Always visibleoverlay_hash and modified values stored
aligntrue override statusAlways visibleShows active overlays and their effects
aligntrue override diffAlways visibleShows before/after comparison
Inline content mode exportsVisible in rendered contentFull rule content includes metadata
JSON/structured exportsVisible in metadata fieldsMachine-readable format preserves all fields

Where overlay changes are NOT visible

LocationVisibilityReason
Link-based AGENTS.mdNot visibleLinks point to files, don’t include metadata
Link-based exportsNot visibleMarkdown links don’t render 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 guidelines

These links point to the canonical rules but don’t embed metadata like severity. The overlay still affects:

  1. Check behavior - The in-memory IR has the modified severity (even if exports omit metadata)
  2. Lockfile hashes - Team mode tracks the overlay
  3. CLI commands - aligntrue override status shows the change

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 inline

Using inline mode to see metadata

If you need metadata visible in exports, use inline content mode:

aligntrue sync --content-mode inline

Or configure in .aligntrue/config.yaml:

sync: content_mode: inline

This embeds full rule content including metadata in AGENTS.md.

Scenarios

Real-world examples showing how to use overlays for fork-safe customization:

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 - cursor

Expected 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 - cursor

Expected 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 - cursor

Expected 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 - cursor

Expected 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 - cursor

Expected 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 status to check health

Summary

Overlays let you customize without forking:

  1. Quick: Add overlay in 60 seconds
  2. Safe: Preserve upstream updates
  3. Flexible: Change severity, inputs, autofix
  4. Auditable: Dashboard and drift detection
  5. 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.

Last updated on