---
name: nemesis-redistribuir
description: >
  Protocolo de redistribución del scope cuando una auditoría nemesis supera
  los umbrales que saturan la context window del agente evaluator (>1500 LOC
  o >5 archivos en módulos distintos). Divide el scope en sub-scopes coherentes,
  ejecuta el evaluator una vez por sub-scope con ventana fresca, y consolida
  los reportes parciales en un veredicto unificado. Cargar desde el comando
  /swl:nemesis cuando la fase 0 detecta scope grande, antes de invocar al
  agente nemesis-auditor-swl. NO cargar para scope pequeño — el bucle iterativo
  Feynman+State del agente es más profundo que la redistribución.
version: "1.0.0"
exclusiones:
  - "No cargar para scope <1500 LOC ni <5 archivos — el agente Nemesis directo es suficiente."
  - "No cargar fuera del flujo /swl:nemesis — la redistribución es específica de ese comando."
  - "No cargar para revisiones de otros tipos (revisor-codigo, revisor-seguridad) — esos no requieren redistribución por scope."
---

# Redistribución de scope para Nemesis

Este skill implementa el patrón "divide & consolidate" cuando una auditoría
nemesis no cabe en una sola invocación del agente evaluator. El bug que
originó esta solución es el incidente SIGM 2026-05-16 documentado en
ADR-0021: el agente saturó Sonnet 4.6 (200K context) en la pasada 4-5 de 6
con scope de ~3170 LOC.

El skill **NO sustituye** al protocolo Feynman+State del agente. Lo aplica
en porciones coherentes del codebase con context fresca por porción.

---

## Cuándo cargar

- El comando `/swl:nemesis` en su Fase 0 detectó que el scope supera el
  umbral de redistribución.
- El usuario invocó explícitamente `/swl:nemesis --redistribuir` (forzado).
- Un componente downstream (orquestador, hook de telemetría) necesita
  conocer el formato del plan de redistribución para coordinar.

## Cuándo NO cargar

- Scope ≤ 1500 LOC y ≤ 5 archivos: el bucle iterativo normal del agente
  evaluator cabe sin problema. Redistribuir aquí degrada profundidad.
- Auditoría dirigida con `--modulo` ya acotado por el usuario: respetar la
  decisión explícita. NO sobre-dividir lo que el usuario ya delimitó.
- Modo `--pass1` o `--pass2` sin loop: una sola pasada cabe en cualquier
  contexto razonable. La redistribución agregaría overhead sin ganancia.

---

## Umbrales canónicos

| Métrica | Umbral | Justificación |
|---------|--------|---------------|
| LOC totales del scope | > 1500 | El bucle Feynman+State con feed-forward llega a ~3-4× del scope en tokens hacia la pasada 4. 1500 LOC × 4 ≈ 80K tokens cabe; >1500 LOC tiende a saturar 200K en pasadas finales. |
| Archivos en módulos distintos | > 5 | Cada módulo introduce vocabulario y contratos propios; >5 dominios distintos hacen que el agente pierda foco entre pasadas. |
| Profundidad de directorios | > 4 niveles desde root | Heurística secundaria — codebases profundos suelen tener acoplamiento implícito que el agente no captura en una sola invocación. |

**Activar redistribución si CUALQUIERA de los tres umbrales se supera.** No
requerir los tres simultáneamente. Es defensa conservadora.

Los umbrales son heurísticos iniciales basados en el incidente SIGM. La
auto-evolución del skill ajustará valores con telemetría real.

---

## Protocolo de redistribución

### Fase 1 — Análisis del scope

```bash
# Contar LOC reales (excluyendo blank lines y comentarios single-line)
find <scope> -type f \( -name "*.py" -o -name "*.ts" -o -name "*.go" -o -name "*.rs" -o -name "*.java" -o -name "*.cs" -o -name "*.sql" \) | \
    xargs grep -cv "^[[:space:]]*$\|^[[:space:]]*#\|^[[:space:]]*//" | \
    awk -F: '{sum += $2} END {print sum}'

# Listar archivos por módulo (primer subdirectorio bajo backend/, frontend/, database/, etc.)
find <scope> -type f -name "*.py" | awk -F/ '{print $1"/"$2"/"$3}' | sort -u
```

Producir un análisis estructurado:

```json
{
  "loc_total": 3170,
  "archivos": 14,
  "modulos": [
    { "ruta": "backend/app/auth/", "archivos": 5, "loc": 627 },
    { "ruta": "backend/app/db/", "archivos": 1, "loc": 345 },
    { "ruta": "database/schemas/", "archivos": 3, "loc": 1057 },
    { "ruta": "database/policies/", "archivos": 4, "loc": 775 },
    { "ruta": "database/functions/", "archivos": 1, "loc": 166 }
  ],
  "supera_umbrales": ["loc_total", "archivos_modulos_distintos"]
}
```

### Fase 2 — División en sub-scopes coherentes

Reglas de división, en orden de prioridad:

1. **Por capa arquitectónica** cuando aplica: separar `backend/`, `frontend/`,
   `database/`, `mobile/`. Estas capas tienen vocabularios diferentes y el
   agente trabaja mejor con una a la vez.

2. **Por dominio de negocio** dentro de una capa: si `backend/app/` tiene
   `auth/`, `pagos/`, `usuarios/` y cada uno excede 500 LOC, dividir por
   dominio. Los acoplamientos cross-dominio son input para una pasada de
   consolidación posterior, no para la pasada inicial.

3. **Por archivo de tamaño excepcional**: si un solo archivo supera 1000 LOC
   (caso típico de `repository.py` o `schema.sql` monolíticos), tratarlo
   como sub-scope independiente. El agente puede dedicarle una pasada
   completa sin distracción.

4. **Por relación contractual**: schema SQL + funciones PL/pgSQL + policies
   RLS de un mismo dominio van juntas (no se divide schema de su policy
   correspondiente — el agente perdería la correlación).

Plan resultante en `.planning/audit/nemesis-plan.json`:

```json
{
  "modo": "redistribuido",
  "fecha_generacion": "2026-05-16T20:00:00Z",
  "scope_original": ["backend/app/auth/", "database/schemas/002-schema-usuario.sql", "database/policies/"],
  "sub_scopes": [
    {
      "id": "sub-1-auth-backend",
      "archivos": ["backend/app/auth/router.py", "backend/app/auth/service.py", "backend/app/auth/dependencies.py", "backend/app/auth/schemas.py"],
      "loc": 627,
      "dominio": "Autenticación backend Python",
      "orden_ejecucion": 1
    },
    {
      "id": "sub-2-auth-schema",
      "archivos": ["database/schemas/002-schema-usuario.sql", "database/schemas/010-schema-token-revocacion.sql"],
      "loc": 955,
      "dominio": "Schema SQL usuario + tokens",
      "orden_ejecucion": 2
    },
    {
      "id": "sub-3-rls-policies",
      "archivos": ["database/policies/rls.sql", "database/policies/rls-fase5.sql"],
      "loc": 499,
      "dominio": "Row Level Security policies",
      "orden_ejecucion": 3
    }
  ],
  "consolidacion_requerida": true,
  "razon_redistribuir": "loc_total=3170 (>1500) + archivos_modulos_distintos=5 (>5)"
}
```

### Fase 3 — Ejecución secuencial de sub-scopes

El comando `/swl:nemesis` invoca al agente `nemesis-auditor-swl` una vez por
sub-scope, en el orden declarado en `nemesis-plan.json`. Cada invocación:

- Recibe scope acotado al sub-scope correspondiente.
- Recibe **`sub_id`** (el campo `id` del sub-scope en el plan, ej: `"sub-1-auth-backend"`).
  El agente USA `sub_id` para construir la ruta de output. **Sin `sub_id`, todos
  los sub-scopes escribirían al mismo `iter-N/` y se sobreescribirían entre sí.**
- Recibe `iter` (1, 2 o 3 según iteración del loop).
- Produce `.planning/audit/findings/iter-N/<sub_id>/evaluacion.json` + reporte markdown.
- Es invocación independiente con context window fresca (no acumula del
  sub-scope anterior).

**Contrato del comando ↔ agente**:

```
invocar(nemesis-auditor-swl,
        scope=sub_scope.archivos,
        iter=<1..3>,
        sub_id=sub_scope.id)
```

El agente DEBE respetar `sub_id` al escribir. Si recibe `null` o `undefined`,
opera en modo monolítico (escribe a `iter-N/` sin subdirectorio).

**Importante**: ejecutar **secuencialmente**, no en paralelo. La razón:

- Permite que el agente del sub-scope N+1 cargue `Skill("memoria-busqueda")`
  y consulte los hallazgos del sub-scope N para detectar correlaciones.
- Evita race conditions sobre `.planning/audit/findings/`.
- Suaviza el costo de tokens (no se acumulan N invocaciones simultáneas).

Si el costo de secuencial es prohibitivo, considerar paralelo solo cuando
los sub-scopes son **arquitectónicamente independientes** (capas separadas
sin acoplamiento esperado).

### Fase 4 — Consolidación

Tras completar todos los sub-scopes, el comando genera un `evaluacion.json`
consolidado en `.planning/audit/findings/iter-N/evaluacion.json`:

```json
{
  "schema_version": "1.0.0",
  "metadata": {
    "iteracion": 1,
    "modo": "redistribuido",
    "sub_scopes_consolidados": ["sub-1-auth-backend", "sub-2-auth-schema", "sub-3-rls-policies"]
  },
  "veredicto": {
    "status": "NEEDS_IMPROVEMENT",
    "puede_remediar_automaticamente": true
  },
  "hallazgos": [
    /* concatenación de hallazgos de todos los sub-scopes, con prefijo de origen */
    /* ej: hallazgos del sub-1 tienen id "S1-F-04", del sub-2 tienen "S2-F-04" */
  ],
  "correlaciones_cross_subscope": [
    {
      "descripcion": "F-04 (sub-1, backend no incrementa intentos_fallidos) correlaciona con S2-X (schema declara la columna). Ambos hallazgos comparten causa raíz.",
      "hallazgos_ligados": ["S1-F-04", "S2-X"],
      "accion_unificada": "Una sola implementación cierra ambos."
    }
  ]
}
```

La consolidación es responsabilidad del comando, **no** del agente. El skill
provee el formato; el comando lo materializa con datos reales de los sub-scopes.

### Detección de correlaciones cross-subscope

Tras consolidar, el comando puede invocar al agente `nemesis-auditor-swl` con
**scope mínimo** (~50 LOC seleccionados estratégicamente) y skills
`memoria-busqueda` + el reporte consolidado como input, para que detecte
correlaciones cross-subscope que ninguna pasada individual encontró.

Esta "pasada de consolidación" es opcional. Se activa cuando:

- Hay 2+ sub-scopes con hallazgos.
- Los sub-scopes comparten al menos un identificador (tabla, función, módulo
  importado) — detectable con grep simple.
- El presupuesto de tokens lo permite.

---

## Formato del plan persistido

`.planning/audit/nemesis-plan.json` — schema:

```typescript
interface NemesisPlan {
    schema_version: "1.0.0";
    modo: "redistribuido";
    fecha_generacion: string;  // ISO 8601
    scope_original: string[];  // paths
    sub_scopes: SubScope[];
    consolidacion_requerida: boolean;
    razon_redistribuir: string;  // formato "metrica1=valor1 (>umbral1) + ..."
}

interface SubScope {
    id: string;  // "sub-N-<dominio-kebab>"
    archivos: string[];  // paths relativos
    loc: number;
    dominio: string;  // descripción humana
    orden_ejecucion: number;  // 1-indexed
    consolidacion_inputs?: string[];  // ids de sub-scopes cuyos hallazgos
                                      // este sub-scope debe considerar como contexto
}
```

---

## Reglas estrictas

### Trazabilidad

Cada hallazgo del reporte consolidado DEBE incluir prefijo del sub-scope de
origen (`S1-F-04`, `S2-F-12`). Permite al implementador:

- Localizar el reporte parcial original.
- Reproducir el sub-scope con `/swl:nemesis --pass1 --modulo <archivos del sub-scope>`.
- Auditar qué porción del codebase produjo qué hallazgos.

### Registro en nudges.jsonl

El comando DEBE registrar la activación del modo redistribuido en
`.planning/nudges.jsonl`:

```json
{
  "timestamp": "2026-05-16T20:00:00Z",
  "tipo": "nemesis-redistribuido",
  "mutation_category": "scope-adaptation",
  "risk_level": "low",
  "razon": "loc_total=3170 (>1500)",
  "sub_scopes": 3,
  "archivo_plan": ".planning/audit/nemesis-plan.json"
}
```

Esto alimenta la telemetría de auto-evolución (regla `memoria-consolidada.md
§ Estado del sistema y observabilidad`) y permite ajustar umbrales con datos
reales.

### Idempotencia

Si `.planning/audit/nemesis-plan.json` ya existe y `--continue` fue pasado al
comando, reutilizar el plan existente. NO regenerar — la división puede
diferir si el filesystem cambió entre invocaciones y eso rompe la trazabilidad.

Para forzar regeneración del plan: `/swl:nemesis --redistribuir --reset-plan`.

---

## Anti-patrones

- **Dividir scope ya pequeño**: aplicar redistribución a < 1500 LOC introduce
  overhead sin ganancia. Verificar umbrales antes de cargar este skill.

- **Dividir por número de archivos sin coherencia**: 10 archivos del mismo
  módulo NO requieren división — el agente puede manejarlos juntos. El criterio
  es **dominios diferentes**, no archivos totales.

- **Paralelizar sub-scopes con acoplamiento implícito**: ejecutar `auth/` y
  `db/tenant.py` en paralelo pierde la correlación que el agente vería en
  ejecución secuencial. Solo paralelo cuando los sub-scopes son
  arquitectónicamente independientes.

- **Olvidar la pasada de consolidación**: si la auditoría es de un sistema
  con alto acoplamiento entre módulos (auth + RLS + tokens), omitir la
  consolidación deja hallazgos cross-módulo sin detectar. Tablar la decisión
  en el plan.

- **Trazabilidad perdida**: emitir hallazgos consolidados sin prefijo `SN-`.
  Cuando el implementador quiera reproducir un hallazgo específico, no sabrá
  qué sub-scope re-auditar.

---

## Referencias

- ADR-0021: `nemesis-evaluator-optimizer` — define el modo redistribuido como
  parte del patrón completo.
- `reglas/analisis-previo-tareas-grandes.md`: aplica el mismo principio
  "dividir antes de implementar" pero a auditoría en lugar de implementación.
- `reglas/seguridad-agentes.md § Anti-fallback silencioso`: justifica registrar
  la activación de redistribución como nudge explícito, no como decisión
  silenciosa.
- Incidente SIGM 2026-05-16: caso real que motivó los umbrales canónicos.
