Severity: Medium
CSA bank-entry removal (energy cut) doesn't remap progression masks, and cluster admission can assign the admitted candidate the wrong cluster label — both are instances of the same underlying problem: multiple index-aligned views of the bank (entries, cluster labels, selection state, progression masks) are maintained by hand and can desynchronize under mutation.
1. Progression masks not remapped on removal — src/variopt/algorithms/population/csa/engine/tell.py:189-197,219-235 with banking/update/result.py:73-85
When reduce_bank_by_energy_cut removes entries, changed_indices/significant_update_indices are positional diffs between the pre-batch and post-removal banks (two different index spaces), and progression_state masks (refresh_mask, stage seed_mask/partner_mask) are never remapped for removals — only selection_state.remove_indices is.
Scenario: adaptive-refresh newcomer mask {0..k} active, energy cut removes index 2 → every masked index > 2 now points at a shifted entry; some newcomers become seedable early, some non-newcomers get masked; partner_mask is never cleaned by without_updated_seed_mask at all.
2. Cluster admission inherits the wrong label on far-update paths — src/variopt/algorithms/population/csa/banking/clustering/state.py:416-426 (register_admission)
When nearest_distance <= cluster_distance and the admission replaced a far entry (far-update path, or largest_cluster mode where remove_index is in a different cluster), the admitted candidate inherits the removed entry's label instead of labels[nearest_index].
Scenario: a candidate spatially inside cluster A replaces the worst entry of cluster B (largest-cluster mode) → gets labeled B; subsequent select_cluster_update decisions in the same observation batch compare/remove against the wrong cluster until the end-of-batch recluster repairs labels.
Fix direction
Remap all index-keyed progression masks with the same removal remapping already applied to selection state, and compute changed/significant indices before the removal step. For clustering, use labels[nearest_index] for the non-appended near-admission case. Longer term: consider a single "aligned bank views" abstraction that permutes/removes atomically across entries/labels/selection-state/masks, since this class of bug (see also the related adaptive-growth desync issue) keeps recurring at each new mutation site.
Severity: Medium
CSA bank-entry removal (energy cut) doesn't remap progression masks, and cluster admission can assign the admitted candidate the wrong cluster label — both are instances of the same underlying problem: multiple index-aligned views of the bank (entries, cluster labels, selection state, progression masks) are maintained by hand and can desynchronize under mutation.
1. Progression masks not remapped on removal —
src/variopt/algorithms/population/csa/engine/tell.py:189-197,219-235withbanking/update/result.py:73-85When
reduce_bank_by_energy_cutremoves entries,changed_indices/significant_update_indicesare positional diffs between the pre-batch and post-removal banks (two different index spaces), andprogression_statemasks (refresh_mask, stageseed_mask/partner_mask) are never remapped for removals — onlyselection_state.remove_indicesis.Scenario: adaptive-refresh newcomer mask
{0..k}active, energy cut removes index 2 → every masked index > 2 now points at a shifted entry; some newcomers become seedable early, some non-newcomers get masked;partner_maskis never cleaned bywithout_updated_seed_maskat all.2. Cluster admission inherits the wrong label on far-update paths —
src/variopt/algorithms/population/csa/banking/clustering/state.py:416-426(register_admission)When
nearest_distance <= cluster_distanceand the admission replaced a far entry (far-update path, orlargest_clustermode whereremove_indexis in a different cluster), the admitted candidate inherits the removed entry's label instead oflabels[nearest_index].Scenario: a candidate spatially inside cluster A replaces the worst entry of cluster B (largest-cluster mode) → gets labeled B; subsequent
select_cluster_updatedecisions in the same observation batch compare/remove against the wrong cluster until the end-of-batchreclusterrepairs labels.Fix direction
Remap all index-keyed progression masks with the same removal remapping already applied to selection state, and compute changed/significant indices before the removal step. For clustering, use
labels[nearest_index]for the non-appended near-admission case. Longer term: consider a single "aligned bank views" abstraction that permutes/removes atomically across entries/labels/selection-state/masks, since this class of bug (see also the related adaptive-growth desync issue) keeps recurring at each new mutation site.