EVOLUTIONARY SEARCH / SELECTOR REVIEW
Scope: supplied source only; no hardware run, no claims about measured efficacy.
Paths below are relative to full_code_review/source/. GA = Module/GeneticAlgorithm_05.h; ES = Module/EvolutionarySelector_02.h; H = SampleTestIntegrationCode_v35.cpp; CM = Module/ConfigManager.h.

ACTIVE CODE AND ARCHITECTURE
The active GA is GA12–2799 (class through1400, out-of-class implementation through2799); later copies are commented history. The active selector class is ES35–1289; the later class copies are commented history (there is an innocuous active repeated #include at1301). Read comments as intent, not implementation evidence.

The implemented architecture is a persistent evolutionary/Pareto population, online workload-conditioned surrogate learning, one GA-owned AWM, and one persistent selector-owned Scheduler/ThermalGovernor/RuntimeControls path. ES602–603 owns Scheduler and GA; GA864–902 owns population, RNG, generation, mutation history, AWM, surrogate and temporal credit. There is no implemented policy/value-network/replay learning in these files: seedRLReplayBuffer merely counts/logs rank-0 members (GA1808–1818). This does not detract from the explicitly intended surrogate-learning architecture, but “RL replay seeding” should not be described as an implemented training mechanism.

ACTIVE CONTROL/DATA FLOW
1. Selector waits for pipelineReady, then configured warmup (ES644–660). It reads aggregator -> converted snapshot (ES711;1033–1147): FPS=algorithm FPS; processing time separate; power=5 accepted-poll moving average; temperature normalized from possible millidegrees; fitness/surrogate latency=endToEndLatencyMs (1125–1126), not inferenceTimeMs.
2. Invalid/usefulness checks happen before evolution (ES713–731;1280–1287). Freshness requires positive frameId greater than lastEvolvedFrameId (754); workload provenance requires current worker epoch and processedFrame >= snapshot.frameId, plus a posttransition provenance floor (771–815). These gates prevent repeated-frame generations and many old-workload rows. They do NOT prove that this frame started after the preceding action or that meter/temperature samples belong to that action.
3. Under gaMutex, ES847 calls ga_->evolve(snapshot) using default creditPreviousAction=true and previousActionStalled=false. GA524–527 checks snapshot stability unless explicitly passed a stall. stableFramesRequired counts successive evolve calls with useful snapshots, not a physical settling period (GA1845–1858).
4. AWM updates from the measured snapshot and fixed performanceTargetFps (GA547–556); evaluatePopulation credits last requested genome to current snapshot, if hasLastApplied (1085–1101), predicts each candidate and computes its constraint/objective/scalar state (1105–1250).
5. Constraint-aware nondominated sort + per-front crowding (GA1968–2047), then deployment selection (2311–2387). Selected candidate is copied before population mutation (617), applied through Scheduler (627;2428), action epoch generation+1 is published after apply (2434–2442), and full evaluated population is exported before replacement (638).
6. Mutation rate adapts using the selected feasible scalar fitness or negative least violation (657–664); a rank-0 logging-only replay hook runs (686). reducePopulation truncates the evaluated mating pool, elite/offspring generation refills configured popSize, mode diversity is enforced, and population is replaced (694–702). Action export occurs after timings finalize and generation increments (723–727).

SEARCH SPACE AND EXACT DECISION RULES
Genome: mode MAX/BALANCED/LOW; target FPS; power budget; GPU preference; CPU max frequency; GPU split. Initial target uniform[min,max], modes guaranteed once each when possible, GPU Bernoulli.65, budget integer3–7W, clocks {102000,403200,921600,1132800,1479000}kHz, split uniform[0,1] before workload canonicalization (GA1860–1903). CPU-only disables GPU/split; binary workloads collapse split to0/1; MAX always gets fixed performanceTargetFps (GA970–1005).

All four objectives are minimized (GA1257–1322):
  FPS: -clamp(predFPS/performanceTargetFps,0,2) only when AWM current regime=HIGH_PERFORMANCE; otherwise -1/(1+abs(predFPS-target_fps)). Outside that regime it is target matching, not monotonic throughput maximization.
  Power: predPower/10 in surrogate mode. Legacy CSV obj_energy means normalized watts, not joules/frame. Surrogate-off instead discounts measured power by frequency/max-frequency and concurrency (1294–1303).
  Temperature: max(0,predCPUtemp-onsetCPU)/20 in surrogate mode; GPU measured penalty is additionally included only when surrogate is off (1304–1313).
  Latency: predicted aggregated E2E latency/50.
Scalar fitness = (-sum(w_i*objective_i)+legacy GPU bonus)*0.985^(age/50)+explorationBonus-stallPenalty (GA2140–2189;1245–1249). Fixed configured weights are replaced entirely by AWM weights when enabled (2149–2153); this is not a multiplication by fixed weights. GPU bonus .05 only exists surrogate-off at15<gpuUtil<85. Age increments each evaluation (1250).

Feasibility: exact-bucket timeout violation requires >=3 attempts and timeoutRatio>.5 by defaults (GA1178–1185); LOW prohibited when measured FPS<.7*fixed target with physically valid power below batteryCritical-.5W and both temperatures below warning-2C (1194–1221); MAX prohibited above either critical thermal threshold (1228–1238). Violations sum. Feasible dominates infeasible; among infeasible, lower violation dominates; within equal violation ordinary Pareto domination applies (1412–1435).

Deployment selects highest scalar-fitness evaluated feasible rank0, with feasibility-first defensive fallback; if all candidates infeasible, smallest finite violation wins, then rank, then fitness (GA2311–2387). “Hard feasibility” is thus relative admissibility, not an absolute guarantee never to emit an infeasible action; downstream thermal safety remains essential.

Parents/elites use rank ascending, crowding descending, NOT scalar fitness (GA273–275;2039–2047;1580–1592;2109–2134). Tournament draws3 with replacement. Crossover probability is respected; target/budget/split averaged, mode/GPU/frequency inherited (1443–1499). Mutation is per-child probability, then FPS N(0,4), GPU flip25%, budget mutation30% N(0,.5), continuous split N(0,.15), neighboring clock step, mode redraw7% (1506–1556). Copied-parent offspring reset age/evaluation; elites retain age (1580–1618). Mode diversity repairs missing modes by replacing a donor with >1 member and anchoring clocks/MAX target, retaining other genes (1632–1707).

This uses NSGA-II ranking/crowding operators but is not full parent-plus-offspring NSGA-II environmental selection: only configured elites survive, children are first evaluated next tick. There is no retained external Pareto archive. The persistent object stores the current population, not every past nondominated solution. Reduction after generation10 only reduces the parent pool, preserving all rank0 members/minPop; offspring immediately refill popSize (1710–1734;1590–1619). Thus evaluated population ordinarily remains fixed-size, and the generic undersized diversity injector is ordinarily inactive (1737–1751). explorationDecay is declared/parsed (GA58;ES137) but never used in active behavior.

PERSISTENCE / TRANSITION
ES378–414 raises pause and acquires the mutex barrier; worker swap is outside this file; commit checks active worker epoch, changes GA workload in place, installs provenance floor and releases pause (416–472). GA446–501 preserves object, generation, current population, RNG, adaptive mutation state and AWM object/history, changes workload ID/capabilities/prior, switches retained surrogate bank and remembered best-measured-FPS per workload, canonicalizes physically invalid genes, and clears ONLY last-action credit. It does not reset population or AWM on recurrence. The preserved current population can nevertheless have evolved away from an earlier workload's useful genomes, and canonicalization can irreversibly lose genes; only surrogate banks constitute explicitly workload-indexed memory. One global mutation progress baseline crosses AWM objective/regime and workload changes; its numerical improvement can reflect changed scoring/context rather than improved control (GA657–664;1913–1950).

CONFIGURATION: SOURCE DEFAULTS VERSUS HARNESS ASSIGNMENTS
Parameter                 GAConfig      Selector absent-key     Harness ERL assignment
population/min/elite      12/6/3        12/4/2                  8/4/2
crossover/mutation        .75/.18       .70/.15                 .70/.15
control interval          800ms         500ms                   800ms
AWM enabled               false         false                   true, interval5gens
evidence export           false         true                    true
Sources: GA53–64,155–156; ES132–140,198–209,223; H644–650,695,726–747. Adaptive mutation=true/cap.35; surrogate=true/exploration.15; target20–60/fixed reference60; default seed-1 nondeterministic (GA66–89,160–180;ES143–176,213–220). H's targetFPS30 at692 is not the GA's fixed target; GA uses ga_performance_target_fps or ga_max_target_fps. Dynamic mission sets selector warmup0 and explicit initial workload/prior (H1464–1476), using external hold instead.
These are source-level defaults/assignments, not reconstructed final experiment parameters: external base JSON is absent. CM327–330 merges EvolutionarySelector keys OVER Scheduler keys, so supplied base configuration can shadow harness Scheduler assignments. ES ctor takes awmCfg but does not use it; it reconstructs GA AWM settings from merged JSON (ES42–46,254–275), making direct caller-provided awmCfg ineffective. Some GAConfig knobs have no active selector JSON binding, including timeout feasibility controls and surrogateMinSupport/coldFPS/capRatio; their GA defaults apply unless code/caller changes.

PRIORITIZED FINDINGS / EVIDENCE LIMITATIONS
EVO-01 HIGH: Recovery contaminates temporal credit. Watchdog recoverFast (ES694), or invalid-data recovery (726), changes real controls without GA.notifyExternalOverride (GA433). Last requested genome is retained, and next useful snapshot is credited to that genome (GA1085–1101). The controller can teach that a previously starving request achieved the recovery configuration's output. Fix the recovery path to close/invalidate credit and synchronize a fresh action/evidence epoch; capture effective applied/readback configuration for training.
EVO-02 HIGH: Timeout feasibility path is dormant in the active integration. Only call is ES847 evolve(snapshot); previousActionStalled is always default false (GA513–515). Consequently observeStarvation1093 is never reached through this selector, while watchdog bypasses evolution on stale data. The claimed repeated timeout constraint cannot learn these real stalls. Add an actual bounded evidence-window state machine that reports timeout exactly once to the correct effective action and keeps recovery evidence separate.
EVO-03 HIGH causal limitation: fresh frame/workload provenance is weaker than action-conditioned evidence. ES754/771–815 does not compare a frame's action epoch to the last action, require a post-apply start timestamp or settle interval. Pipeline backlog, overlapping sensor windows, retained 5-poll power average and thermal lag can mix actions. The pilot hook explicitly labels the assigned window/settings state unknown (ES832–834). Report online association/model-guided adaptation, not isolated causal effects of requested configurations, until action-window alignment is verified. See surrogate and actuation reviews for additional requested/applied mapping divergence.
EVO-04 MEDIUM: Aging sign inversion. Multiplication by factor<1 increases negative fitness toward0 (GA2173–2174). An old rank0 tradeoff with base-.20/age500 scores-.171946 and beats a fresh rank0 tradeoff with superior unaged scalar-.19. This rewards age precisely in a negative-utility region and can preserve stale elites. Use an explicit nonnegative age penalty or a monotonic transformation with documented semantics. Reproduced by source-extracted compiled scalar function; see test below.
EVO-05 MEDIUM: Live selected-action accessor depends on CSV success. lastSelectedEval_ is populated only after evidence-enabled check and successful file-open in exportSelectedActionEvidence (GA2639–2647,2677–2692). Disabling export or I/O failure leaves getLastActionEpoch/lastSelectedEvaluation stale while real evolution/actuation continues, damaging pilot IDs and prediction tickets (ES844–897). Capture decision state in apply/evolve regardless of export; let exporters read it.
EVO-06 MEDIUM interpretation: Surrogate-off is not a single-mechanism ablation. It changes power objective arithmetic, adds measured GPU temperature and a GPU bonus, disables timeout evidence learning and exploration/stall terms (GA1085,1125–1187,1294–1313,2165–2168). An ON/OFF comparison estimates that combined package, not only learned-vs-unlearned prediction.
EVO-07 LOW/API: getBestAction() reselects from the already-replaced population after evolve (GA782–787;702), so may differ from the dispatched selectedCopy. Current pilot uses lastSelectedEvaluation as intended mitigation (ES889), subject to EVO-05; CM725 still exposes getBestAction for other clients. Separate best-search-candidate versus last-applied-action APIs.
EVO-08 LOW selection detail: crowding marks first/last points infinite before checking zero range (GA2084–2092). An objective that is constant across the entire front therefore grants arbitrary boundary privileges, affecting elitism/tournaments even though that dimension supplies no diversity information. Skip constant objectives before marking boundaries.

No actual supplied full GA/selector header compilation was performed by this reviewer; dependencies are hardware-heavy. No hardware access/run. No source files modified. Standalone test evolution_scalar_repro.py extracts the verbatim GA2140–2190 member into minimal stub types, compiles with g++-std=c++17 and executes. It is stronger than a rewritten numerical emulation but is not full-header/integration verification. Test passed; artifacts evolution_scalar_repro.cpp and evolution_scalar_repro_result.json. The rank0-compatible vectors are old[0,.4,0,0] and fresh[-.05,.48,0,0]; neither dominates the other, making the demonstrated age reversal relevant to scalar rank0 deployment. Source extraction has explicit range/name check.
