---
name: swl:wiki
description: >
  Gestiona el wiki de conocimiento del proyecto. Implementa el patrón de
  knowledge base persistente y compounding de Andrej Karpathy: tres capas
  separadas (raw/wiki/outputs) con index.md y log.md para navegación y
  trazabilidad. Subcomandos: init, ingest, query, lint.
allowed_tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
---

# /swl:wiki — Wiki de conocimiento del proyecto

Gestiona el knowledge base persistente del proyecto. A diferencia de
`.planning/APRENDIZAJES.md` (patrones técnicos de implementación), el wiki
almacena conocimiento de dominio, decisiones de investigación, arquitectura
conceptual y análisis que deben sobrevivir indefinidamente sin purgarse.

## Arquitectura del wiki

```
.planning/knowledge/
  raw/          ← fuentes crudas INMUTABLES (artículos, docs, notas, outputs de agentes)
  wiki/         ← síntesis mantenida por IA (una página .md por topic)
    INDEX.md    ← catálogo de todas las páginas (actualizado en cada ingest)
    log.md      ← historial cronológico append-only (parseable con grep)
    [topic].md  ← página por topic/agente/tecnología/decisión
  outputs/      ← respuestas a queries, análisis, comparativas (referencias al wiki)
```

**Separación de responsabilidades**:
- `raw/` → NUNCA modificar. Es la fuente de verdad. El LLM solo lee.
- `wiki/` → El LLM escribe y mantiene. El usuario lee.
- `outputs/` → El LLM escribe al responder queries. Se pueden reutilizar como fuentes.

---

## Subcomando: `init`

**Uso**: `/swl:wiki init`

Inicializa la estructura del wiki para el proyecto actual.

### Pasos

1. **Crear estructura de directorios**:

```bash
mkdir -p .planning/knowledge/raw
mkdir -p .planning/knowledge/wiki
mkdir -p .planning/knowledge/outputs
echo "✓ Estructura de directorios creada"
```

2. **Crear INDEX.md** — catálogo inicial:

```bash
cat > .planning/knowledge/wiki/INDEX.md << 'EOF'
---
tipo: indice
actualizado: YYYY-MM-DD
total_paginas: 0
---

# Índice del Wiki — [nombre del proyecto]

> Catálogo de todas las páginas del wiki. Actualizado automáticamente en cada ingest.
> Para navegar: leer esta página primero, luego profundizar en las páginas relevantes.

## Páginas por categoría

### Arquitectura y decisiones
_(vacío — agregar páginas vía `/swl:wiki ingest`)_

### Tecnologías y frameworks
_(vacío)_

### Investigaciones y análisis
_(vacío)_

### Procesos y metodología
_(vacío)_

---
_Wiki inicializado: [FECHA]. Usar `/swl:wiki ingest <archivo>` para agregar contenido._
EOF
```

Reemplazar `YYYY-MM-DD` y `[nombre del proyecto]` con los valores reales.

3. **Crear log.md** — historial cronológico:

```bash
cat > .planning/knowledge/wiki/log.md << 'EOF'
# Log del Wiki — Historial cronológico

> Registro append-only de operaciones. Parseable:
> `grep "^## \[" .planning/knowledge/wiki/log.md | tail -10`
> `grep "ingest" .planning/knowledge/wiki/log.md`

EOF
echo "## [$(date +%Y-%m-%d)] init | Wiki inicializado para el proyecto" >> .planning/knowledge/wiki/log.md
```

4. **Crear schema.md** — reglas del wiki para este proyecto:

```bash
cat > .planning/knowledge/schema.md << 'EOF'
# Schema del Wiki — Reglas y convenciones

## Qué es este wiki
Knowledge base del proyecto [NOMBRE]. Captura conocimiento de dominio,
decisiones técnicas, investigaciones y análisis que deben persistir
indefinidamente como memoria institucional del proyecto.

## Diferencia con APRENDIZAJES.md
- APRENDIZAJES.md → patrones de implementación técnica (código, bugs, anti-patrones)
- wiki/ → conocimiento de dominio, arquitectura conceptual, investigación (negocio, decisiones)

## Estructura de cada página wiki (patrón Compiled Truth)

Cada página wiki sigue el patrón **Compiled Truth**: síntesis curada arriba,
evidencia cronológica abajo. La síntesis es el conocimiento compilado y
actualizado; la timeline es el registro inmutable de cómo se llegó ahí.

Cada archivo en wiki/ debe seguir este formato:

```
---
topic: [nombre del topic]
categoria: arquitectura | tecnologia | investigacion | proceso
actualizado: YYYY-MM-DD
fuentes: [N archivos en raw/ que respaldan esta página]
confianza: alta | media | baja
---

# [Título]

## Compiled Truth (síntesis curada)

### Resumen
[Un párrafo que resume el topic — usado en INDEX.md]

### Estado actual
[Qué se sabe HOY sobre este topic. Afirmaciones verificadas con fuentes.
Cada afirmación clave marcada con [F:N] donde N refiere a la fuente en la
sección Timeline.]

### Decisiones vigentes
[Decisiones activas sobre este topic, con justificación breve.]

### Relaciones
- Relacionado con: [[otro-topic]], [[otro-topic-2]]
- Depende de: [[prerequisito]]
- Referenciado por: [[topic-que-lo-usa]]

## Timeline (evidencia cronológica)

### [YYYY-MM-DD] [F:1] — [nombre de la fuente]
- Aportó: [qué conocimiento agregó]
- Fuente: raw/YYYYMMDD-nombre-fuente.md

### [YYYY-MM-DD] [F:2] — [nombre de la fuente]
- Aportó: [qué conocimiento agregó]
- Cambió: [qué afirmación anterior se actualizó o contradijo]
- Fuente: raw/YYYYMMDD-nombre-fuente.md
```

**Reglas del patrón Compiled Truth**:
- La sección **Compiled Truth** es la fuente de verdad actual — se reescribe con cada ingest.
- La sección **Timeline** es append-only — nunca modificar entradas anteriores.
- Si una fuente nueva contradice una anterior, actualizar Compiled Truth Y agregar en Timeline con `Cambió:`.
- El campo `confianza` refleja cuántas fuentes independientes respaldan las afirmaciones: alta (3+), media (2), baja (1).

## Convenciones
- Links entre páginas: `[[nombre-archivo-sin-extension]]`
- Una página por topic, no por fuente
- El LLM actualiza wiki/ — el humano lee y valida
- raw/ es inmutable — nunca modificar archivos existentes
- outputs/ contiene respuestas completas — referenciar wiki/ para síntesis
- log.md es append-only — nunca editar entradas existentes

## Topics prioritarios para este proyecto
[Completar con los dominios específicos del proyecto — ej: "autenticación", "facturación", "arquitectura de microservicios"]
EOF
```

5. **Confirmación al usuario**:

```
✓ Wiki inicializado en .planning/knowledge/

Estructura creada:
  raw/       → depositar fuentes crudas aquí
  wiki/      → el LLM mantiene las páginas
  outputs/   → respuestas y análisis guardados
  INDEX.md   → catálogo de páginas (actualizado automáticamente)
  log.md     → historial cronológico de operaciones
  schema.md  → reglas del wiki (editar para personalizar al proyecto)

Próximos pasos:
  /swl:wiki ingest <archivo>   → ingerir primera fuente
  /swl:wiki query "<pregunta>" → consultar el wiki
  /swl:wiki lint               → health check periódico
```

---

## Subcomando: `ingest`

**Uso**: `/swl:wiki ingest <ruta-o-url>`

Ingiere una fuente en el wiki: lee, extrae knowledge, actualiza páginas relevantes,
actualiza INDEX.md y agrega entrada al log.

### Tipos de fuente soportados

| Tipo | Ejemplo | Herramienta |
|------|---------|-------------|
| `.md`, `.txt` (local) | `ingest ./notas/reunion.md` | Read |
| `.pdf` ≤ 20 páginas (local) | `ingest ./docs/guia.pdf` | Read con `pages:` |
| `.pdf` > 20 págs o con tablas | `ingest ./docs/reporte.pdf` | swl-markitdown |
| `.docx`, `.pptx` (local) | `ingest ./docs/arquitectura.docx` | swl-markitdown |
| `.xlsx`, `.xls` (local) | `ingest ./datos/metricas.xlsx` | swl-markitdown |
| `.ipynb` Jupyter (local) | `ingest ./notebooks/analisis.ipynb` | swl-markitdown |
| `.zip` con documentos | `ingest ./docs/documentacion.zip` | swl-markitdown |
| URL estática (HTML simple) | `ingest https://blog.domain.com/post` | WebFetch |
| URL dinámica (SPA, JS heavy) | `ingest https://spa-site.com/docs` | agent-browser |
| URL de YouTube | `ingest https://www.youtube.com/watch?v=...` | swl-markitdown |
| Output de agente previo | `ingest .planning/knowledge/outputs/2026-04-09-investigacion.md` | Read |

### Pasos del ingest

**Paso I.1 — Leer la fuente** (detección automática de herramienta):

```bash
PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
CLI_MKD="$PROJECT_ROOT/scripts/vendor/markitdown/cli.py"
FUENTE="[RUTA_O_URL]"

# Detectar tipo de fuente y elegir herramienta
if echo "$FUENTE" | grep -qE "^https?://"; then
  # Fuente web
  if echo "$FUENTE" | grep -qE "youtube\.com|youtu\.be"; then
    # YouTube: usar swl-markitdown para transcripción
    CONTENIDO=$(python "$CLI_MKD" "$FUENTE" 2>/dev/null)
  else
    # HTML: WebFetch primero, agent-browser como fallback
    CONTENIDO=$(# usar WebFetch tool aquí)
    PALABRAS=$(echo "$CONTENIDO" | wc -w)
    if [ "$PALABRAS" -lt 500 ]; then
      CONTENIDO=$(# usar agent-browser como fallback)
    fi
  fi
else
  # Archivo local: elegir según extensión
  EXT="${FUENTE##*.}"
  case "$EXT" in
    md|txt|markdown)
      # Read tool directamente
      ;;
    pdf)
      # Read para PDFs cortos; swl-markitdown para PDFs con tablas o > 20 págs
      CONTENIDO=$(python "$CLI_MKD" "$FUENTE" 2>/dev/null)
      ;;
    docx|pptx|xlsx|xls|ipynb|epub|zip|csv)
      # swl-markitdown para formatos que Read no soporta
      CONTENIDO=$(python "$CLI_MKD" "$FUENTE" 2>/dev/null)
      if [ -z "$CONTENIDO" ]; then
        echo "Error: swl-markitdown no pudo convertir $FUENTE"
        echo "Verificar: python $CLI_MKD --check"
        exit 1
      fi
      ;;
    *)
      # Intentar con swl-markitdown; si falla, reportar
      CONTENIDO=$(python "$CLI_MKD" "$FUENTE" 2>/dev/null)
      ;;
  esac
fi
```

**Paso I.2 — Guardar copia en raw/** (si la fuente es externa o fue convertida):

```bash
FECHA=$(date +%Y%m%d)
NOMBRE_LIMPIO=$(echo "[FUENTE]" | sed 's|https://||' | sed 's|[/. ]|-|g' | cut -c1-60)

# Para archivos Markdown/texto ya en formato correcto
cp "[FUENTE_LOCAL]" ".planning/knowledge/raw/${FECHA}-${NOMBRE_LIMPIO}.md"

# Para archivos convertidos con swl-markitdown (DOCX, XLSX, PPTX, etc.)
python "$CLI_MKD" "[FUENTE_LOCAL]" > ".planning/knowledge/raw/${FECHA}-${NOMBRE_LIMPIO}.md" 2>/dev/null

# Para URLs (WebFetch o agent-browser)
# agent-browser get text "article" > ".planning/knowledge/raw/${FECHA}-${NOMBRE_LIMPIO}.md"
```

**Paso I.3 — Extraer knowledge de la fuente**:

Leer la fuente completa e identificar:
- Topics principales cubiertos
- Entidades mencionadas (tecnologías, patrones, decisiones, personas)
- Afirmaciones verificables con su fuente
- Relaciones con topics que ya existen en el wiki

**Paso I.4 — Actualizar páginas wiki existentes**:

Para cada topic cubierto en la fuente que ya tiene página en `wiki/`:
- Leer la página existente
- **Compiled Truth**: Reescribir la sección "Estado actual" integrando la información nueva con la existente. No eliminar afirmaciones válidas — solo actualizarlas o expandirlas.
- **Timeline**: Agregar nueva entrada cronológica append-only con `[F:N]` y lo que la fuente aportó. Si contradice algo, incluir `Cambió:` en la entrada.
- Actualizar la fecha `actualizado` y el campo `fuentes` (incrementar) en el frontmatter
- Actualizar `confianza`: baja (1 fuente) → media (2) → alta (3+)
- Si la nueva info contradice la anterior: actualizar Compiled Truth con la versión correcta Y registrar el cambio en Timeline con `Cambió:`

**Paso I.5 — Crear páginas wiki nuevas** (para topics que no tienen página):

Para cada topic nuevo identificado que justifique su propia página (criterio: ≥3 afirmaciones distintas sobre el mismo topic):

```bash
cat > ".planning/knowledge/wiki/[nombre-topic].md" << 'EOF'
---
topic: [nombre]
categoria: [arquitectura|tecnologia|investigacion|proceso]
actualizado: YYYY-MM-DD
fuentes: 1
confianza: baja
---

# [Título del topic]

## Compiled Truth (síntesis curada)

### Resumen
[Un párrafo conciso — este texto va al INDEX.md]

### Estado actual
[Afirmaciones verificadas, marcadas con [F:1] referenciando la timeline.]

### Decisiones vigentes
[Decisiones activas si aplica, o eliminar sección si no hay.]

### Relaciones
- Relacionado con: [otros topics del wiki si aplica]

## Timeline (evidencia cronológica)

### [YYYY-MM-DD] [F:1] — [nombre de la fuente]
- Aportó: [qué conocimiento agregó]
- Fuente: raw/YYYYMMDD-nombre-fuente.md
EOF
```

**Paso I.6 — Actualizar INDEX.md**:

Agregar o actualizar la entrada del topic nuevo en INDEX.md:

```bash
# Agregar al INDEX.md bajo la categoría correspondiente:
# | [[nombre-topic]] | [resumen de una línea] | [YYYY-MM-DD] |
```

Estructura de la tabla en INDEX.md:
```markdown
| Página | Resumen | Actualizado |
|--------|---------|-------------|
| [[nombre-topic]] | Resumen de una línea | YYYY-MM-DD |
```

**Paso I.7 — Agregar al log**:

```bash
echo "## [$(date +%Y-%m-%d)] ingest | [nombre de la fuente] → [N páginas tocadas]" \
  >> .planning/knowledge/wiki/log.md
echo "  Fuentes en raw: $(ls .planning/knowledge/raw/ | wc -l) total" \
  >> .planning/knowledge/wiki/log.md
```

**Paso I.8 — Reporte al usuario**:

```
Ingest completado: [nombre de la fuente]

Páginas actualizadas: [N]
  - wiki/[topic1].md — [qué se actualizó]
  - wiki/[topic2].md — [qué se actualizó]

Páginas nuevas creadas: [N]
  - wiki/[nuevo-topic].md — [descripción]

INDEX.md actualizado: [N] entradas
log.md: entrada agregada

[Si hay contradicciones detectadas:]
⚠ Contradicciones detectadas — revisar antes de continuar:
  - wiki/[topic].md contradice raw/[fuente-anterior].md en: [claim]
```

---

## Subcomando: `query`

**Uso**: `/swl:wiki query "<pregunta>"`

Responde una pregunta usando el knowledge base del wiki. Guarda la respuesta
en `outputs/` para que componga en el knowledge base.

### Pasos del query

**Paso Q.1 — Leer INDEX.md primero**:

```bash
cat .planning/knowledge/wiki/INDEX.md
```

Identificar qué páginas del wiki son relevantes para la pregunta.
**No cargar todo el wiki** — solo las páginas identificadas en el índice.

**Paso Q.2 — Leer páginas relevantes**:

Para cada página identificada como relevante:
```bash
cat .planning/knowledge/wiki/[topic].md
```

Máximo 5-7 páginas por query para mantener el costo bajo.
Si la pregunta requiere más páginas, descomponerla en sub-preguntas.

**Paso Q.3 — Sintetizar respuesta**:

Responder la pregunta basándose SOLO en el contenido del wiki.
Si la pregunta no puede responderse con el wiki actual, indicarlo explícitamente:
```
⚠ El wiki actual no tiene suficiente información sobre [aspecto].
Fuentes faltantes sugeridas:
  - [tipo de fuente que respondería esto]
  
¿Ejecutar investigación con investigador-swl para completar el wiki?
```

**Paso Q.4 — Guardar output**:

```bash
FECHA=$(date +%Y-%m-%d)
PREGUNTA_SLUG=$(echo "[PREGUNTA]" | tr ' ' '-' | tr '[:upper:]' '[:lower:]' | cut -c1-50)
OUTPUT_PATH=".planning/knowledge/outputs/${FECHA}-query-${PREGUNTA_SLUG}.md"

cat > "$OUTPUT_PATH" << 'EOF'
---
fecha: YYYY-MM-DD
tipo: query
pregunta: "[PREGUNTA]"
paginas_consultadas: [LISTA]
---

# Respuesta: [PREGUNTA]

[RESPUESTA COMPLETA]

## Fuentes wiki consultadas
- [[topic1]]
- [[topic2]]
EOF

echo "✓ Respuesta guardada en: $OUTPUT_PATH"
```

**Paso Q.5 — Proponer si el output debe incorporarse al wiki**:

```
Output guardado en outputs/[archivo].md

¿Incorporar esta respuesta al wiki?
[S] Sí — es un análisis valioso que debería estar en wiki/
[N] No — es una respuesta puntual que no suma al wiki
```

Si el usuario dice Sí: ejecutar ingest sobre el output para integrarlo al wiki.

---

## Subcomando: `lint`

**Uso**: `/swl:wiki lint`

Health check del wiki. Detecta problemas de calidad antes de que se acumulen.
Ejecutar mensualmente o después de ingestas masivas.

### Verificaciones del lint

**L.1 — Páginas huérfanas** (sin referencias desde otras páginas):

```bash
echo "=== Páginas huérfanas ==="
for PAGE in .planning/knowledge/wiki/*.md; do
  NOMBRE=$(basename "$PAGE" .md)
  [ "$NOMBRE" = "INDEX" ] || [ "$NOMBRE" = "log" ] && continue
  REFS=$(grep -r "\[\[$NOMBRE\]\]" .planning/knowledge/wiki/ 2>/dev/null | \
         grep -v "^$PAGE:" | wc -l)
  INDEX_REF=$(grep "\[\[$NOMBRE\]\]" .planning/knowledge/wiki/INDEX.md 2>/dev/null | wc -l)
  TOTAL=$((REFS + INDEX_REF))
  [ "$TOTAL" -eq 0 ] && echo "  HUERFANA: $NOMBRE"
done
```

**L.2 — Páginas fuera del INDEX.md**:

```bash
echo "=== Páginas no indexadas ==="
for PAGE in .planning/knowledge/wiki/*.md; do
  NOMBRE=$(basename "$PAGE" .md)
  [ "$NOMBRE" = "INDEX" ] || [ "$NOMBRE" = "log" ] && continue
  INDEXED=$(grep "\[\[$NOMBRE\]\]" .planning/knowledge/wiki/INDEX.md 2>/dev/null | wc -l)
  [ "$INDEXED" -eq 0 ] && echo "  NO INDEXADA: $NOMBRE"
done
```

**L.3 — Páginas con frontmatter desactualizado** (no actualizadas en >60 días):

```bash
echo "=== Páginas posiblemente desactualizadas (>60 días) ==="
HACE_60=$(date -d "60 days ago" +%Y-%m-%d 2>/dev/null || \
          date -v-60d +%Y-%m-%d 2>/dev/null)  # macOS fallback
grep -r "actualizado:" .planning/knowledge/wiki/*.md 2>/dev/null | \
  awk -F: '{if ($2 < "'$HACE_60'") print "  VIEJA: " $1 " (" $2 ")"}'
```

**L.4 — Contradicciones marcadas pendientes**:

```bash
echo "=== Contradicciones marcadas sin resolver ==="
grep -r "\[CONTRADICE:" .planning/knowledge/wiki/*.md 2>/dev/null | \
  sed 's/:.*//' | sort -u
```

**L.5 — Claims sin fuente en raw/**:

```bash
echo "=== Páginas wiki sin fuentes en raw/ ==="
for PAGE in .planning/knowledge/wiki/*.md; do
  NOMBRE=$(basename "$PAGE" .md)
  [ "$NOMBRE" = "INDEX" ] || [ "$NOMBRE" = "log" ] && continue
  FUENTES=$(grep "^- raw/" "$PAGE" 2>/dev/null | wc -l)
  [ "$FUENTES" -eq 0 ] && echo "  SIN FUENTE: $NOMBRE"
done
```

**L.6 — Tamaño del wiki** (métricas de salud):

```bash
echo "=== Métricas del wiki ==="
echo "  Páginas totales: $(ls .planning/knowledge/wiki/*.md 2>/dev/null | grep -v "INDEX\|log" | wc -l)"
echo "  Fuentes en raw/: $(ls .planning/knowledge/raw/ 2>/dev/null | wc -l)"
echo "  Outputs guardados: $(ls .planning/knowledge/outputs/ 2>/dev/null | wc -l)"
echo "  Último ingest: $(grep "^## \[" .planning/knowledge/wiki/log.md 2>/dev/null | tail -1)"
echo "  Entradas en log: $(grep "^## \[" .planning/knowledge/wiki/log.md 2>/dev/null | wc -l)"
```

### Acciones recomendadas post-lint

Basándose en los resultados:

| Hallazgo | Acción recomendada |
|----------|-------------------|
| Páginas huérfanas | Agregar links desde páginas relacionadas O eliminar si el topic ya no es relevante |
| Páginas sin indexar | Agregar al INDEX.md bajo la categoría correcta |
| Páginas >60 días sin actualizar | Revisar si el contenido sigue siendo válido; marcar como `[REVISAR]` si hay dudas |
| Contradicciones pendientes | Resolver antes del próximo ingest — ver protocolo en `/swl:aprender` Paso 5.5 |
| Páginas sin fuente | Agregar la fuente a `raw/` O marcar el contenido como `[SIN-FUENTE: verificar]` |

### Reporte del lint

```bash
# Agregar al log
echo "## [$(date +%Y-%m-%d)] lint | health check completado" >> .planning/knowledge/wiki/log.md
echo "  Hallazgos: [N huérfanas] huérfanas, [N] sin indexar, [N] contradicciones" \
  >> .planning/knowledge/wiki/log.md
```

Mostrar al usuario:
```
Wiki health check completado:

✓ Páginas totales: [N]
✓ Fuentes en raw/: [N]

Hallazgos:
  Páginas huérfanas:     [N] → [lista]
  Páginas sin indexar:   [N] → [lista]
  Páginas desactualizadas: [N] → [lista]
  Contradicciones:       [N] → [lista]
  Páginas sin fuente:    [N] → [lista]

[Si todo OK:]
✓ Wiki en buen estado — sin problemas críticos detectados.

[Si hay hallazgos:]
¿Quieres que resuelva los hallazgos ahora? [S/N]
```

---

## Integración con otros comandos SWL

| Comando | Integración con wiki |
|---------|---------------------|
| `/swl:aprender` | Paso 5.5 verifica consistencia con wiki antes de persistir; Fase 4.5 ejecuta lint del wiki |
| `/swl:mapear-codebase` | El mapa del codebase puede ingresarse al wiki como fuente inicial |
| `investigador-swl` | Guarda outputs en `outputs/` y fuentes en `raw/` automáticamente |
| `arquitecto-swl` | Los ADRs pueden ingresarse al wiki como páginas de decisión |
| `/swl:checkpoint` | Puede hacer referencia al INDEX.md del wiki para contexto de sesión |

## Reglas del sistema

- `raw/` es **INMUTABLE** — nunca modificar archivos existentes; solo agregar nuevos.
- `wiki/` es **responsabilidad del LLM** — el humano lee, el LLM escribe y mantiene.
- `log.md` es **append-only** — nunca editar entradas existentes.
- Cada ingest debe tocar entre 1 y 15 páginas wiki como máximo. Si una fuente toca más de 15 temas distintos, dividir en múltiples ingests.
- Un topic que aparece en <3 fuentes no justifica su propia página — agregarlo a una página relacionada.
- Los outputs en `outputs/` son legibles pero no se indexan automáticamente en INDEX.md — solo si el usuario confirma que deben incorporarse al wiki.
