depcruise-rule-alternative-disjointness

Validates that dependency-cruiser and esquery rule alternatives match disjoint sets via must-fail fixtures.

1|Updated Jun 9, 2026
One-click install
npx skills add https://github.com/VilnaCRM-Org/claude-plugins --skill depcruise-rule-alternative-disjointness-vilnacrm-org
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: depcruise-rule-alternative-disjointness
Source: https://github.com/VilnaCRM-Org/claude-plugins/tree/main/plugins/react-frontend-sdlc/skills/depcruise-rule-alternative-disjointness
Command: npx skills add https://github.com/VilnaCRM-Org/claude-plugins --skill depcruise-rule-alternative-disjointness-vilnacrm-org

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Architecture rules written as several alternatives (dependency-cruiser forbidden rules or esquery no-restricted-syntax selector unions) silently rot when one alternative is a superset of another: deleting the narrower alternative changes nothing, no fixture can pin it, and the rule looks healthy while a branch is dead. This Skill detects and prevents that overlap. ## Core Features & Use Cases - Disjointness verification: Ensures each alternative in a rule matches a disjoint set by having later alternatives negate what earlier ones already claim, with the node type anchored before negation chains. - Fixture-based rule-rot guards: Requires at least two must-fail fixtures per alternative so deleting any single alternative makes a fixture stop failing, plus bidirectional completeness assertions between rules and fixtures. - Documented-overlap governance: Rules that legitimately co-fire are listed in a reviewed overlap map in both the fixture file and the test, so widening the map to hide a regression stays visible. - Use Case: When adding a new import-shape alternative to a no-restricted-syntax union in config/di-collaborator-policy.js, narrow the side-effect catch-all so it excludes default, namespace, and named specifiers, then add fixtures proving each branch still fires. ## Quick Start Check whether the alternatives in my .dependency-cruiser.js forbidden rules and esquery selector union are disjoint, and add must-fail fixtures for any alternative that cannot currently be pinned.

Frequently Asked Questions about depcruise-rule-alternative-disjointness

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I keep dependency-cruiser rule alternatives from overlapping?▼

Make each later alternative negate what earlier alternatives already claim, so every branch matches a disjoint set. Then prove it by deleting any single alternative and confirming at least one must-fail fixture stops failing.

How do I write a side-effect import selector in esquery without swallowing other import shapes?▼

Anchor the node type first, then negate: start with ImportDeclaration and chain :not(:has(ImportSpecifier)), :not(:has(ImportDefaultSpecifier)), and :not(:has(ImportNamespaceSpecifier)). An unprefixed :not(:has(...)) matches nearly every node in the file.

Why does my dependency-cruiser fixture guard pass even when rules are broken?▼

The programmatic cruise() API returns zero violations unless called with validate: true, so the guard passes vacuously without it. Also strip tsConfig from fixture options so path aliases do not resolve out of the sandbox.

How many fixtures does each rule alternative need?▼

At least two must-fail fixtures per alternative, one per context the selector must work in, such as a project-relative specifier and a third-party library specifier. One fixture per rule leaves partial regressions green.

When is this disjointness check not needed?▼

Skip it for single-alternative rules, since one fixture already pins the whole rule. It targets rules built from several alternatives where a superset branch can hide a dead subset branch.