From e2963cbcbaf8cdab763efd3818f5742de8c041ef Mon Sep 17 00:00:00 2001 From: johba Date: Sun, 22 Mar 2026 05:47:34 +0000 Subject: [PATCH 1/2] fix: `fitness_flags` not propagated to manifest entries for newly admitted candidates (#990) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two changes in evolve.sh pool-admission code: 1. Include `fitness_flags` from evaluator JSONL in the manifest entry dict for newly admitted candidates (~line 866-874). Previously the field was omitted, so downstream `effective_fitness()` could never zero-rate a new candidate. 2. Use `effective_fitness(entry)` when appending new candidates to the evolved ranking list (~line 907), so ZERO_RATED_FLAGS defence applies at first admission — not only when re-ranking existing entries. Co-Authored-By: Claude Opus 4.6 (1M context) --- tools/push3-evolution/evolve.sh | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tools/push3-evolution/evolve.sh b/tools/push3-evolution/evolve.sh index 6b771b8..db0067c 100755 --- a/tools/push3-evolution/evolve.sh +++ b/tools/push3-evolution/evolve.sh @@ -834,7 +834,8 @@ for fname in sorted(os.listdir(output_dir)): f'candidate_{int(cand_str):03d}.push3' ) if os.path.exists(push3_path): - qualifying.append((fitness, push3_path, gen_idx, cand_str)) + flags = d.get('fitness_flags', '') + qualifying.append((fitness, push3_path, gen_idx, cand_str, flags)) except (json.JSONDecodeError, ValueError, TypeError, AttributeError): pass @@ -844,7 +845,7 @@ qualifying.sort(key=lambda x: x[0], reverse=True) new_items = [] # (fitness, push3_path, manifest_entry) seen = set(existing_hashes) -for fitness, push3_path, gen_idx, cand_str in qualifying: +for fitness, push3_path, gen_idx, cand_str, flags in qualifying: h = file_hash(push3_path) if h in seen: continue @@ -864,13 +865,14 @@ for fitness, push3_path, gen_idx, cand_str in qualifying: break counter += 1 entry = { - 'file': filename, - 'fitness': fitness, - 'origin': 'evolved', - 'run': run_id, - 'generation': gen_idx, - 'date': today, - 'note': f'Evolved from {seed_name} (run{run_id} gen{gen_idx})', + 'file': filename, + 'fitness': fitness, + 'fitness_flags': flags, + 'origin': 'evolved', + 'run': run_id, + 'generation': gen_idx, + 'date': today, + 'note': f'Evolved from {seed_name} (run{run_id} gen{gen_idx})', } new_items.append((fitness, push3_path, entry)) @@ -903,7 +905,7 @@ pinned = [(effective_fitness(e), e, None) for e in existing evolved = [(effective_fitness(e), e, None) for e in existing if e.get('origin') == 'evolved'] for fitness, push3_path, entry in new_items: - evolved.append((fitness, entry, push3_path)) + evolved.append((effective_fitness(entry), entry, push3_path)) evolved.sort(key=lambda x: x[0], reverse=True) admitted_evolved = evolved[:MAX_EVOLVED] From abac7f7ed77896c2467f75ef71b75b7c5d1b2d77 Mon Sep 17 00:00:00 2001 From: johba Date: Sun, 22 Mar 2026 06:02:20 +0000 Subject: [PATCH 2/2] fix: use None instead of '' for absent fitness_flags to match schema Review feedback: d.get('fitness_flags') without a default preserves the null vs absent distinction mandated by the manifest schema (string | null). Co-Authored-By: Claude Opus 4.6 (1M context) --- tools/push3-evolution/evolve.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/push3-evolution/evolve.sh b/tools/push3-evolution/evolve.sh index db0067c..8833080 100755 --- a/tools/push3-evolution/evolve.sh +++ b/tools/push3-evolution/evolve.sh @@ -834,7 +834,7 @@ for fname in sorted(os.listdir(output_dir)): f'candidate_{int(cand_str):03d}.push3' ) if os.path.exists(push3_path): - flags = d.get('fitness_flags', '') + flags = d.get('fitness_flags') qualifying.append((fitness, push3_path, gen_idx, cand_str, flags)) except (json.JSONDecodeError, ValueError, TypeError, AttributeError): pass