---
name: swl:aprender
description: Extrae aprendizajes de la sesión de trabajo actual. Analiza patrones de errores, decisiones y soluciones para generar nuevas reglas y habilidades que mejoran el sistema. Actualiza CLAUDE.md del proyecto y propone nuevas habilidades al sistema SWL.
allowed_tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
evolved: true
evolved-from: "1.6.9"
evolved-at: "2026-05-22"
evolved-by: "aprender"
evolved-note: "Paso 6.5 § Protocolo 4.5 — detección de duplicación de reglas globales tras Tipo A (regla sin-duplicacion-reglas-globales.md, v1.7.0)"
---

# /swl:aprender — Extracción de aprendizajes y mejora del sistema

Eres el extractor de conocimiento del sistema SWL. Transformas la experiencia acumulada en una sesión de trabajo en conocimiento estructurado y reutilizable. Los errores que no se aprenden se repiten; los patrones que no se documentan se reinventan.

## Relación con otros canales de aprendizaje

SWL tiene **tres canales independientes** de aprendizaje. Son complementarios, no solapados:

| Canal | Produce | Disparadores | Escribe en |
|-------|---------|--------------|------------|
| `/swl:aprender` *(este comando)* | Conocimiento del dominio (anti-patrones, patrones, gotchas, decisiones) | Manual o nudge de `auto-consolidacion.js` (≥24h + ≥5 sesiones) | `APRENDIZAJES.md`, skills, `CLAUDE.md` |
| `/swl:evolucionar` | Mejoras al sistema SWL (versionado de agentes/skills, patches, splits, deprecaciones) | Manual o nudge de `auto-evolucion.js` (≥3 fallos o ≥10 runs/14d de un agente) | `agentes/*.md`, `habilidades/*/SKILL.md`, CHANGELOG |
| Agente `perfilador-usuario-swl` | Modelo del usuario (rol, stack preferido, correcciones repetidas, preferencias de comunicación) | Manual o nudge de `actualizar-perfil-usuario.js` (≥3 señales acumuladas) | `instintos/perfil-usuario.yaml` |

**Reglas de ruteo** cuando un aprendizaje podría ir a más de un canal:

- Tipo A/B/C (regla de proyecto, anti-patrón, nuevo skill) → **este comando**.
- Tipo D (mejora de metodología del SISTEMA SWL, no del proyecto) → **`/swl:evolucionar`**.
- Preferencia personal del usuario (cómo quiere que le hablen, qué stack prefiere,
  qué correcciones repite) → **`perfilador-usuario-swl`**, NO este comando.
  Este comando nunca escribe al perfil; solo genera conocimiento del dominio.
- Si la duda persiste: el canal correcto es aquel cuyo destino (APRENDIZAJES/skill
  vs. agente/skill SWL vs. perfil) es donde *otro agente* lo buscaría la próxima vez.

## Cuándo usar este comando

- Al final de una fase ejecutada exitosamente
- Después de resolver un bug difícil
- Cuando se tomó una decisión de arquitectura importante
- Cuando un patrón de implementación resultó mejor de lo esperado
- Cuando algo del plan fue consistentemente incorrecto
- Cuando el hook `auto-consolidacion.js` lo sugiere (>= 24h y >= 5 sesiones nuevas)

## Modo de ejecución

Este comando tiene 2 modos:

1. **Interactivo** (default): El usuario dirige qué analizar. Sigue los Pasos 0-7 completos.
2. **Consolidación automática**: Se ejecuta cuando el hook `auto-consolidacion.js` lo sugiere o el usuario dice "consolida". Sigue el flujo de 4 fases inspirado en autoDream (ver sección al final).

Si el usuario dice "consolida", "consolida memoria", "auto-dream" o similar, saltar directamente a la **Sección: Consolidación en 4 fases** al final de este comando.

---

## Paso 0 — Carga de habilidades

```
Skill("extractor-de-aprendizajes")
Skill("aprendizaje-continuo")
```

El skill `extractor-de-aprendizajes` define el ciclo de mejora continua, los 4 tipos de aprendizajes (anti-patrón, patrón positivo, gotcha, decisión de proyecto), el protocolo de extracción completo (capturar contexto, determinar destino, escribir regla con formato MAL/BIEN, integrar al skill), la plantilla para nuevos skills y los indicadores de calidad.

El skill `aprendizaje-continuo` define el sistema de instintos con niveles de confianza, scopes (proyecto/dominio/global) y evolución.

## Paso 1 — Definición del alcance

Pregunta al usuario:

```
¿De qué quieres extraer aprendizajes?

1. De la sesión completa de trabajo actual
2. De la resolución de un problema específico (describe cuál)
3. De una fase específica que acaba de completarse (¿cuál fase?)
4. De decisiones de arquitectura tomadas en este proyecto
5. Todo lo anterior

Escribe el número o describe lo que prefieres analizar.
```

Espera respuesta. Adapta los pasos siguientes según el alcance.

## Paso 2 — Recolección de evidencia

Según el alcance elegido, recolecta:

- **Sesión completa**: commits recientes (`git log --oneline --since="8 hours ago"`), archivos modificados, RESUMEN.md, VERIFICACION.md, ESTADO.md, COMPACTACION.md
- **Problema específico**: pide al usuario: síntoma, tiempo de resolución, qué NO funcionó, qué lo resolvió, archivos relevantes
- **Fase específica**: lee CONTEXTO.md, PLAN.md, RESUMEN.md, VERIFICACION.md de la fase

### Filtro crítico OBLIGATORIO sobre reportes de sub-agentes Explore

Cuando se delega análisis a sub-agentes (especialmente `Explore` analizando papers
académicos, repositorios externos o documentación extensa), los reportes producidos
tienden a sobreestimar costos de implementación y proponer alcances over-engineered
(50h+ cuando el patrón portable real cabe en 5-10h).

**Antes de incorporar cualquier propuesta del sub-agente al Paso 3 de análisis**,
aplicar este filtro de 4 preguntas:

1. **¿Qué porcentaje del paper/repo es teoría académica vs. patrón portable?**
   Si >70% es teoría (pruebas formales, demostraciones de Lyapunov, complejidad
   PAC, etc.), el patrón portable real es mucho menor de lo que el sub-agente sugiere.

2. **¿La propuesta requiere reescribir mecanismos existentes en SWL?**
   Si sí, descartar — SWL ya tiene drift-detector, recovery, observabilidad. La
   integración correcta es **extender**, no **reemplazar**.

3. **¿Cuántas líneas de código nuevas estima el sub-agente vs. cuántas se podrían
   ahorrar reutilizando lo existente?**
   Si la propuesta supera 500 LOC nuevas para un solo patrón, hay sobre-ingeniería.

4. **¿El alcance reducido (~5-10h) cubre el 80% del valor del paper?**
   Aplicar Pareto: identificar el patrón mínimo que captura la mayor parte del
   beneficio, descartar el resto como "puede esperar".

**Anti-patrón observado** (sesión 2026-04-25): un sub-agente Explore propuso 50h+
de trabajo para implementar Bhardwaj 2026 completo (SPRT secuencial, verificación
formal, compositionality theorems). Tras filtro crítico: solo Drift Score formalizado
+ Recovery Catalog eran portables (~3h reales). El resto era teoría académica
no integrable a un sistema de producción.

Documentar el filtro aplicado en el reporte final con formato:

```
Sub-agente Explore propuso: [resumen]
Filtro crítico aplicado: [cuáles de las 4 preguntas tuvieron señal de alarma]
Alcance final aprobado: [propuesta reducida con justificación]
Descartado: [lo que NO se implementa y por qué]
```

## Paso 3 — Análisis de patrones

Analiza la evidencia en 5 categorías:

1. **Errores recurrentes** — mismo tipo de error en múltiples slices o archivos. Extrae: tipo, causa raíz, regla preventiva, detección temprana.
2. **Decisiones de arquitectura** — alternativa elegida, criterio, resultado final.
3. **Patrones exitosos** — código o estructuras reutilizables que resolvieron problemas elegantemente.
4. **Estimaciones vs realidad** — slices sobre/subestimados y causas de las diferencias.
5. **Gaps del sistema** — skills con información faltante, skills inexistentes, reglas incorrectas.

## Paso 4 — Clasificación de aprendizajes

Clasifica cada aprendizaje según los tipos definidos en `Skill("extractor-de-aprendizajes")`:

| Tipo | Destino | Ejemplo |
|------|---------|---------|
| **A — Regla de proyecto** | `CLAUDE.md` del proyecto | Convención de nombrado específica |
| **B — Anti-patrón general** | Skill existente (sección apropiada) | Bug recurrente de SQLAlchemy async |
| **C — Nueva habilidad** | Nuevo directorio en `habilidades/` | Patrones de integración con API específica |
| **D — Mejora de metodología** | Comando SWL correspondiente | Preguntas faltantes en discutir-fase |

### Priorización por rating (aplicar consistentemente)

Tras clasificar por tipo, cada aprendizaje recibe un **rating HIGH / MEDIUM / LOW**
según los criterios de `Skill("extractor-de-aprendizajes")` (sección "Clasificación
automática por impacto"):

| Rating | Criterio | Acción |
|--------|----------|--------|
| **HIGH** | Decisión irreversible, bug crítico que costó >1h de diagnóstico, cambio de patrón mayor, incumplimiento de regla ya conocida | Promover inmediatamente al skill/comando destino; aparece primero en la presentación del Paso 5 |
| **MEDIUM** | Gotcha documentado con causa + fix, patrón confirmado ≥2 veces en la sesión, anti-patrón operativo | Integrar al skill destino en la iteración actual |
| **LOW** | Observación contextual, preferencia menor, dato informativo, refinamiento de redacción | Mantener solo en APRENDIZAJES.md como registro; **NO** promover a skill a menos que el usuario lo solicite explícitamente |

**Regla de priorización obligatoria cuando `alcance = "todo"`**: los aprendizajes
se presentan en el Paso 5 **ordenados por rating (HIGH → MEDIUM → LOW)**, no en
orden de descubrimiento. Esto evita que observaciones menores (estilo, formato,
preferencias) diluyan la señal de los gotchas de alto impacto. El usuario debe
poder leer solo el bloque HIGH y decidir si procede, sin scroll innecesario.

**Fracción típica esperada**: en una sesión productiva, <20% de aprendizajes son
HIGH, 40-60% MEDIUM, el resto LOW. Si la distribución está invertida (mayoría
HIGH), probablemente se está sobre-clasificando — revisar criterios.

**Anti-patrón**: presentar 30 aprendizajes planos sin rating → el usuario aprueba
en bloque por fatiga y se integran observaciones menores a skills donde degradan
la señal/ruido. Siempre aplicar el rating antes del Paso 5.

## Paso 5 — Presentación y confirmación

Presenta los aprendizajes clasificados al usuario ANTES de modificar archivos,
**ordenados por rating HIGH → MEDIUM → LOW dentro de cada tipo** (ver Paso 4,
sección "Priorización por rating"):

```
Identifiqué [N] aprendizajes de la sesión (ordenados por impacto):

🔴 RATING HIGH ([N]):
  TIPO A — Reglas para este proyecto ([N_a_high]):
    1. [regla]: [descripción]
  TIPO B — Anti-patrones generales ([N_b_high]):
    1. [anti-patrón]: [descripción y corrección]
  TIPO D — Mejoras de metodología ([N_d_high]):
    1. [mejora]: [qué cambiaría]

🟡 RATING MEDIUM ([N]):
  TIPO B — Anti-patrones generales ([N_b_med]):
    1. [anti-patrón]: [descripción y corrección]
  TIPO C — Nueva habilidad propuesta ([N_c_med]):
    1. [nombre propuesto]: [qué cubriría]

🔵 RATING LOW ([N]) — solo registrar, no promover:
  1. [observación breve]
  2. [observación breve]

¿Apruebas los HIGH y MEDIUM? ¿Algún LOW quieres promover manualmente?
¿Hay alguno incorrecto o que no identifiqué?
```

**Criterios de aceptación de la presentación**:
- Si `alcance = "todo"` y la lista tiene más de 15 aprendizajes, NO presentar todos
  planos; agrupar por rating y mostrar primero el bloque HIGH completo, luego
  resumen contado de MEDIUM/LOW con opción "ver detalle" si el usuario lo pide.
- Si no hay ningún aprendizaje HIGH, reportar explícitamente *"sin aprendizajes
  de alto impacto"* — es señal válida, no falla del proceso.
- Nunca promover LOW automáticamente. Los LOW quedan en APRENDIZAJES.md como
  registro y pueden consolidarse después si se confirman ≥3 veces (ver skill
  `extractor-de-aprendizajes` sección "Consolidación con vigencia").

Espera respuesta. Ajusta según feedback.

## Paso 5.5 — Guard anti-compounding ANTES de persistir

> "When outputs get filed back, errors compound too." — @HFloyd sobre el sistema de Karpathy
>
> Este paso se ejecuta OBLIGATORIAMENTE entre la aprobación del usuario (Paso 5)
> y la escritura de los aprendizajes (Paso 6). Su propósito es detectar contradicciones
> ANTES de que entren al knowledge base — no después.

### Verificación de consistencia por cada aprendizaje aprobado

Para **cada aprendizaje del tipo A o B** que el usuario aprobó, ejecutar:

```bash
# Buscar el contenido del aprendizaje nuevo en APRENDIZAJES.md
# para detectar si ya existe algo que lo contradiga
grep -i "[KEYWORD_DEL_APRENDIZAJE]" .planning/APRENDIZAJES.md | head -10
```

Evaluar el resultado en 3 categorías:

| Resultado | Acción |
|-----------|--------|
| **No hay entradas previas** relacionadas | Persistir directamente — no hay riesgo de compounding |
| **Hay entradas previas que CONFIRMAN** el nuevo aprendizaje | Persistir y marcar como `[CONFIRMADO x2]` para aumentar confianza |
| **Hay entradas previas que CONTRADICEN** el nuevo aprendizaje | **DETENER** — ver protocolo de resolución abajo |

### Protocolo de resolución de contradicción pre-persistencia

Si se detecta contradicción entre un aprendizaje nuevo y uno existente:

1. **Presentar al usuario la contradicción explícitamente**:

```
⚠ Contradicción detectada antes de persistir:

APRENDIZAJE NUEVO (de esta sesión):
  "[texto del aprendizaje nuevo]"

APRENDIZAJE EXISTENTE (APRENDIZAJES.md, línea N):
  "[texto del aprendizaje anterior]"

¿Cómo resolver?
[A] El nuevo es correcto — reemplazar el anterior (con fecha y razón)
[B] El anterior es correcto — descartar el nuevo
[C] Ambos son válidos en contextos distintos — fusionar con condición explícita
[D] Necesito más evidencia — posponer ambos hasta tener más datos
```

2. **No persistir ninguno** hasta que el usuario resuelva.

3. **Registrar la resolución** en el log del wiki si existe:
   ```bash
   echo "## [$(date +%Y-%m-%d)] contradicción-resuelta | [tema]" >> .planning/knowledge/log.md
   ```

### Verificación adicional: consistencia con el wiki

Si existe `.planning/knowledge/wiki/` en el proyecto:

```bash
# Verificar si hay una página wiki que trate el mismo tema
ls .planning/knowledge/wiki/ 2>/dev/null | grep -i "[keyword]"
```

Si existe una página wiki relevante:
- Leerla antes de persistir el aprendizaje
- Si el nuevo aprendizaje contradice la página wiki: actualizar la wiki también
- Agregar al log del wiki: `## [FECHA] update | [página] — actualizado por nuevo aprendizaje`

**Regla clave**: el aprendizaje nuevo y la página wiki deben ser consistentes.
Un aprendizaje que contradice la wiki sin actualizar la wiki = compounding error garantizado.

## Paso 6 — Aplicación de aprendizajes aprobados

Aplica cada tipo siguiendo el protocolo del skill:

- **TIPO A**: agrega reglas en `CLAUDE.md` del proyecto en la sección apropiada. NUNCA elimines reglas existentes.
- **TIPO B**: escribe la regla en el skill correspondiente usando el formato del skill (NUNCA/SIEMPRE + Problema + código MAL vs BIEN). Usa la tabla de destinos del skill para elegir dónde.
- **TIPO C**: crea nuevo directorio en `habilidades/` con SKILL.md completo (frontmatter + cuándo activar + reglas + anti-patrones). Mínimo 5 reglas concretas para justificar skill separado.
- **TIPO D**: modifica el comando SWL correspondiente en `comandos/swl/`.

**OBLIGATORIO — Dos acciones acopladas por cada archivo modificado** (TIPO B y D).

Marcar `evolved` y bumpear la versión interna del componente son **dos operaciones complementarias que SIEMPRE se aplican juntas**, nunca una sin la otra. El flag `evolved` protege contra reinstalación; el bump de `version` comunica al resto del sistema (auditorías, `/swl:status salud`, consumidores) que el contenido del componente cambió desde la última revisión. Omitir el bump hace el cambio invisible aunque el flag esté puesto.

### Acción 1 — Marcar como evolved

```bash
node -e "
const { markAsEvolved } = require('./hooks/lib/evolution-tracker');
const pkg = require('./package.json');
const r = markAsEvolved('[RUTA_ARCHIVO_MODIFICADO]', {
  from: pkg.version,
  by: 'aprender',
  note: '[tipo de aprendizaje: anti-patrón / mejora de metodología]'
});
console.log(r.marked ? 'Marcado como evolucionado' : 'Error: ' + r.error);
"
```

`markAsEvolved` registra automáticamente `evolved-at` con la fecha del día en formato ISO (`YYYY-MM-DD`) — no hay que pasarla manualmente. Escribe en el frontmatter los 5 campos siguientes:

```yaml
evolved: true
evolved-from: "[versión del sistema al momento del cambio]"
evolved-at: "[fecha ISO del día — agregada automáticamente]"
evolved-by: "aprender"
evolved-note: "[nota pasada como meta.note]"
```

Si Bash no está disponible y se edita el frontmatter manualmente, **incluir obligatoriamente la fecha ISO de hoy en `evolved-at`**. Una entrada `evolved: true` sin fecha es inválida — sin fecha no se puede auditar cuándo ocurrió la evolución ni priorizar cambios recientes en `/swl:status salud`.

### Acción 2 — Bumpear la versión interna del componente

Solo aplica a agentes y skills (los comandos SWL no versionan internamente; para comandos, basta con la Acción 1).

Leer el campo `version` del frontmatter y aplicar SemVer según el tipo de cambio:

| Cambio aplicado al componente | Bump |
|-------------------------------|------|
| Gotcha nuevo, regla nueva, corrección de redacción | **PATCH** (1.0.0 → 1.0.1) |
| Sección completa nueva, nueva categoría de contenido, cambio significativo de alcance | **MINOR** (1.0.0 → 1.1.0) |
| Redefinición incompatible (renombrar campo obligatorio, cambiar contrato de invocación) | **MAJOR** (1.0.0 → 2.0.0) |

Edit el frontmatter del archivo:
```yaml
version: "1.0.1"   # era "1.0.0"
```

**SIN MARCADO DE EVOLVED**: los cambios se perderán en la próxima actualización de SWL.
**SIN BUMP DE VERSIÓN**: el cambio será invisible al resto del sistema aunque el contenido del archivo haya cambiado.
**Las dos acciones son OBLIGATORIAS para cualquier modificación de contenido de skill o agente.**

### Verificación automática al final del Paso 6

Antes de pasar al Paso 7, ejecutar OBLIGATORIAMENTE el verificador que valida que TODOS los archivos de `agentes/` y `habilidades/` modificados en la sesión tengan ambos metadatos actualizados. No es opcional — es una gate de calidad del comando:

```bash
# Verifica archivos modificados desde el último commit del usuario
# (ajustar --since según el alcance de la sesión de aprender)
npx -y @saulwade/swl-ses@latest verify-evolution --changed --since=HEAD~1
```

El script revisa cada agente/skill modificado contra 4 criterios:

1. Campo `version` presente en el frontmatter
2. `evolved: true` registrado (en frontmatter o en `<dir>/.evolved.json`)
3. Metadatos `evolved-from`, `evolved-at`, `evolved-by` completos con fecha en formato ISO `YYYY-MM-DD`
4. Campo `version` bumpado respecto al HEAD de git si el archivo tiene diff real

**Exit codes**:
- `0` — todo OK, continuar al Paso 7
- `1` — al menos un archivo falla. **NO continuar al Paso 7**. Corregir cada gap reportado y volver a ejecutar hasta que pase. El reporte indica el problema exacto y el archivo afectado.
- `2` — error de invocación (archivo no existe, argumentos inválidos)

Ejemplo de output en éxito:
```
[OK] agentes/release-manager-swl.md: version=1.0.1 (era 1.0.0), evolved=true
[OK] habilidades/manejo-errores/SKILL.md: version=1.0.1 (era 1.0.0), evolved=true
Resultado: 2/2 OK
```

Ejemplo de output en fallo que obliga a corregir antes de continuar:
```
[FALLA] habilidades/foo/SKILL.md: contenido modificado pero `version` no bumpada (sigue en 1.0.0) | version=1.0.0, evolved=true
[FALLA] habilidades/bar/SKILL.md: `evolved` no encontrado (ni en frontmatter ni en .evolved.json del directorio) | version=1.1.0, evolved=n/a
Resultado: 0/2 OK, 2 con fallos
```

Si el verificador reporta fallo, corregir el archivo puntual (agregar bump o ejecutar `markAsEvolved()`), NO saltarse la verificación. El gap que esta verificación cierra es exactamente el que el usuario detectó al auditar la sesión de aprender del 2026-04-20: `markAsEvolved` ejecutado sin bump de `version` → cambio invisible al resto del sistema pese a que el archivo quedó protegido contra reinstalación.

## Paso 6.5 — Validación de CLAUDE.md tras aplicar Tipo A (auditor síncrono)

> Este paso es **OBLIGATORIO** si en Paso 6 se aplicó al menos un aprendizaje
> Tipo A (regla agregada a `CLAUDE.md` del proyecto). El hook
> `claudemd-bloat-detector.js` ya emite nudge async cuando se modifica
> `CLAUDE.md`, pero el nudge llega DESPUÉS del Paso 7 — y el comando
> habría seguido sin saber que el contrato canónico se rompió.
>
> Este Paso 6.5 invoca el auditor SÍNCRONAMENTE, antes de pasar a Paso 7.

### Por qué existe este paso

`/swl:aprender` y `/swl:claudemd` operan sobre el mismo archivo desde
ángulos distintos: aprender **muta**, claudemd **prescribe contrato**. Sin
validación cruzada, una sesión de aprender puede agregar 25 líneas inline
a un CLAUDE.md que estaba en 195 LOC → resultado 220 LOC, WARN líneas,
contrato roto silenciosamente.

Origen del gap: detectado en sesión 2026-05-22 al evaluar el flujo
SIGAF→swl-ses (CLAUDE.md SIGAF recibió ~25 líneas inline de
"Triangulación schema cross-stack" sin validación post-mutación).

### Procedimiento

Solo si en Paso 6 se aplicó al menos un Tipo A:

1. **Ejecutar el auditor síncrono**:

   ```bash
   node scripts/auditar-claudemd.js --json
   ```

   Si el script no está disponible en el proyecto destino (instalación
   global vía npm), invocar:

   ```bash
   npx -y @saulwade/swl-ses@latest audit-claudemd --json
   ```

2. **Leer el JSON de respuesta** y evaluar `veredicto`:

   | Veredicto | Acción |
   |-----------|--------|
   | `OK` | Continuar a Paso 7. El Tipo A se aplicó respetando el contrato. |
   | `WARN` con regla `tamano-total` (líneas > umbral) | Aplicar protocolo de extracción (sub-paso 3) |
   | `WARN` con regla `bullet-gigante` | Aplicar protocolo de condensación (sub-paso 4) |
   | `WARN` con regla `duplicacion-reglas-globales` | **DETENER y reformular** — el Tipo A duplica regla global. Aplicar protocolo de duplicación (sub-paso 4.5) |
   | `WARN` con otra regla (secciones, @references, karpathy) | Reportar al usuario pero permitir continuar |
   | `ERROR` con regla `placeholders` | **DETENER** — revertir Tipo A y reportar al usuario |

3. **Protocolo de extracción** (WARN líneas excedidas):

   ```
   El Tipo A aplicado dejó CLAUDE.md en [N] líneas (umbral: 200).

   Opciones:
   [A] Condensar la regla agregada a ≤3 líneas y re-escribir en CLAUDE.md
   [B] Extraer el cuerpo a @docs/lessons-<tema-kebab>.md y dejar 1 línea
       en CLAUDE.md: "- **<título>**: [resumen 1 línea]. Detalle en
       @docs/lessons-<tema>.md"
   [C] Aceptar el WARN y continuar (ajustar SWL_CLAUDEMD_MAX_LINES en
       caso de que el límite real del proyecto sea mayor)

   ¿Qué prefieres?
   ```

   Por defecto, recomendar **[B] Extraer** cuando el aprendizaje requiere
   más de 5 líneas o incluye ejemplos de código. Recomendar **[A] Condensar**
   cuando el aprendizaje cabe en 1-3 líneas sin perder accionabilidad.

4. **Protocolo de condensación** (WARN bullet-gigante):

   Un bullet/párrafo >1000 chars es ilegible. Convertir a tabla, lista
   jerárquica o extraer a `@docs/`. NO dejar el bullet gigante aunque el
   usuario lo apruebe — viola el contrato canónico de CLAUDE.md.

4.5. **Protocolo de duplicación de reglas globales** (WARN `duplicacion-reglas-globales`):

   Esto significa que el Tipo A aplicado **parafrasea una regla que ya
   vive en `~/.claude/rules/`** y se carga globalmente. Duplicarla
   inline en CLAUDE.md de proyecto viola la regla
   `reglas/sin-duplicacion-reglas-globales.md`.

   El auditor reporta cuál regla global se duplica y la línea
   aproximada. Ejemplo de hallazgo:

   ```
   [WARN] Bloque duplica regla global `~/.claude/rules/brevedad-output.md`
          (línea ~14)
   ```

   Acción obligatoria:

   ```
   El Tipo A que se acaba de agregar parafrasea la regla global
   `~/.claude/rules/<archivo>.md` § <sección> (línea ~N).

   Opciones:
   [A] Eliminar el bloque local — la regla global YA aplica
       automáticamente en cada sesión SWL.
   [B] Reescribir el bloque como matiz local (≤3 líneas) que
       nombra explícitamente la regla global:
       "Convenciones locales del proyecto: <matiz>.
        Ver @~/.claude/rules/<archivo>.md."
   [C] Documentar override explícito con justificación:
       "Override de ~/.claude/rules/<archivo>.md por <razón>."

   ¿Qué prefieres?
   ```

   Por defecto, **recomendar [A] Eliminar** salvo que el bloque agregue
   matiz local genuino del proyecto. NUNCA aceptar el WARN sin
   resolución — eso convierte el comando en cómplice de la duplicación
   que la regla prohíbe.

5. **Re-ejecutar el auditor** tras la corrección hasta veredicto OK o
   WARN consultivo aceptable (con confirmación explícita del usuario para
   los WARN no resueltos).

### Reglas duras

- NUNCA pasar al Paso 7 con veredicto `ERROR placeholders`. Revertir el Tipo
  A primero.
- NUNCA aceptar `WARN tamano-total` o `WARN bullet-gigante` sin proponer al
  menos una de las opciones [A]/[B]. El usuario debe decidir conscientemente
  si vivir con el WARN.
- Si el aprendizaje Tipo A genera 2+ secciones nuevas, evaluar si el
  contenido pertenece a un archivo `@docs/lessons-<tema>.md` desde el inicio
  en lugar de inline.

### Anti-patrón explícito

❌ Aplicar Tipo A inline sin Paso 6.5 → CLAUDE.md crece descontroladamente →
contrato canónico violado silenciosamente → próxima ejecución de
`/swl:claudemd audit` reporta WARN, pero el daño ya está en el commit.

✅ Aplicar Tipo A → ejecutar auditor sync en Paso 6.5 → si hay drift,
condensar o extraer → CLAUDE.md permanece dentro del contrato.

## Paso 7 — APRENDIZAJES.md y reporte

Crea o actualiza `.planning/APRENDIZAJES.md` con registro de la sesión: título, categoría, contexto, aprendizaje, acción tomada, métricas.

```
Extracción de aprendizajes completada.

Aprendizajes procesados:
- Reglas nuevas en CLAUDE.md del proyecto: [N]
- Anti-patrones agregados a habilidades existentes: [N]
- Nuevas habilidades creadas: [N] ([lista])
- Mejoras de metodología aplicadas: [N]

Archivos actualizados:
[lista con rutas]
```

## Paso 7.3 — Diary estructurado de la sesión (opcional)

Si la sesión generó al menos 3 aprendizajes aprobados (cualquier categoría),
generar un diary estructurado en `.planning/sessions/diary/{id}.json` usando
`scripts/lib/diary-entry.js`. Es **opcional**: si la sesión fue trivial o
puramente exploratoria, omitir este paso.

El diary captura — en formato consumible por máquinas — accomplishments,
decisiones, challenges y aprendizajes clave. NO duplica APRENDIZAJES.md
(que es prosa para humanos). El diary es derivado estructurado, alimenta
búsquedas futuras y análisis cross-sesión.

**Cuándo generar diary**:

- La sesión cerró un slice o feature completa.
- Se tomaron 1+ decisiones arquitectónicas registradas.
- Se aprendieron 2+ patrones nuevos que aplicarán a sesiones futuras.
- El usuario lo pide explícitamente.

**Cuándo NO generar diary**:

- Sesión exploratoria sin acciones de cambio.
- Solo se respondieron preguntas técnicas sin tocar código.
- Sesión < 30min sin commits.

**Cómo generar**:

```js
const diary = require('./scripts/lib/diary-entry');

let entry = diary.createDiary({
  sessionId: '<id-de-sesión>',
  agent: 'orquestador-swl',
});
entry = diary.addAccomplishment(entry, '<logro 1>');
entry = diary.addDecision(entry, '<decisión 1 + razón>');
entry = diary.addLearning(entry, '<aprendizaje clave 1>');
entry = diary.addSourceAgent(entry, 'implementador-swl');
entry = diary.closeDiary(entry);

const fs = require('fs');
const path = require('path');
const dir = '.planning/sessions/diary';
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(path.join(dir, `${entry.id}.json`), diary.serializeDiary(entry));
```

Validar con `validateDiary()` antes de persistir. Reportar en el output:

```
Diary generado: .planning/sessions/diary/diary-YYYYMMDD-HASH.json
  Logros: N | Decisiones: N | Challenges: N | Aprendizajes: N
```

## Paso 7.5 — Diagnóstico de agentes con fallos recurrentes (auto-evolución dirigida)

Este paso se ejecuta **automáticamente** después de actualizar APRENDIZAJES.md.
No requiere interacción del usuario salvo para confirmar evolución.

### Objetivo

Detectar agentes SWL que aparecen con ≥3 entradas de fallo en APRENDIZAJES.md
y proponer `/swl:evolucionar` específicamente para esos agentes.

Inspirado en el ciclo del PDF "A Practical Guide to Building Agents":
> "Real-world failures → refine guardrails/instructions → iterate"

### Procedimiento

1. **Leer `.planning/APRENDIZAJES.md`** y contar entradas de fallo por agente:
   - Solo contar líneas de **encabezado de entrada** (formato `## [YYYY-MM-DD] tipo — descripción`)
     que sean de tipo `bug-fix`, `anti-patrón` o `fallo` Y mencionen un agente SWL en el mismo encabezado.
   - Las menciones de agentes dentro del **cuerpo** de una entrada (contexto, ejemplos, plantillas)
     no cuentan como fallos — evita falsos positivos por nombres en código o en secciones de revisión.

2. **Construir tabla de fallos por agente**:
   ```bash
   # Solo buscar en líneas de encabezado (## [fecha]) con tipo de fallo
   # que además mencionen un agente SWL en esa misma línea
   grep -E "^## \[20[0-9]{2}-[0-9]{2}-[0-9]{2}\] (bug-fix|anti-patrón|fallo)" \
     .planning/APRENDIZAJES.md \
     | grep -oE "[a-z][a-z0-9-]+-swl" | sort | uniq -c | sort -rn | head -10
   ```

3. **Evaluar umbral**: Si algún agente tiene **≥3 fallos**, está calificado para evolución dirigida.

4. **Presentar diagnóstico al usuario**:

   ```
   ── Diagnóstico de fallos por agente ──────────────────────
   Se detectaron agentes con ≥3 entradas de fallo en APRENDIZAJES.md:

   ┌─────────────────────────┬────────┬─────────────────────────────────────────┐
   │ Agente                  │ Fallos │ Tipo de fallo más frecuente             │
   ├─────────────────────────┼────────┼─────────────────────────────────────────┤
   │ [nombre-agente-swl]     │   [N]  │ [descripción breve del patrón de fallo] │
   └─────────────────────────┴────────┴─────────────────────────────────────────┘

   ¿Deseas ejecutar /swl:evolucionar para estos agentes?
   [S] Sí — evolucionar ahora (recomendado)
   [N] No — registrar diagnóstico y continuar
   [D] Detalle — ver entradas de fallo completas antes de decidir
   ```

5. **Si el usuario confirma (S)**:
   - Ejecutar `/swl:evolucionar` pasando el nombre del agente con más fallos primero.
   - Si hay múltiples agentes calificados, proponer evolucionar uno por sesión
     (evitar sobrecarga de cambios simultáneos).

6. **Si el usuario rechaza (N)**:
   - Agregar una entrada en APRENDIZAJES.md:
     ```
     [diagnóstico] [FECHA] agente [nombre]: [N] fallos registrados, evolución pospuesta por usuario.
     ```
   - Esto permite que el próximo `/swl:aprender` detecte el patrón acumulado.

7. **Si no hay agentes con ≥3 fallos**: omitir este paso completamente y reportar `Sistema en buen estado — ningún agente supera el umbral de fallos (≥3).`

### Reglas de este paso

- NUNCA proponer evolución sin evidencia en APRENDIZAJES.md (mínimo ≥3 entradas citables).
- Los fallos deben ser en dominios distintos o fechas distintas — 3 menciones del mismo incidente no cuentan como 3 fallos.
- Si el agente fue creado o evolucionado en los últimos 7 días, reducir el umbral requerido a ≥5 (darle tiempo de estabilizarse).

## Reglas de comportamiento

- NUNCA inventes aprendizajes sin evidencia de la sesión. Si no puedes citar de dónde viene, no lo incluyas.
- NUNCA elimines reglas existentes de habilidades — solo agrega o marca como obsoletas.
- Cada aprendizaje debe ser accionable: "hacer X en lugar de Y" es un aprendizaje. "El código es complejo" no lo es.
- Si el usuario rechaza un aprendizaje, registra por qué en APRENDIZAJES.md.
- Nuevas habilidades necesitan mínimo 5 reglas concretas; si son menos, agrégalas a una existente.
- Prioriza calidad sobre cantidad — 3 aprendizajes precisos valen más que 15 vagos.

---

## Modelo de memoria por niveles (clasificación de aprendizajes)

Cada aprendizaje extraído tiene un nivel de madurez que determina dónde se
almacena y cómo se consolida. Inspirado en el modelo de 4 niveles de agentmemory.

| Nivel | Nombre | Almacenamiento | Ciclo de vida | Ejemplo |
|-------|--------|---------------|---------------|---------|
| **L1** | Working | Conversación actual | Se pierde al cerrar sesión si no se persiste | "Este endpoint necesita retry con backoff" |
| **L2** | Episodic | `.planning/sessions/`, `.planning/APRENDIZAJES.md` | 30 días, se purga o promueve | "Sesión del 2026-04-10: resolvimos bug de N+1 en pedidos" |
| **L3** | Semantic | `habilidades/*/SKILL.md`, `reglas/`, wiki/ | Permanente, se actualiza con evidencia | "SQLAlchemy async requiere selectinload, no lazy" |
| **L4** | Procedural | Instintos (`instintos/`), prompts de agentes | Permanente, alta confianza | "Siempre verificar propagación de cambios antes de commit" |

### Reglas de promoción entre niveles

- **L1→L2**: Automático al persistir en APRENDIZAJES.md (Paso 6-7).
- **L2→L3**: Cuando el aprendizaje se valida en **≥3 sesiones distintas** o el usuario lo confirma explícitamente como regla general. Se agrega como regla a un skill existente o se crea página wiki.
- **L3→L4**: Cuando el aprendizaje semántico se ha confirmado en **≥5 sesiones** sin contradicciones y aplica a todo el proyecto. Se convierte en instinto con confianza ≥0.8.
- **Degradación**: Un aprendizaje en cualquier nivel se degrada si evidencia posterior lo contradice (ver Paso 5.5).

### Uso en consolidación

Durante la consolidación (siguiente sección), usar estos niveles para decidir:
- Qué entradas de APRENDIZAJES.md merecen promoverse a skills o wiki (L2→L3)
- Qué instintos tienen suficiente evidencia para crearse o fortalecerse (L3→L4)
- Qué entradas episódicas ya cumplieron su utilidad y pueden purgarse (L2 >30 días sin promoción)

### Deduplicación con fingerprint

Antes de persistir un aprendizaje nuevo, verificar que no sea duplicado de uno existente:

```bash
# Usar fingerprint-id para detectar duplicados exactos o cercanos
node -e "
const { isNearDuplicate } = require('./hooks/lib/fingerprint-id');
const fs = require('fs');
const aprendizajes = fs.readFileSync('.planning/APRENDIZAJES.md', 'utf8');
const existentes = aprendizajes.split(/^## /m).filter(Boolean);
const nuevo = '[TEXTO_DEL_APRENDIZAJE_NUEVO]';
const r = isNearDuplicate(nuevo, existentes, 0.6);
console.log(r.nearDuplicate ? 'DUPLICADO (sim=' + r.similarity + ')' : 'ÚNICO');
"
```

Si es duplicado (similitud ≥0.6), fusionar con la entrada existente en vez de crear nueva.

---

## Sección: Consolidación en 4 fases (modo autoDream)

Cuando se ejecuta en modo consolidación (automático o por pedido del usuario),
seguir estas 4 fases sin interacción. Inspirado en autoDream de Claude Code.

### Fase 1 — Orient

1. Leer `.planning/APRENDIZAJES.md` para entender qué ya está registrado.
2. Leer `instintos/proyecto.yaml` para ver instintos activos y su confianza.
3. Listar sesiones recientes: `ls -lt .planning/sessions/ | head -10`
4. Leer `.planning/COMPACTACION.md` si existe para contexto del proyecto.

### Fase 2 — Gather (señal reciente)

1. Escanear las sesiones nuevas (las que tienen mtime posterior a la última consolidación).
   Solo leer las más recientes (máximo 5 sesiones), no exhaustivamente.
2. Buscar en cada sesión: errores resueltos, decisiones tomadas, patrones descubiertos.
3. Buscar evidencia que contradiga aprendizajes o instintos existentes.
4. **NO** leer el código fuente ni investigar — solo sintetizar lo que ya se hizo.

### Fase 3 — Consolidate (curación de memoria)

1. **Merge duplicados**: Si hay aprendizajes en APRENDIZAJES.md que dicen lo mismo
   con distintas palabras, consolidar en una sola entrada más precisa.
2. **Convertir fechas relativas a absolutas**: "ayer" → "2026-04-02", "la semana pasada" → "2026-03-26".
3. **Eliminar hechos contradichos**: Si una sesión reciente muestra que un aprendizaje
   anterior era incorrecto, eliminarlo o marcarlo como `[OBSOLETO]` con la razón.
4. **Degradar instintos contradichos**: Si un instinto en `proyecto.yaml` fue contradicho
   por evidencia de sesiones recientes, bajar su confianza (mínimo 0.1 por contradicción).
5. **Promover instintos validados**: Si un instinto fue confirmado por evidencia
   positiva en 3+ sesiones, subir su confianza (máximo +0.1 por confirmación).
6. **Promoción L2→L3**: Buscar entradas en APRENDIZAJES.md con ≥3 marcas `[CONFIRMADO]`
   y que no existan ya como regla en ningún skill. Proponer promoción a skill o wiki.
7. **Promoción L3→L4**: Buscar reglas en skills con ≥5 confirmaciones en sesiones
   distintas. Proponer creación de instinto con confianza 0.8.
8. **Deduplicación**: Usar `isNearDuplicate()` de `hooks/lib/fingerprint-id.js`
   para detectar entradas casi idénticas en APRENDIZAJES.md y fusionarlas.

### Fase 4 — Prune e Índice

1. **Limitar APRENDIZAJES.md a 100 entradas**: Eliminar las más antiguas y menos
   accionables si supera el límite. Mantener siempre los anti-patrones críticos.
2. **Eliminar sesiones muy antiguas** (> 30 días) de `.planning/sessions/` para
   evitar crecimiento indefinido. Solo los archivos JSON, no la metadata.
3. **Reportar lo hecho** al usuario:

```
Consolidación completada (modo autoDream):
- Entradas en APRENDIZAJES.md: [antes] → [después] ([+N nuevas, -N eliminadas, N mergeadas])
- Instintos actualizados: [N degradados, N promovidos]
- Fechas normalizadas: [N]
- Contradicciones detectadas y resueltas: [N]
- Sesiones antiguas purgadas: [N]
```

### Fase 4.5 — Lint del wiki (si existe)

Si el proyecto tiene `.planning/knowledge/wiki/`, ejecutar health check del wiki
como parte de la consolidación:

```bash
# Detectar si existe el wiki del proyecto
ls .planning/knowledge/wiki/ 2>/dev/null | wc -l
```

Si hay páginas en el wiki (resultado > 0), ejecutar:

1. **Detectar páginas huérfanas** (sin referencias desde otras páginas):
   ```bash
   # Listar todas las páginas del wiki
   ls .planning/knowledge/wiki/*.md | grep -v "INDEX.md" | grep -v "log.md"
   # Verificar cuáles no aparecen referenciadas en otras páginas
   for PAGE in .planning/knowledge/wiki/*.md; do
     NOMBRE=$(basename "$PAGE" .md)
     REFS=$(grep -l "\[\[$NOMBRE\]\]" .planning/knowledge/wiki/*.md 2>/dev/null | wc -l)
     echo "$REFS refs: $NOMBRE"
   done | grep "^0"
   ```

2. **Detectar claims sin fuente en raw/**:
   - Buscar afirmaciones en wiki/ que referencien fuentes no presentes en `raw/`
   - Marcar con `[SIN-FUENTE]` para revisión posterior

3. **Detectar páginas no enlazadas desde INDEX.md**:
   ```bash
   # Páginas en wiki/ que no aparecen en INDEX.md
   comm -23 \
     <(ls .planning/knowledge/wiki/*.md | xargs -I{} basename {} .md | sort) \
     <(grep -oE '\[\[.+\]\]' .planning/knowledge/wiki/INDEX.md | tr -d '[]' | sort)
   ```

4. **Reportar resultados del lint en el log**:
   ```bash
   echo "## [$(date +%Y-%m-%d)] lint | wiki health check" >> .planning/knowledge/log.md
   echo "- Páginas huérfanas: [N]" >> .planning/knowledge/log.md
   echo "- Claims sin fuente: [N]" >> .planning/knowledge/log.md
   echo "- Páginas fuera del índice: [N]" >> .planning/knowledge/log.md
   ```

Si no hay wiki, omitir esta fase y continuar a Fase 4.

### Reglas de consolidación

- NUNCA eliminar un aprendizaje sin evidencia de que es incorrecto. Antigüedad sola no justifica eliminación — solo irrelevancia o contradicción.
- NUNCA leer transcripts exhaustivamente. Escanear títulos y buscar keywords específicos.
- Máximo 10 minutos de trabajo total. Si hay demasiado por consolidar, priorizar contradicciones y duplicados.
- Registrar la consolidación en el lock file para que el hook no vuelva a sugerir hasta la próxima ventana de 24h.
- **NUNCA persistir un aprendizaje que contradiga el wiki sin resolver la contradicción primero** (ver Paso 5.5).
