---
name: meta-skills-estandar
description: >
  Referencia extendida del estándar de skills SWL. Complementa la regla
  obligatoria `reglas/skills-estandar.md` con: Response Discipline,
  Anti-substitution Guardrails, campo dual `herramientasPermitidas`/
  `allowed-tools`, nivel de control de instrucciones, reglas detalladas
  para scripts/ y recursos/, y recursos/ con anti-patrones, leyes de diseño,
  idiomas de framework y mapeo a frameworks de seguridad. Cargar cuando se
  esté escribiendo o auditando un SKILL.md y se necesiten patrones avanzados
  que no están en la regla core.
version: "1.1.1"
evolved: true
evolved-from: "1.1.0"
evolved-at: "2026-05-16"
evolved-by: "aprender"
evolved-note: "v1.1.0 MINOR: 3 secciones nuevas (contratos controller↔worker + return explícito + evaluator-optimizer). v1.1.1 PATCH: corrige inconsistencia interna — ejemplos de la sección 'Pseudocódigo con return' usaban iter=0/while iter<3, contradiciendo el contrato 1-based de la sección anterior. Mismo skill que enseña off-by-one no debe cometerlo en sus ejemplos."
herramientasPermitidas: [Read, Write, Edit]
exclusiones:
  - "No cargar si solo se necesita el frontmatter obligatorio, el límite de líneas o la estructura de directorio — eso está en la regla core `reglas/skills-estandar.md` que se carga siempre."
  - "No cargar para crear un skill simple de dominio conceptual sin comandos prescritos ni herramientas específicas — las reglas core bastan."
  - "No cargar para consultar el checklist de auditoría, la convención de naming o el proceso de creación — los tres viven en la regla core."
  - "No cargar para skills fuera del dominio seguridad — el mapeo a frameworks (NIST, MITRE) solo aplica al dominio seguridad."
evolvable: true
---

# meta-skills-estandar — Referencia extendida del estándar de skills

Complementa la regla `reglas/skills-estandar.md` con detalles, ejemplos y
tablas que no son estrictamente obligatorios para cualquier skill pero sí
son referencia crítica cuando aplican. Separar este contenido de la regla
core reduce el costo de contexto por sesión ~7,000 tokens cuando no se
escriben skills activamente.

## Cuándo cargar

- Al escribir un skill nuevo cuya descripción prescribe comandos, snippets
  o verdicts específicos → Response Discipline + Anti-substitution.
- Al auditar un skill existente contra leyes de diseño de alta señal.
- Al escribir skills de framework específico (FastAPI, Django, NestJS,
  Spring Boot) que requieren patrones idiomáticos.
- Al agregar mapeos de seguridad (NIST, MITRE) al frontmatter.
- Al configurar el campo dual `herramientasPermitidas` / `allowed-tools`.
- Al migrar skills viejos a nombres de campo en español.
- Al diagnosticar falsos positivos del evaluador `evaluar-skill`.

## Cuándo NO cargar

- Solo se necesita frontmatter obligatorio o estructura de directorio.
- Se consulta el checklist de auditoría (vive en la regla core).
- Skill sin comandos prescritos ni herramientas específicas.
- Skill fuera del dominio seguridad → no necesita mapeo a frameworks.

---

## Nivel de control de instrucciones

Calibrar la especificidad de las instrucciones según el costo de error:

| Nivel | Cuándo usar | Técnica |
|-------|-------------|---------|
| Alto (libertad máxima) | Code review, texto, análisis | Objetivos + restricciones, sin pasos |
| Medio | Runbooks, deploys | Preferencias explícitas, pasos sugeridos |
| Bajo (control máximo) | Migraciones BD, operaciones destructivas | Pasos exactos, scripts precisos, sin variación |

Skills de nivel bajo DEBEN incluir:
- Checklist de ejecución progresiva (no solo verificación post-hoc).
- Sección Known Gotchas con modos de falla concretos.
- Preferentemente un script en `scripts/` que ejecute la operación determinista.

El tono del skill (persona al inicio, si la hay) también es un control:
establece la rúbrica de juicio del modelo.

---

## Response Discipline (OBLIGATORIO para skills de comando)

Aplica a skills cuyo producto principal es un comando, snippet o verdict
token (ej: `swl-markitdown`, `dbml-experto`, `likec4-experto`). **No aplica**
a skills de dominio conceptual (patrones, testing, seguridad).

### Reglas

1. **Command-first / snippet-first**. Si el prompt pide `"minimal"`, `"strict"`,
   `"exact"`, `"paste-ready"` o una línea específica: responde con un solo
   comando/snippet/verdict como primera línea, sin preámbulo ni alternativas.
2. **Una sola respuesta canónica**. No dar "opción A vs opción B" en prompts
   strict.
3. **Primera línea es autoridad**. Si el prompt requiere un token específico
   (`VALIDATE OK`, `npx X`), esa es la primera línea. Explicación después.
4. **Prose-only es falla** cuando se pide snippet/comando. Una explicación
   sin el comando exacto es incorrecta aunque el contenido sea acertado.
5. **Documentar el patrón** con sección `## Response Discipline` listando qué
   keywords activan respuesta estricta en ese dominio.

### Ejemplo

Prompt: *"Minimal command to validate schema.dbml strictly."*

MAL: *"Para validar un esquema DBML puedes usar varias opciones..."*
BIEN: `npx @dbml/cli validate schema.dbml --strict`

---

## Anti-substitution Guardrails (OBLIGATORIO para skills que prescriben herramientas)

Las skills que prescriben comandos, flags o APIs DEBEN listar sustituciones
prohibidas más comunes para prevenir que el LLM invente alternativas plausibles
pero incorrectas.

### Formato obligatorio

```markdown
## Anti-substitution guardrails

- Familia <nombre>: usar `<comando-canónico>` (nunca sustituir con
  `<alternativa-plausible-1>`, `<alternativa-plausible-2>`).
- Flag de <propósito>: usar `--<flag-canónico>` (nunca `--<flag-parecido>`).
- API de <propósito>: usar `<método.canónico>` (nunca `<método.parecido>`).
```

### Criterios para incluir una entrada

Una sustitución se lista solo si **TODAS** son verdaderas:

- La alternativa es plausible (existe, funciona para algo).
- La alternativa es incorrecta en el contexto específico de la skill.
- Un LLM sin la guardrail la produciría con probabilidad >5%.

No listar sustituciones obvias (`cd` vs `ls`) ni imposibles (`curl` vs `cat`).

### Ejemplo — skill `/swl:cron`

```markdown
## Anti-substitution guardrails

- Schedule recurrente: usar `every 2h` (nunca `@every 2h`, `*/2 * * * *`
  cuando el usuario pidió "cada 2 horas" sin constraints específicos).
- Crear job: usar subcomando `add` (nunca `create`, `new`, `register`).
- Eliminar job: usar `remove <id>` (nunca `delete`, `rm`, `drop`).
```

---

## Reglas detalladas para `scripts/`

**Cuándo crear un script**: la lógica es determinista, costosa de regenerar,
no requiere razonamiento contextual y se reutiliza ≥2 veces por sesión.

**Cuándo NO crearlo**: la lógica cambia por proyecto, necesita acceso runtime
a sistema, es simple (<5 líneas), o no se reutilizaría.

**Detección empírica**: ejecutar el skill en 3 casos de uso. Si el modelo
regeneró el mismo helper 2+ veces independientemente, ese helper es candidato
a `scripts/`.

**Referencia desde SKILL.md**:

```markdown
`python scripts/validar-frontmatter.py ruta/al/SKILL.md`
```

Los scripts NUNCA entran en contexto automáticamente. Claude los ejecuta vía
bash y procesa solo el output. Los scripts deben:

- Imprimir resultados claros en stdout.
- Usar exit codes estándar (0 = éxito, 1 = error).
- Documentar su uso en las primeras 5 líneas.

---

## Reglas detalladas para `recursos/`

**Cuándo crear un recurso**: plantilla reutilizable, ejemplo de código completo,
esquema de referencia, documentación extendida que no cabe en SKILL.md, o
lista de referencia extensa.

**Referencia desde SKILL.md**:

```markdown
Usar la plantilla en [recursos/claude-md-template.md](recursos/claude-md-template.md)
```

Los paths SIEMPRE son relativos al directorio de la skill.

**ToC obligatoria si supera 200 líneas**: incluir tabla de contenido al inicio
para que lecturas truncadas sigan siendo útiles:

```markdown
## Contenido

- [Sección A](#sección-a)
- [Sección B](#sección-b)
```

---

## Campo dual: `herramientasPermitidas` y `allowed-tools`

**Principio de 3 capas**: `herramientasPermitidas` es el campo autoritativo del
sistema SWL (español). `allowed-tools` es el campo del protocolo Anthropic que
Claude Code lee (inglés, no negociable). Ambos coexisten con la misma semántica.

### Cuándo usar cada campo

- **Skills propios de swl-ses**: declarar solo `herramientasPermitidas`.
- **Skills exportados fuera de swl-ses** (paquetes Anthropic-compatibles):
  declarar también `allowed-tools` explícitamente.

### Ejemplo

```yaml
---
name: mi-skill-analisis
description: >
  Analiza estructura de código. Cargar al revisar código antes de merge.
herramientasPermitidas: [Read, Grep, Glob]
# Solo agregar allowed-tools si se distribuye fuera de swl-ses:
# allowed-tools: [Read, Grep, Glob]
---
```

**Validación cruzada**: si ambos están presentes deben tener el mismo contenido.
El evaluador `evaluar-skill` emite W011 si divergen.

### Aclaración crítica: pre-aprobación vs restricción real

Ambos campos son **pre-aprobación de UX**, NO restricción de seguridad real.
Las restricciones reales provienen de permission rules en `.claude/settings.json`
y matchers en hooks PreToolUse.

---

## Skills as agents pattern (variant técnico avanzado)

Patrón Anthropic nativo: `agent: true` + `model:` en el frontmatter ejecuta
el skill como sub-agente independiente, aislado del contexto del padre.
Aplica cuando el skill consume input grande y devuelve output acotado;
NO aplica para skills passive (reglas, knowledge). Detalles completos
(cuándo usarlo, ejemplo de skill, reglas del frontmatter, candidatos SWL)
en [recursos/skills-as-agents.md](recursos/skills-as-agents.md).

---

## Relación con otros componentes del sistema

| Componente | Relación con skills |
|-----------|-------------------|
| Agentes SWL | Invocan skills con `Skill("nombre")` antes de implementar |
| Comandos `/swl:*` | Pueden invocar skills para guiar su comportamiento |
| Reglas en `reglas/` | Las reglas aplican a código/proceso; los skills a conocimiento de dominio |
| Hooks | Los hooks no invocan skills — trabajan a nivel de herramientas |
| CLAUDE.md | Registra el inventario de skills disponibles |

---

## Contenido extendido (cargar bajo demanda)

Los siguientes bloques viven en `recursos/` y se consultan cuando se necesite
el contenido específico, sin inflar el contexto con cada invocación:

- **Anti-patrones al crear skills + leyes de diseño de alta señal** —
  6 anti-patrones y 6 leyes con ejemplos MAL/BIEN completos. Ver
  [recursos/anti-patrones-y-leyes.md](recursos/anti-patrones-y-leyes.md).
- **Principio de idiomas de framework** — tabla para Django, FastAPI, NestJS,
  Spring Boot, Laravel, Rails, Go, Rust con anti-patrón de código. Ver
  [recursos/idiomas-framework.md](recursos/idiomas-framework.md).
- **Mapeo a frameworks de seguridad (NIST CSF, NIST AI RMF, MITRE ATT&CK/ATLAS/
  D3FEND)** + **migración a nombres de campo en español (REC-S15)**. Ver
  [recursos/frameworks-seguridad.md](recursos/frameworks-seguridad.md).
- **Convención `EXAMPLES.md` como recurso opcional** para skills críticos cuyo
  valor depende de mostrar diff MAL→BIEN lado a lado (decisiones, arquitectura,
  anti-patrones sutiles). NO retroactiva — las 63 carpetas `recursos/` existentes
  no se renombran. Ver [recursos/convencion-examples.md](recursos/convencion-examples.md).
- **Rúbrica skill-judge (Knowledge Delta + Freedom Calibration + 5 patrones)** —
  tres lentes complementarios a las 10 dimensiones de `/swl:evaluar-skill`
  para autoría: detectar contenido redundante, matchear libertad a fragilidad,
  elegir patrón estructural al inicio. NO reemplaza el gate `/swl:evaluar-skill`;
  aplica durante la escritura. Ver [recursos/skill-judge-rubrica.md](recursos/skill-judge-rubrica.md).
  Origen: ADR-0024.

Cada recurso tiene ToC al inicio y es autocontenido — leer solo el relevante
al caso en cuestión en lugar de los tres.

---

## Gotchas / Errores comunes no obvios

- **Confundir Response Discipline con skills de dominio conceptual**: aplicar
  el patrón "command-first" a un skill de patrones de diseño produce respuestas
  truncadas sin contexto. Response Discipline SOLO aplica a skills que
  prescriben comandos, snippets o tokens específicos.
- **Escribir Anti-substitution sin criterio de plausibilidad**: listar
  sustituciones imposibles o obvias diluye la señal. Aplicar los 3 criterios
  (plausible + incorrecta + prob >5%) antes de listar una entrada.
- **Mapear skills no-seguridad a frameworks NIST/MITRE**: genera ruido en
  reportes de cobertura. Reservar el mapeo para el dominio seguridad.
- **Copiar ambos campos (`herramientasPermitidas` y `allowed-tools`) en skills
  internos**: genera duplicación de mantenimiento. Solo el campo español es
  autoritativo en swl-ses; la copia en inglés se hace al exportar.
- **Documentar idioma de framework en skills transversales**: un skill de
  `compactacion-contexto` no debe usar `@Transactional` como ejemplo. El
  principio aplica solo cuando la skill cubre UN framework específico.
- **Cargar este skill cuando la regla core basta**: esto invierte el trade-off
  de context budget. Cargar `meta-skills-estandar` solo cuando se necesita
  contenido extendido, no por defecto.
- **Absorber naming externo al portar un patrón valioso**: cuando un skill
  externo (de cc-sdd, harness-sdd, langchain, kiro, etc.) aporta un patrón
  útil, la tentación es importar también el nombre original (`kiro-review`,
  `kiro-impl`, `langchain-router`). Causa: economía cognitiva en la transición.
  Costo: rompe la identidad del sistema receptor, confunde routing del
  orquestador, viola la regla de idioma español MX y crea acoplamiento
  conceptual con un sistema externo cuya API puede cambiar. Solución
  obligatoria: **portar el patrón, adaptar el nombre al naming del sistema
  receptor**. Para SWL: usar prefijo `swl-` o sufijo `-swl`, en español MX,
  con el dominio del problema (no del sistema origen). Ejemplo real
  (2026-05-15): el patrón `kiro-review` de cc-sdd se absorbió como
  `protocolo-revision-swl` por instrucción explícita del usuario; `kiro-impl`
  iterativo se absorbió como `ejecutar-task-iterativo`. Documentar el origen
  en la sección "Referencias" o "Origen" del skill, NO en el nombre. Verificar
  con `git log --grep="kiro\|otro-prefijo-externo"` que no quedan menciones
  del naming externo en el codebase del sistema receptor.

## Referencias

- Regla core (se carga siempre): `reglas/skills-estandar.md`.
- Evaluador de skills: `comandos/swl/evaluar-skill.md` (usa W009, W010, W011).
- Schema: `schemas/skill-frontmatter.schema.json`.
- Normalizador de campos legacy: `scripts/lib/skill-normalizer.js`.

---

## Contratos controller ↔ worker en skills/agentes

Cuando un skill orquesta un loop iterativo entre un **controller** (comando
o agente padre) y un **worker** (agente o sub-skill invocado N veces), el
contrato entre ambos DEBE explicitar tres dimensiones:

| Dimensión | Pregunta | Riesgo si se omite |
|---|---|---|
| **Indexing** | ¿1-based o 0-based? | Off-by-one entre output paths (`iter-N/`) y argumentos al worker |
| **Identificadores únicos** | ¿Cada sub-invocación tiene un ID propio? | Colisiones de output cuando hay paralelismo o sub-scopes |
| **Convergencia** | ¿Cuándo termina el loop? `PASS` explícito, max-iter, ambos | Loops infinitos o terminación prematura |

### Anti-patrón: convenciones distintas entre capas

```
# Controller (comando): zero-based
iter = 0
while iter < 3:
    invocar(worker, iter=iter)
    iter += 1

# Worker (agente): one-based
"Recibo iter ∈ {1, 2, 3}. Escribo a iter-N/."
```

Resultado: cuando el controller pasa `iter=0`, el worker espera `iter=1` y
escribe a `iter-0/` que la documentación no contempla. El path documentado
`iter-1/` nunca se llena hasta la segunda iteración. Bug silencioso —
detectable solo cuando se intenta leer `iter-N-1/` para correlación entre
iteraciones.

### Pattern correcto: contrato explícito documentado

```python
# Controller (comando) — usar mismo indexing que el worker
iter = 1
MAX_ITER = 3
while iter <= MAX_ITER:
    invocar(worker, iter=iter, sub_id=sub_scope.id if redistribuir else None)
    iter += 1
```

```yaml
# Agente (worker) — declara qué recibe
## Iteración del loop
El agente recibe:
- `iter`: entero ∈ {1, 2, 3} (one-indexed, coherente con paths `iter-N/`)
- `sub_id`: opcional, identificador del sub-scope (string o null)
- En iteraciones >= 2, ruta del output previo (`iter-<N-1>/`)

| Modo | sub_id | Output |
|------|--------|--------|
| Monolítico | null | `iter-N/<archivos>` |
| Redistribuido | "sub-1-X" | `iter-N/<sub_id>/<archivos>` |
```

### Origen

Bug detectado en sesión 2026-05-16 del proyecto swl-ses (PR #28):
`/swl:nemesis --remediar` con `iter=0` en el controller y agente esperando
`iter ∈ {1,2,3}`. Adicional: invocación al worker sin pasar `sub_id` en
modo redistribuido → todos los sub-scopes escribían al mismo path y se
sobreescribían entre sí (fix en PR #29).

Mantener el contrato comando ↔ agente ↔ skill ↔ skill `nemesis-redistribuir`
coherente requiere documentarlo en los **tres** archivos: comando (controller),
agente (worker) y skill operativo (orquestación). Inconsistencia en cualquiera
de los tres = bug.

---

## Pseudocódigo en ADRs y skills: `return` siempre explícitos

Cuando un ADR o skill describe lógica de control con pseudocódigo, las
salidas tempranas DEBEN ser explícitas — no implícitas a través de naming
de funciones helper.

### Anti-patrón: nombre semántico sin `return`

```
# Indexing 1-based para no mezclar dos problemas (helper sin return +
# off-by-one) en el mismo ejemplo. Aquí el bug pedagógico es solo el
# helper ambiguo.
iter = 1
MAX_ITER = 3
while iter <= MAX_ITER:
    eval = invocar(evaluator, iter=iter)
    if eval.status == "PASS": break
    if not flag_remediar: emitir_reporte_y_salir()   # ← ¿sale del while? ¿del scope completo?
    invocar(generator, eval.hallazgos)
    iter += 1
```

Lector estricto puede interpretar `emitir_reporte_y_salir()` como
"emite el reporte y retorna del scope completo" O como "función con
side effect cuyo nombre prometía salida pero no la ejecuta". Ambigüedad
detectada por revisor externo y reportada como bug del ADR.

### Pattern correcto: `return` explícitos con valor

```
# Indexing 1-based coherente con la sección "Contratos controller ↔ worker"
# arriba. Si este skill enseña a evitar off-by-one entre capas, sus propios
# ejemplos deben usar el mismo indexing que el contrato canónico.
iter = 1
MAX_ITER = 3
evaluacion = null
while iter <= MAX_ITER:
    evaluacion = invocar(evaluator, iter=iter)
    if evaluacion.status == "PASS":
        return { exito: True, iters: iter, evaluacion }   # convergencia
    if not flag_remediar:
        emitir_reporte(evaluacion)
        return { exito: False, iters: iter, evaluacion }  # solo audita
    invocar(generator, evaluacion.hallazgos)
    iter += 1
return activar_recovery_catalog(evaluacion)               # max-iter agotado
```

Cada path de salida es:
- Explícito (`return` literal en pseudocódigo)
- Tipado (objeto con campos esperados)
- Comentado con la condición que lo dispara
- Coherente con el indexing del contrato controller ↔ worker (1-based)

### Regla

El pseudocódigo de un ADR o skill es **contrato visual** entre el documento
y el implementador. Funciones helper con nombres semánticos (`emitir_*`,
`escalar_*`, `salir_*`) son aceptables PERO siempre acompañadas de `return`
explícito en el pseudocódigo, no solo en la implementación.

### Origen

Bug del ADR-0021 detectado por revisor externo (sesión 2026-05-16):
*"`emitir_reporte_y_salir()` no muestra explícitamente que sale del loop.
Si la función solo emite output, la ejecución continúa a la siguiente
línea, violando la retrocompatibilidad."* Verificado y corregido en
el mismo ADR.

---

## Patrón evaluator-optimizer aplicado a auditoría

Cuando un skill o agente implementa el patrón `audit → fix → re-audit`,
adoptar el **patrón canónico evaluator-optimizer** del [cookbook oficial
de Anthropic](https://github.com/anthropics/anthropic-cookbook/blob/main/patterns/agents/evaluator_optimizer.ipynb)
en lugar de re-inventar nomenclatura propia.

### Mapeo del patrón

| Componente del cookbook | Equivalente en SWL |
|---|---|
| `generator(prompt, task, context)` | Agente que aplica correcciones (ej: `orquestador-swl` delegando a `depurador-swl`, `backend-python-swl`, etc.) |
| `evaluator(prompt, content, task)` | Agente auditor (ej: `nemesis-auditor-swl`, `revisor-codigo-swl`) que produce veredicto estructurado |
| Veredicto: `PASS / NEEDS_IMPROVEMENT / FAIL` | Status del JSON estructurado del evaluator |
| `loop()` con `while evaluation != "PASS"` | Controller en el comando (no en el agente — ver sección "Contratos controller ↔ worker") |
| Memoria de intentos previos | `.planning/<modulo>/iter-N/` con outputs de cada iteración |

### Reglas obligatorias del patrón

1. **Evaluator y generator NUNCA son el mismo agente**. La separación
   revisor/ejecutor de `reglas/gobernanza.md` se mantiene.
2. **El loop vive en el controller (comando)**, no en el evaluator ni en
   el generator. Esto preserva privilegio mínimo del evaluator (sin Agent
   tool) y delega orquestación a la capa correcta.
3. **Convergencia por `PASS` explícito + max-iter como guardrail**. Anthropic
   recomienda terminación natural; el max-iter (típicamente 3) evita loops
   infinitos sin sustituir el criterio principal.
4. **Output estructurado del evaluator** (JSON con schema versionado). El
   markdown legible es complementario, no source of truth.
5. **Recovery Catalog cuando max-iter agotado sin PASS**: aplicar
   `reprompt → reduce-autonomy → escalate → terminate` según
   `reglas/seguridad-agentes.md`.

### Ejemplo aplicado

ADR-0021 (`/swl:nemesis --remediar`):
- Evaluator: `nemesis-auditor-swl` (atómico, sin Agent tool).
- Generator: `orquestador-swl` invocado con hallazgos como input.
- Loop: en `comandos/swl/nemesis.md` (controller).
- Convergencia: `evaluacion.status == "PASS"`.
- Max-iter: 3 hardcoded en comando.
- Recovery: catálogo formal en escalada secuencial.

### Cuándo NO aplicar este patrón

- Audit one-shot sin remediación automática: aplicar solo el evaluator,
  entregar reporte, fin.
- Cuando el evaluator no puede emitir veredicto estructurado (ejemplo:
  análisis de UX subjetivo): el patrón requiere clasificación binaria
  PASS/no-PASS, no opina.
- Para tareas donde el costo del loop (3-5× tokens) supera el valor de
  la convergencia automática.

### Origen y referencia

Adoptado formalmente en swl-ses v1.5.2 vía ADR-0021. Citar el cookbook
Anthropic directamente en ADRs evita re-inventar terminología y facilita
la integración con otros sistemas que sigan el mismo patrón.
