Lab 23 — Monorepo Dependency Updater
Migración masiva de Pydantic v1 a v2 en un monorepo con 6 paquetes. Parallel workers procesan cada paquete en worktrees aislados, con Ralph Loop para asegurar que los tests pasan.
Setup
Nivel: Full-Stack
Duración estimada: 40 minutos. Features: parallel, loop, guardrails, reports, .architect.md.
bash
mkdir -p ~/architect-labs/lab-23 && cd ~/architect-labs/lab-23
git init && mkdir -p reports Crear monorepo simulado con 6 paquetes Python
bash
for pkg in core api auth storage utils worker; do
mkdir -p "packages/${pkg}/src" "packages/${pkg}/tests"
# requirements.txt con versiones viejas
cat > "packages/${pkg}/requirements.txt" << REQEOF
requests==2.28.0
pydantic==1.10.0
structlog==22.1.0
REQEOF
# Código que usa la API vieja de pydantic v1
cat > "packages/${pkg}/src/models.py" << PYEOF
from pydantic import BaseModel, validator
class ${pkg^}Config(BaseModel):
name: str
enabled: bool = True
max_retries: int = 3
@validator("name")
def name_not_empty(cls, v):
if not v.strip():
raise ValueError("name cannot be empty")
return v
@validator("max_retries")
def retries_positive(cls, v):
if v < 0:
raise ValueError("max_retries must be >= 0")
return v
class Config:
# Pydantic v1 style
schema_extra = {
"example": {"name": "default", "enabled": True, "max_retries": 3}
}
PYEOF
# Tests
cat > "packages/${pkg}/tests/test_models.py" << PYEOF
import pytest
from src.models import ${pkg^}Config
def test_valid_config():
c = ${pkg^}Config(name="test")
assert c.name == "test"
assert c.enabled == True
assert c.max_retries == 3
def test_empty_name():
with pytest.raises(Exception):
${pkg^}Config(name="")
def test_negative_retries():
with pytest.raises(Exception):
${pkg^}Config(name="test", max_retries=-1)
def test_json_serialization():
c = ${pkg^}Config(name="test")
data = c.dict()
assert data["name"] == "test"
PYEOF
done Verificar que todo funciona con pydantic v1
bash
pip install pydantic==1.10.0 --break-system-packages 2>/dev/null
for pkg in packages/*/; do
echo "=== $(basename $pkg) ==="
cd "$pkg"
PYTHONPATH=. pytest tests/ -q 2>&1 | tail -1
cd ~/architect-labs/lab-23
done Configuración
.architect.md
markdown
# Pydantic v1 -> v2 Migration Rules
## Cambios necesarios
- @validator -> @field_validator con mode='before'
- class Config: -> model_config = ConfigDict(...)
- schema_extra -> json_schema_extra
- .dict() -> .model_dump()
- .json() -> .model_dump_json()
- from pydantic import validator -> from pydantic import field_validator
- Import ConfigDict: from pydantic import ConfigDict
## Obligatorio
- Actualizar requirements.txt a pydantic>=2.0
- Mantener la misma API pública
- No cambiar nombres de clases ni campos
- Los tests deben pasar (pueden necesitar ajustes a .dict() -> .model_dump())
## Prohibido
- No eliminar validaciones
- No cambiar la lógica de validación
- No ignorar errores con # type: ignore .architect.yaml
yaml
llm:
model: openai/gpt-4.1
api_base: http://localhost:4000/v1
api_key_env: LITELLM_API_KEY
guardrails:
max_files_modified: 5
skills:
auto_discover: true
costs:
budget_usd: 0.50 bash
git add -A && git commit -m "initial: monorepo with 6 packages using pydantic v1" Paso 1: Instalar pydantic v2
bash
pip install pydantic>=2.0 --break-system-packages 2>/dev/null Paso 2: Verificar que los tests fallan con v2
bash
for pkg in packages/*/; do
echo "=== $(basename $pkg) ==="
cd "$pkg"
PYTHONPATH=. pytest tests/ -q 2>&1 | tail -1
cd ~/architect-labs/lab-23
done
# Todos deben fallar (pydantic v1 API rota en v2) Importante
Este es el escenario real: una breaking change en una dependencia rompe todos los paquetes del monorepo. Architect procesa cada uno en paralelo para minimizar el tiempo de migración.
Paso 3: Crear manifest
bash
find packages/ -maxdepth 1 -mindepth 1 -type d > packages-to-update.txt
cat packages-to-update.txt Paso 4: Parallel migration con Ralph Loop
bash
architect parallel \
"Migra este paquete de Pydantic v1 a Pydantic v2. \
Sigue las reglas de .architect.md. \
Actualiza models.py, tests, y requirements.txt. \
Los tests deben pasar con pydantic v2." \
--manifest packages-to-update.txt \
--workers 3 \
--config .architect.yaml \
--confirm-mode yolo \
--report-file reports/migration.json Paso 5: Verificar
bash
# Tests de TODOS los paquetes
for pkg in packages/*/; do
echo "=== $(basename $pkg) ==="
cd "$pkg"
PYTHONPATH=. pytest tests/ -q 2>&1 | tail -1
cd ~/architect-labs/lab-23
done
# Verificar que usa API de pydantic v2
for pkg in packages/*/src/models.py; do
echo "=== $pkg ==="
grep "field_validator\|model_config\|ConfigDict" "$pkg" \
|| echo " Still using v1 API"
done
# Reporte
python3 -c "
import json
r = json.load(open('reports/migration.json'))
success = sum(1 for x in r.get('results',[]) if x.get('success'))
total = len(r.get('results',[]))
print(f'Migrated: {success}/{total} packages')
" Paso 6: Crear PR
bash
git checkout -b migration/pydantic-v2
git add -A
git commit -m "chore: migrate all packages from pydantic v1 to v2
- @validator to @field_validator
- class Config to model_config = ConfigDict(...)
- .dict() to .model_dump()
- All tests passing with pydantic>=2.0" Siguiente lab
Lab 24: AIOps Incident Remediation — Alerta de producción, diagnóstico y hotfix automático.