#613 fixed adaptive_classifier.rs:94 (the IQR sort) and called the audit
done, but the grep used `partial_cmp(b).unwrap()` as a literal and missed
seven additional production sites that use comparator variants:
adaptive_classifier.rs:205 AdaptiveModel::classify() argmax over softmax
probs — same per-frame hot path as #611.
NaN flows through normalise → logits → softmax
and still reaches this site even after the
IQR fix.
adaptive_classifier.rs:480 train() argmax (training accuracy loop)
adaptive_classifier.rs:500 train() per-class argmax
main.rs:2446, 2449 count_persons_mincut variance source/sink select
csi.rs:602, 605 count_persons_mincut variance source/sink select
(duplicate of main.rs logic in csi.rs)
For the variance-select sites, note that the *outer* `unwrap_or((0, &0))`
only catches an empty iterator — it cannot rescue a panic raised inside
the comparator. A single NaN in `variances[]` still aborts the process.
Same fix as #613: swap `.unwrap()` for `.unwrap_or(std::cmp::Ordering::Equal)`
inside the comparator closure. Pure behavioural change, no API surface.
Re-audit of the remaining `partial_cmp(...).unwrap()` matches in v2/:
they are all inside `#[cfg(test)]` / `#[test]` blocks (spectrogram.rs:269,
depth.rs:234, connectivity.rs:477, vital_signs.rs:737) where inputs are
controlled and panic-on-NaN is acceptable.