pub fn assign_layers(
graph: &Graph,
labels: &[String],
matches: impl Fn(usize, &str) -> bool,
) -> Result<(Vec<Layer>, Vec<String>), String>Expand description
Assign each workspace member to a layer by the matches(index, name)
predicate. Returns the layers (label + member ids, input order preserved)
and the names of members matching no layer. Errors when a member matches
more than one layer — an ambiguous spec, not a clean pass.