---
name: validate_recipe_yaml
kind: function
lang: py
domain: core
version: "1.0.0"
purity: pure
signature: "def validate_recipe_yaml(yaml_text: str) -> dict"
description: "Parsea y valida recipe YAML del navegator. Comprueba name (snake_case), url_pattern (regex valido), steps (js o wait_selector), output.schema y output.sink."
tags: [navegator, recipe, validation, yaml, pure, validator]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [re, yaml]
params:
  - name: yaml_text
    desc: "Texto completo de la recipe en formato YAML."
output: "dict {valid: bool, errors: [str], warnings: [str], parsed: dict}. valid=True solo si errors esta vacio."
tested: true
tests:
  - "recipe valida minima retorna valid true"
  - "name ausente produce error"
  - "url_pattern invalido produce error"
  - "step sin js ni wait_selector produce error"
  - "sink invalido produce error"
test_file_path: "python/functions/core/validate_recipe_yaml_test.py"
file_path: "python/functions/core/validate_recipe_yaml.py"
---

## Ejemplo

```python
import sys
sys.path.insert(0, "python/functions")
from core.validate_recipe_yaml import validate_recipe_yaml

yaml_text = """
name: product_list
url_pattern: "https://shop\\.example\\.com/.*"
steps:
  - wait_selector: ".product-card"
  - js: "Array.from(document.querySelectorAll('.product-card')).map(e => e.innerText)"
output:
  sink: stdout
"""

result = validate_recipe_yaml(yaml_text)
# {"valid": True, "errors": [], "warnings": [], "parsed": {...}}
```

## Cuando usarla

Antes de ejecutar una recipe con `cdp_extract_recipe`: validar el YAML en seco sin necesitar Chrome. Tambien util en un editor de recipes para dar feedback al usuario en tiempo real.

## Gotchas

- Requiere `pyyaml` en el entorno; si falta devuelve `valid=False` con mensaje claro (no lanza excepcion).
- Funcion pura: no accede a red ni a disco.
- `url_pattern` se compila con `re.compile` — patrones validos en Python pero invalidos en otros motores no se detectan aqui.
