Personalizacion Avanzada
Personalizacion Avanzada
El problema
Ejecutas /opsx:propose add-user-auth y obtienes un plan con 6 tareas: crear modelo, crear servicio, crear controlador, crear rutas, crear middleware y configurar variables. Todo correcto, pero falta algo critico: no hay tareas de tests, ni validacion de inputs, ni consideraciones de seguridad.
El plan no es malo, es incompleto. OpenSpec genera artefactos basandose en el contexto que le proporcionas. Si no le dices que testing y seguridad son prioritarios, no los incluira.
Este capitulo explica como configurar OpenSpec para que por defecto cada plan incluya tests, seguridad y calidad.
Las 3 palancas de personalizacion
OpenSpec tiene 3 mecanismos que influyen en lo que la IA genera:
| Palanca | Archivo | Que controla |
|---|---|---|
| Context | openspec/config.yaml | Informacion del proyecto que la IA recibe |
| Rules | openspec/config.yaml | Restricciones por tipo de artefacto |
| CLAUDE.md | CLAUDE.md | Instrucciones globales para Claude Code |
Las 3 se complementan. context dice “que es este proyecto”, rules dice “que restricciones tiene cada artefacto” y CLAUDE.md dice “como debe comportarse la IA en general”.
config.yaml: Context
El campo context es lo que openspec instructions envia a la IA cuando genera artefactos. Aqui defines tu stack, convenciones y prioridades de calidad.
Antes (basico)
context: |
Proyecto TypeScript con React y Express.
Despues (con calidad integrada)
context: |
## Stack
- Runtime: Node.js 20, TypeScript 5.4 (strict mode)
- Frontend: React 19, Vite 6, Tailwind CSS 4
- Backend: Express 5, Prisma 6, PostgreSQL 16
- Testing: Vitest (unit/integration), Playwright (e2e)
- Linting: Biome (format + lint)
- CI: Husky + lint-staged pre-commit
## Prioridades (en orden)
1. Seguridad: validar inputs con zod, sanitizar datos, no exponer secretos
2. Testing: todo codigo nuevo requiere tests unitarios minimo
3. Performance: lazy loading, memoizacion, queries optimizadas
4. Mantenibilidad: funciones < 30 lineas, archivos < 150 lineas
## Convenciones de testing
- Tests unitarios junto al archivo fuente: `archivo.test.ts`
- Mocks en `__mocks__/` del mismo directorio
- Cobertura minima: 80% en lineas y branches
- Naming: describe("NombreModulo") > it("should comportamiento")
## Seguridad obligatoria
- Todo input del usuario se valida con zod antes de procesarse
- Passwords hasheados con bcrypt (cost 12)
- JWT con expiracion maxima de 1 hora
- Rate limiting en endpoints publicos
- Headers de seguridad con helmet
- No logs de datos sensibles (passwords, tokens, PII)
La diferencia es que ahora la IA sabe que testing y seguridad son prioritarios. Cuando genere el design.md, considerara zod para validaciones. Cuando genere tasks.md, incluira tareas de tests.
config.yaml: Rules
Las rules son restricciones por tipo de artefacto. Son mas directivas que el context: le dicen a la IA que debe y que no debe hacer en cada artefacto especifico.
Rules para que tasks incluya tests
rules:
tasks:
- Incluir al menos una tarea de tests unitarios por cada modulo nuevo
- Incluir tarea de test de integracion si el cambio toca API o BD
- Las tareas de test van DESPUES de la implementacion del modulo
- 'Formato: "Crear tests unitarios para [modulo] en [path].test.ts"'
- Si el cambio modifica codigo existente, incluir tarea de actualizar tests
Rules para que design sea secure by default
rules:
design:
- "Validacion de inputs: especificar schema zod para cada endpoint/funcion publica"
- "Autenticacion/autorizacion: especificar quien puede ejecutar cada accion"
- "Datos sensibles: especificar como se almacenan, transmiten y loggean"
- Si el cambio expone un endpoint, incluir seccion "Seguridad" en el design
Rules para specs con escenarios de seguridad
rules:
specs:
- Formato Given/When/Then obligatorio
- Incluir escenario de input valido (happy path)
- Incluir escenario de input invalido (tipos incorrectos, campos faltantes)
- Incluir escenario de input malicioso (inyeccion SQL, XSS, path traversal)
- Incluir escenario de limites (strings vacios, valores extremos, payloads grandes)
Rules para proposals acotados
rules:
proposal:
- Mantener bajo 500 palabras
- "Secciones obligatorias: Motivacion, Alcance, Fuera de alcance, Riesgos"
- En Riesgos, siempre considerar implicaciones de seguridad
config.yaml completo de ejemplo
schema: spec-driven
context: |
## Stack
- Runtime: Node.js 20, TypeScript 5.4 (strict mode)
- Frontend: React 19, Vite 6, Tailwind CSS 4
- Backend: Express 5, Prisma 6, PostgreSQL 16
- Testing: Vitest (unit/integration), Playwright (e2e)
- Linting: Biome (format + lint)
- CI: Husky + lint-staged pre-commit
- Idioma: Espanol (artefactos en espanol)
## Prioridades
1. Seguridad: validar inputs, sanitizar datos
2. Testing: tests unitarios obligatorios para codigo nuevo
3. Mantenibilidad: archivos < 150 lineas, funciones enfocadas
## Patrones de testing
- Archivos test junto al fuente: modulo.test.ts
- Vitest con coverage > 80%
- Mocks con vi.mock() para dependencias externas
## Seguridad baseline
- Validacion con zod en boundaries
- bcrypt para passwords
- Rate limiting en endpoints publicos
rules:
proposal:
- Maximo 500 palabras
- Incluir seccion de Riesgos con consideraciones de seguridad
specs:
- Formato Given/When/Then obligatorio
- Incluir escenarios de input invalido y malicioso para features con input del usuario
design:
- Incluir seccion "Seguridad" si el cambio expone endpoints o maneja datos del usuario
- Especificar schemas de validacion (zod) para cada boundary
tasks: |
OBLIGATORIO:
- Incluir tarea de tests unitarios por cada modulo nuevo
- Incluir tarea de tests de integracion si toca API o BD
- Incluir tarea de validacion de inputs si hay datos del usuario
Las tareas de test van despues de implementar el modulo correspondiente.
El efecto en la generacion
Con esta configuracion, al ejecutar /opsx:propose add-user-auth, las tareas generadas se veran asi:
# Tasks: Add User Auth
- [ ] Crear schema de validacion con zod para registro y login
- [ ] Crear modelo User en Prisma con password hasheado
- [ ] Crear tests unitarios para el modelo User
- [ ] Crear AuthService con registro, login y verificacion JWT
- [ ] Crear tests unitarios para AuthService
- [ ] Crear middleware de autenticacion con verificacion JWT
- [ ] Crear tests unitarios para auth middleware
- [ ] Crear rutas POST /auth/register y POST /auth/login
- [ ] Crear tests de integracion para endpoints de auth
- [ ] Configurar rate limiting en rutas de auth
- [ ] Agregar headers de seguridad con helmet
Comparalo con el plan sin reglas: 6 tareas sin tests ni seguridad. Ahora tiene 11 tareas con tests intercalados y seguridad integrada.
CLAUDE.md como refuerzo
CLAUDE.md complementa a config.yaml. Mientras config.yaml influye solo en artefactos de OpenSpec, CLAUDE.md influye en todo lo que hace Claude Code, incluyendo cuando implementa con /opsx:apply.
# Prioridades
1. Seguridad: Validar inputs, sanitizar datos, no exponer secretos
2. Testing: Todo codigo nuevo requiere tests unitarios
3. Mantenibilidad: Funciones < 30 lineas, archivos < 150 lineas
# Testing
- Crear test file junto al modulo: modulo.test.ts
- Usar describe/it con nombres descriptivos
- Mockear dependencias externas, no la implementacion interna
- Coverage minimo: 80% lineas y branches
# Seguridad
- Validar todo input del usuario con zod
- No loggear datos sensibles
- Passwords con bcrypt, JWT con expiracion
Con esto, cuando /opsx:apply ejecuta las tareas, la IA sigue estas instrucciones al escribir el codigo real. El config.yaml asegura que las tareas existan; el CLAUDE.md asegura que la implementacion cumpla los estandares.
Schemas personalizados
Si el schema spec-driven (proposal → specs → design → tasks) no encaja con tu flujo, puedes crear uno propio.
Fork de un schema existente
openspec schema fork spec-driven secure-driven
Esto crea una copia del schema en openspec/schemas/secure-driven/ que puedes modificar:
- Cambiar el orden de artefactos
- Agregar artefactos nuevos (ej:
security-review.md) - Modificar templates por defecto
- Cambiar que artefactos son requeridos antes de apply
Usar el schema nuevo
# openspec/config.yaml
schema: secure-driven
Crear schema desde cero
openspec schema init minimal --artifacts "tasks" --default
Esto crea un schema que solo genera tasks.md, sin proposal, specs ni design. Util para cambios pequenos donde la planificacion completa es innecesaria.
Orden de resolucion de schemas
Cuando ejecutas un comando de OpenSpec, el sistema determina que schema usar siguiendo una cadena de prioridad de 4 niveles:
| Prioridad | Fuente | Ejemplo |
|---|---|---|
| 1 (maxima) | Flag en CLI | openspec new --schema minimal mi-cambio |
| 2 | Metadata del change | Campo schema: en el change activo |
| 3 | config.yaml | schema: spec-driven en la configuracion |
| 4 (minima) | Default del sistema | spec-driven (schema por defecto) |
El nivel 1 siempre gana. Si no se especifica flag, se busca en el change actual. Si el change no tiene schema, se usa config.yaml. Si config.yaml tampoco lo define, se usa spec-driven.
Para diagnosticar que schema esta usando OpenSpec en un momento dado:
openspec schema which
Esto muestra el schema activo y de donde viene (CLI, change, config o default). Util cuando un cambio genera artefactos inesperados y sospechas que esta usando el schema incorrecto.
Validacion y depuracion de schemas
Despues de crear o modificar un schema custom, validalo antes de usarlo:
openspec schema validate mi-workflow
Este comando detecta:
- Errores de sintaxis: YAML malformado, campos faltantes o con tipos incorrectos
- Templates inexistentes: Referencias a archivos de template que no existen en el directorio del schema
- Dependencias circulares: Artefacto A requiere B, B requiere C, C requiere A
- Campos desconocidos: Typos en nombres de campo que serian ignorados silenciosamente
Para ver todos los schemas disponibles y su estado:
openspec schema which --all
Esto lista los schemas built-in y los custom, indicando cual esta activo actualmente.
Cuando validar: siempre que crees un schema nuevo con
init, hagas fork confork, o modifiques manualmente los archivos de un schema existente.
Templates: guiando la generacion
Los templates son archivos markdown dentro del schema que definen la estructura que la IA debe seguir al generar cada artefacto. Son el mecanismo mas potente de personalizacion porque controlan directamente el formato del output.
Estructura de un template
Cada template usa section headers para definir las secciones del artefacto y HTML comments como instrucciones para la IA:
# {change_title}
## Motivacion
<!-- Explicar el problema que resuelve este cambio en 2-3 parrafos -->
## Alcance
<!-- Lista de componentes afectados -->
## Fuera de alcance
<!-- Que NO se va a hacer en este cambio -->
La IA recibe este template y lo usa como guia para generar el contenido, respetando las secciones y siguiendo las instrucciones en los comments.
Campos del schema que controlan templates
| Campo | Que hace |
|---|---|
id | Identificador unico del artefacto (ej: tasks, design) |
generates | Archivo de salida (ej: tasks.md, design.md) |
template | Ruta al archivo de template dentro del schema |
instruction | Instruccion adicional que la IA recibe al generar este artefacto |
requires | Lista de artefactos que deben existir antes de generar este |
Ejemplo: template custom para tasks con tests obligatorios
# Tasks: {change_title}
## Implementacion
<!-- Tareas de implementacion del cambio -->
## Testing
<!-- OBLIGATORIO: al menos una tarea de test por cada modulo nuevo -->
<!-- Formato: "Crear tests [tipo] para [modulo] en [path].test.ts" -->
## Validacion
<!-- Tareas de verificacion final: lint, build, integracion -->
Con este template, la IA siempre genera secciones separadas para implementacion, testing y validacion. No puede omitir la seccion de testing porque el template la define explicitamente.
Templates vs Rules
| Aspecto | Templates | Rules |
|---|---|---|
| Que son | Archivos de estructura | Texto de restricciones |
| Como actuan | Definen el formato del output | Definen que incluir/excluir en el contenido |
| Donde viven | Directorio del schema | config.yaml campo rules |
| Ejemplo | ”El artefacto tiene secciones: Motivacion, Alcance, Riesgos" | "Incluir consideraciones de seguridad en Riesgos” |
Usa templates cuando quieras controlar la estructura. Usa rules cuando quieras controlar el contenido dentro de esa estructura. Combinados, dan control total sobre lo que genera OpenSpec.
Resumen
- config.yaml context: Define stack, prioridades y convenciones (la IA lo recibe al generar artefactos)
- config.yaml rules: Restricciones especificas por artefacto (fuerzan tests, seguridad, formato)
- CLAUDE.md: Refuerza las reglas durante la implementacion con
/opsx:apply - Schemas: Permiten personalizar el flujo completo de artefactos
- Orden de resolucion: CLI flag → change metadata → config.yaml → default (diagnosticar con
schema which) - Validacion:
schema validatedetecta errores antes de usar un schema custom - Templates: Archivos markdown que controlan la estructura del output (complementan a rules que controlan el contenido)
- Las 3 palancas juntas hacen que OpenSpec genere planes secure by default con tests incluidos
← Capitulo 11: Roadmap | Capitulo 13: Integracion con Herramientas de Calidad →