From 5163d08af044483222a4a140fa9afbe21003084f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Lucas=20Vitorasso?= Date: Sat, 9 May 2026 22:53:32 +0000 Subject: [PATCH] fix(skills): pass evolved_full (with frontmatter) to skill validator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `skill_structure` constraint checks for YAML frontmatter (`---`), `name` field, and `description` field. It was being called with `evolved_body` (the body only), which meant that constraint *always* failed — every evolution was routed to `evolved_FAILED.md` even when the reassembled skill (`evolved_full`) was well-formed. Repro: 1. Run `python -m evolution.skills.evolve_skill --skill --iterations 5 --eval-source synthetic` — the optimizer completes 10 trials, finds a best-scoring program, then validation fails with: `✗ skill_structure: Skill missing: YAML frontmatter (---), name field, description field`. 2. The output dir contains `evolved_FAILED.md` (saved on line ~206 from `evolved_full`, which IS well-formed) — confirming the only thing wrong was the validator input. Fix: pass `evolved_full` (built one line earlier on L185 via `reassemble_skill(skill["frontmatter"], evolved_body)`) instead of `evolved_body`. After the fix, the same run lands in `output///evolved_skill.md` with all 4 constraints passing. --- evolution/skills/evolve_skill.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/evolution/skills/evolve_skill.py b/evolution/skills/evolve_skill.py index 8ad4d89..6d3770f 100644 --- a/evolution/skills/evolve_skill.py +++ b/evolution/skills/evolve_skill.py @@ -185,8 +185,13 @@ def evolve( evolved_full = reassemble_skill(skill["frontmatter"], evolved_body) # ── 7. Validate evolved skill ─────────────────────────────────────── + # Pass `evolved_full` (frontmatter + body) so the `skill_structure` + # constraint can verify the YAML frontmatter / name / description. + # Passing `evolved_body` here causes that constraint to always fail and + # routes valid evolutions into the FAILED path even when the assembled + # skill is well-formed (and gets saved correctly on line ~206). console.print(f"\n[bold]Validating evolved skill[/bold]") - evolved_constraints = validator.validate_all(evolved_body, "skill", baseline_text=skill["body"]) + evolved_constraints = validator.validate_all(evolved_full, "skill", baseline_text=skill["body"]) all_pass = True for c in evolved_constraints: icon = "✓" if c.passed else "✗"