91ef69ed7b
Add `RandomBinder`, the by-name sibling to `SweepBinder`, so a random sweep (`RandomSpace`, C12.1) can be built by name against `param_space()` instead of by positional `Vec<ParamRange>` slot order. By-name resolution makes a same-kind transposition (e.g. swapping the I64 ranges for `fast.length` and `slow.length`) structurally impossible — the failure class `RandomSpace::new`'s positional validation passes silently. Direct structural mirror of `SweepBinder`: `Composite::range` opens the binder, `.range(name, ParamRange)` accumulates, `.sweep(count, seed, run)` resolves the named ranges via the shared `resolve_into` (new `resolve_ranges` caller) and runs the disjoint sweep. New `BindError::EmptyRange` mirrors `EmptyAxis`; `ParamRange::is_empty` homes the non-empty invariant the named layer pre-checks so `RandomSpace::new` cannot fail. closes #79