Diff Engine Rules
1. Properties (Props)
| Change (Engine) | What & How the Engine compares | Severity | What the Analyzer evaluates / Reasoning |
|---|---|---|---|
| Removed | Property exists in from but not in to. | MAJOR | Code consumers will lose a property they might have been using. Breaks the contract. |
| Added | Property exists in to but not in from. | MINOR | It’s a safe addition (backward compatible). |
| Rename (Heuristic) | Number of removals = number of additions, and NO modified props. | MAJOR | If a prop is removed and another comes in (with clean counts), it assumes a rename. Breaks consumers looking for it by name. |
| Modified (Type Change) | Recursively compares the body, ignoring sortIndex. If there are diffs, it marks as modified. The Analyzer reads the type. | MAJOR | If the property’s type changed, it breaks type definitions. |
| Modified (Enum Removed) | Both are EnumProp. The Analyzer compares arrays and notices a missing option in the new version. | MAJOR | If you removed a possible value (e.g., removed size="small"), designs using it will break. |
| Modified (Enum Added) | Both are EnumProp. The Analyzer notices new options but none removed. | MINOR | New allowed values for a property are backward compatible. |
| Modified (Default/Config) | The object differs, but the type is the same and no enum options were removed. | MINOR | Changing a default value doesn’t break the API, it just alters how it starts by default. |
2. Anatomy (Sub-nodes and Nested Instances)
| Change (Engine) | What & How the Engine compares | Severity | What the Analyzer evaluates / Reasoning |
|---|---|---|---|
| Removed | The anatomy node’s key no longer exists in the new spec. | MAJOR | If an internal structural element disappeared, it counts as a breaking change (assumed lost slot/structural layer). |
| Added | New key appeared in the anatomy spec. | MINOR | New structural elements (new layers) are expansions. |
| Modified (Instance Swap) | Compares AnatomyElement objects (ignoring detectedIn). The Analyzer checks if instanceOf mutated to a different ID. | MAJOR | If you swapped the nested dependency of a component for a different one, it’s breaking (inheritance contract changed). |
| Modified (Generic) | The anatomy object mutated, but instanceOf remains the same or null. | MINOR | Minor structural mutation detected (e.g., renaming an internal layer). |
3. Variant Configurations
| Change (Engine) | What & How the Engine compares | Severity | What the Analyzer evaluates / Reasoning |
|---|---|---|---|
| Removed | Builds an ID using combinatorics (e.g., state=hover|size=large). If that ID is gone, it was removed. | MAJOR | If designers deleted an exact configuration from the variant grid, frontend consumers will fail. |
| Added | New combinatorial signature detected in to. | MINOR | Adding cells to the variant grid is backward compatible. |
| Modified | If the signature exists in both, the Engine compares the Variant object. If it differs even slightly, it marks it modified. | MAJOR | If you touched anything structural or visual of an existing variant (e.g., paddings, layer names), the visual contract changed abruptly. |
4. Styles and Base Tokens (Default)
| Change (Engine) | What & How the Engine compares | Severity | What the Analyzer evaluates / Reasoning |
|---|---|---|---|
| Token Regression | If in the old version the value was a TokenReference ($dtcg alias) and in the new version is a raw value (hex/string). | MAJOR | The designer “unlinked” (broke) the binding against the design system. Serious architectural error. |
| Modified / Added / Removed | Changes in the final style value (different padding, different color, but without unlinking variables). | MINOR | Direct visual adjustments are categorized as evolutions without breaking signatures. |