Actionable findings from a deep codebase analysis (July 2026). Items grouped into incremental steps so each step leaves the project in a strictly better state.
-
cmaes_sigmamissing fromget_params()/set_params()(auto.py:1117–1165).GridSearchCVformode="cmaes"silently fails becauseget_params()omitscmaes_sigmaandset_params()rejects it withValueError. - CuckooSearch
alphawired tolevy_scaleinstead of its own parameter (auto.py:718). The backend constructor receivesalpha=levy_scale, so the user cannot control the CSalphaindependently. - BFO always accepts every candidate (
continuous.rs:~1117). The conditioncandidate_score <= scores[i] + 1e-12is always true when the first clause fails, eliminating selection pressure. -
DiscreteProblem::evaluate()panics on out-of-range tour indices (problem.rs:61–62). Af64→usizecast with no bounds check can OOB thedistance_matrix. - MOPSO personal-best update overly permissive (
advanced.rs:751–758). Non-dominated solutions always replacepersonal_best, causing fluctuation. - Python
AutoColonyscore()in compatibility mode returns-best_score(auto.py:940). Hard-codes sign convention; breaks ifbest_scoreis negative. -
check_graph_adjacencyraises semantically wrongBoundsErrorfor sparse input (utils.py:113).
-
cmaesmode: zero tests at any layer. Addtests/test_cmaes.pywith direct binding +AutoColonyfacade tests. -
bfomode: no functional test (only appears in param-grid assertions). -
BinaryParticleSwarm: registered but untested. - Rust
continuous.rs: add#[cfg(test)]for GWO, FA, SA, CS, BA, GSO, BFO, DE, CMA-ES (9 algorithms, zero Rust unit tests). - Rust
advanced.rs: add#[cfg(test)]for PermutationGA, NSGA-II, MOPSO. - CLI: zero test coverage for all 4 subcommands (
optimize,benchmark,report,list). - Error-case tests: predict-before-fit, bounds violations, reproducibility, bad-objective rejection — only covered for PSO/ABC/ACO; missing for GWO, FA, SA, CS, BA, GSO, BFO, DE, CMA-ES.
- CMA-ES is not real CMA-ES (
continuous.rs).- Diagonal-only covariance (cannot model axis rotation).
- Hardcoded
sigma *= 0.99decay instead of cumulative step-size adaptation. Either implement proper CSA + full covariance, or document as "separable CMA-ES with fixed schedule" and rename to avoid misleading users.
- Cuckoo Search Levy flight uses same step for all dimensions
(
continuous.rs:604–605). Draw independentu/vper dimension. - Bat Algorithm pulse-rate update formula is non-standard
(
continuous.rs:801). The compoundingpulse[i] *= 1 - exp(-gamma * (t+1))does not match the canonical BA. - MOPSO personal-best replacement logic (
advanced.rs:751–758): tighten to only replace whencurrentdominatespersonal_best. - ABC single food-source degeneracy (
abc.rs:63): whensn == 1the mutation produces the same point; no progress made. - ABC
selection_fitnessfor negative objectives (abc.rs:87–93):1.0 + abs(objective)can give enormous weight to highly negative values. Use a bounded transformation or shift by the minimum. - ACO pheromone update for ACS variant (
aco.rs:213): standard ACS uses local + global-best-only updates; the current code applies full global update (all ants + elitist) to all variants.
- Extract
make_rng(seed: Option<u64>) -> StdRnghelper — the sameStdRng::seed_from_u64/StdRng::from_entropypattern is duplicated 12+ times. - Consolidate validation boilerplate in
continuous.rs— ~25 identical lines at the start of everyfit()(dimension check, range computation, init). Move into a helpervalidate_and_init(). - Prevent
partial_cmp().unwrap()panic on NaN fitness — replace.unwrap()with.unwrap_or(std::cmp::Ordering::Equal)or usef64::total_cmp. - Make
history/populationfieldspub(crate)or private with accessors — currently public in allcontinuous.rsstructs, breaking encapsulation. - Add
#[derive(Debug)]to all algorithm structs — missing on BeeColony, GreyWolfOptimizer, FireflyOptimizer, SimulatedAnnealing, CuckooSearch, BatAlgorithm, GlowwormOptimizer, BacterialForagingOptimizer, DifferentialEvolution, CmaEsOptimizer. - Add
ClonetoOptimizationError(base.rs). - Handle multi-
fit()calls — ensurehistory/populationvectors are cleared on each call.
- Replace 8× parameter enumeration with a registry dict (
auto.py).__init__,get_params,set_params,_filter_params,_create_algorithm,parameter_mapping,suggest_parameters, anddefault_param_gridseach repeat the same ~50 params. A single_ALGORITHM_PARAMSdict per algorithm would be the source of truth. -
_detect_problem_typereturns"sklearn"— an internal mode leaked into the public API (auto.py:203).recommend_algorithm()can returnmode: "sklearn", which is not in_valid_modesand breaks_create_algorithm. -
parameter_mapping()is dead code (auto.py:258–355) — never called internally. Remove or wire it in. -
resolve_parameter_conflictsstores ignored params but never exposes them (auto.py:622–632). Either surface them or remove. -
diversity_score()has unreachable dead branch (auto.py:964–966). -
optimization_metricsreturns"best_score"that can be negative MSE (auto.py:987–994) — sign semantics differ between optimization and compatibility mode.
- Bump minimum
scikit-learnto 1.4 (or add version-gated code paths).__sklearn_tags__requires ≥1.6;validate_datareturning(X, y)requires ≥1.4. Currentscikit-learn>=1.0is wrong. - Eager native import (
__init__.py:19):from . import _colonyxloads the Rust module at import time. A missing.soblocks all package imports (even Python-only benchmarks). Switch to lazy import (pattern already used in_create_algorithm).
-
BinaryPSO,NSGA-II,MOPSOdo not implementOptimizer— they havefit_with_objective()instead offit(&mut self, &dyn Problem), so they cannot be used through the uniform trait. Either:- Extend the
Optimizertrait to support multi-objective (breaking change), or - Keep the separate method but add a uniform dispatch layer in bindings.
- Extend the
- Add
predict()/score()to MOPSO — currently has neither.
-
paired_significance_testreturns boguspvalue=1.0when scipy is absent (metrics.py:338). RaiseImportErrorwith a clear message instead. -
profile_callablereads non-existent attributes, always returns NaN (metrics.py:62–65). Document that__profile_*attrs must be pre-set, or set them insideprofile_callableitself. - CLI: no error handling for per-mode failures in batch benchmarks
(
cli.py:92–169). A single failing mode crashes the entire benchmark. - CLI: massive duplication between
_run_benchmarkand_run_report(cli.py:92–169). Extract shared logic. - CLI: hardcoded mode lists duplicated (
cli.py:42,95,117). Share a constant.
- Dead code:
BoundConstraintenum (bounds.rs:82–92) — never referenced. -
n_iterationsfield ignored by BFO (continuous.rs). The outer loop usesn_reproduction_steps;n_iterationsis stored but never read. - ACO
get_paramsomitsuse_two_opt,variant,q0,elitist_weight,tau_min,tau_max(aco.rs). -
cmaesomitted fromdefault_param_grids()(auto.py:1033–1047). -
SolutionSet::find_best()returns first element when all fitnesses areNone(solution.rs:59–77). Should returnNone. -
SolutionSet::get_best()can return stale index — no bounds check afternext_generation()resets it. - Rust
Bounds::clamp()silently skips extra dimensions (bounds.rs:56). - Python
check_optimization_problemmisclassifies any square 2D array as "discrete" (utils.py:135–141). Add an explicit heuristic or require the user to specify problem type. -
benchmark_suite()returns fixed-arity (1D) problem definitions only (benchmarks.py:75–118)._expand_boundsis private incli.py. - CLI CSV output missing trailing newline (
cli.py:158). -
robustness_score()division-by-near-zero edge case (auto.py:978–985). - Schwefel benchmark
optimumprecision truncated (benchmarks.py:116). -
paired_significance_testonly supports parametric t-test — add Wilcoxon signed-rank for non-normal benchmark scores.