- Shipped
- August 14, 2026 at 9:37 PM UTC
- Author
- kamo
- Commit
- 1f7cc39
The cascade highlight now travels the chain instead of flashing every affected row at once. enabledAncestors already arrives nearest-first, so the index IS the distance travelled up the tree and each row delays by 90ms behind the last — watching it move child to parent to grandparent is what teaches the rule, which a simultaneous flash reads as a glitch. Still instant under prefers-reduced-motion. Grant all / Remove all on a branch, shown only when they would change something. Routed through applyToggle per right rather than writing settings directly: a bulk action must not become a second implementation of the cascade rules that drifts from the single one in rightsHierarchy.ts. The granted/total pill is now always on a parent row rather than only when collapsed — it is the fastest read of what a branch actually grants. Also renders hierarchyHeading/hierarchyBody, which the previous commit added to the dictionary and then never used. Shown only above a group that actually has nesting; a banner that appears everywhere is one people learn to skip. rightsTreeForest.test.ts pins the anchoring rule the tree and the branch-types editor share: a right whose parent is filtered out of the current group attaches to the nearest PRESENT ancestor, or becomes a root. The other way round makes a grantable permission vanish from the editor with nothing to indicate it — and it is reachable in practice, because EDIT_QUOTE_TERMS is declared CRM while its parent MANAGE_QUOTES is POS.