sdd-es 2.0.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/.claude/settings.json +21 -45
  2. package/LICENSE +21 -0
  3. package/README.md +51 -21
  4. package/agents/architecture-designer.md +174 -0
  5. package/agents/arquitecto.md +16 -1
  6. package/agents/asesor-datos.md +15 -1
  7. package/agents/critico.md +37 -1
  8. package/agents/desarrollador-backend.md +3 -1
  9. package/agents/desarrollador-frontend.md +3 -1
  10. package/agents/disenador-api.md +13 -1
  11. package/agents/documentador.md +3 -1
  12. package/agents/investigador.md +3 -1
  13. package/agents/operaciones.md +3 -1
  14. package/agents/product-designer.md +232 -0
  15. package/agents/revisor.md +25 -1
  16. package/agents/seguridad.md +5 -1
  17. package/agents/tester.md +3 -1
  18. package/claude-hooks/agent-memory.js +154 -0
  19. package/cli/index.js +1 -2
  20. package/commands/sdd.analizar.md +23 -2
  21. package/commands/sdd.compliance.md +516 -0
  22. package/commands/sdd.configurar.md +33 -0
  23. package/commands/sdd.constitucion.md +198 -23
  24. package/commands/sdd.construir.md +210 -0
  25. package/commands/sdd.dise/303/261ar.md +188 -0
  26. package/commands/sdd.estado.md +68 -1
  27. package/commands/sdd.exportar.md +344 -0
  28. package/commands/sdd.implementar.md +203 -23
  29. package/commands/sdd.interpretar.md +239 -0
  30. package/commands/sdd.md +70 -1
  31. package/commands/sdd.optimizar.md +164 -0
  32. package/commands/sdd.planificar.md +64 -0
  33. package/commands/sdd.verificar.md +10 -0
  34. package/craft/accessibility-baseline.md +216 -0
  35. package/craft/anti-ai-slop.md +158 -0
  36. package/craft/color.md +160 -0
  37. package/craft/typography.md +121 -0
  38. package/design-systems/bold-brutalist/DESIGN.md +239 -0
  39. package/design-systems/editorial-minimal/DESIGN.md +205 -0
  40. package/design-systems/neutral-modern/DESIGN.md +227 -0
  41. package/design-systems/vibrant-consumer/DESIGN.md +257 -0
  42. package/design-systems/warm-editorial/DESIGN.md +221 -0
  43. package/docs/AGENTES.md +4 -1
  44. package/docs/FABRICA.md +164 -115
  45. package/docs/MEMORIA-Y-OBSERVABILIDAD.md +237 -0
  46. package/docs/MODELOS.md +3 -0
  47. package/docs/QUE-PASA-SI-FALLA.md +404 -0
  48. package/docs/SEGURIDAD-PARA-NOTECNICOS.md +280 -0
  49. package/package.json +5 -3
  50. package/skills/cache-audit/SKILL.md +163 -0
  51. package/skills/critica-diseno/SKILL.md +193 -0
  52. package/skills/descubrir-idea/SKILL.md +133 -0
  53. package/skills/effort-router/SKILL.md +128 -0
  54. package/skills/elegir-direccion/SKILL.md +184 -0
  55. package/skills/github-connect/IMPLEMENTATION-CHECKLIST.md +297 -0
  56. package/skills/github-connect/INDEX.md +223 -0
  57. package/skills/github-connect/INTEGRATION.md +361 -0
  58. package/skills/github-connect/QUICK-START.md +168 -0
  59. package/skills/github-connect/README.md +414 -0
  60. package/skills/github-connect/RESUMEN_IMPLEMENTACION.txt +374 -0
  61. package/skills/github-connect/SKILL.md +343 -0
  62. package/skills/github-connect/STRUCTURE.txt +252 -0
  63. package/skills/github-connect/example-config.yaml +41 -0
  64. package/skills/github-connect/github-connect.sh +419 -0
  65. package/skills/interpretar-idea/SKILL.md +254 -0
  66. package/skills/memory-compactor/SKILL.md +114 -0
  67. package/skills/modo-guiado/SKILL.md +12 -2
  68. package/skills/observabilidad-consumo/SKILL.md +164 -0
  69. package/skills/token-budget/SKILL.md +154 -0
  70. package/skills/vercel-deploy/00-START-HERE.txt +364 -0
  71. package/skills/vercel-deploy/CHECKLIST.md +205 -0
  72. package/skills/vercel-deploy/EXEC-SUMMARY.txt +322 -0
  73. package/skills/vercel-deploy/FLOW.txt +334 -0
  74. package/skills/vercel-deploy/INDEX.md +276 -0
  75. package/skills/vercel-deploy/INTEGRATION.md +328 -0
  76. package/skills/vercel-deploy/MANIFEST.md +310 -0
  77. package/skills/vercel-deploy/README.md +65 -0
  78. package/skills/vercel-deploy/SKILL.md +356 -0
  79. package/skills/vercel-deploy/deploy.sh +298 -0
  80. package/skills/vercel-deploy/estado.json.example +205 -0
  81. package/skills/vercel-deploy/skill.yaml +323 -0
  82. package/skills/vercel-deploy/vercel-deploy.sh +216 -0
  83. package/skills/wireframe-mvp/SKILL.md +157 -0
  84. package/.claude-plugin/marketplace.json +0 -31
  85. package/.claude-plugin/plugin.json +0 -97
  86. package/docs/EJEMPLO-PRACTICA.md +0 -383
  87. package/docs/EJEMPLOS.md +0 -212
  88. /package/skills/{compresion-tokens.md → compresion-tokens/SKILL.md} +0 -0
  89. /package/skills/{constitucion-constraint.md → constitucion-constraint/SKILL.md} +0 -0
  90. /package/skills/{deteccion-stack.md → deteccion-stack/SKILL.md} +0 -0
  91. /package/skills/{enrutador-agentes.md → enrutador-agentes/SKILL.md} +0 -0
  92. /package/skills/{gestion-estado.md → gestion-estado/SKILL.md} +0 -0
  93. /package/skills/{indexador.md → indexador/SKILL.md} +0 -0
  94. /package/skills/{validacion-spec.md → validacion-spec/SKILL.md} +0 -0
  95. /package/skills/{verificador-implementacion.md → verificador-implementacion/SKILL.md} +0 -0
@@ -0,0 +1,254 @@
1
+ ---
2
+ description: Convierte una idea en texto libre a un IR (Interpreted Requirement) JSON validado. Trabaja en 2 fases - razonamiento libre + extracción JSON. Lee .sdd/descubrimiento.md si existe.
3
+ model: claude-opus-4-8
4
+ allowed-tools: Read, Write
5
+ ---
6
+
7
+ # Skill: Interpretar Idea → IR
8
+
9
+ ## Propósito
10
+
11
+ Tomar la idea del usuario (más el contexto de discovery si existe) y convertirla en un **IR JSON válido** que alimente el pipeline FORGE. Sin que el usuario tenga que pensar en estructura, campos, o intención.
12
+
13
+ ---
14
+
15
+ ## Contexto que debes leer primero
16
+
17
+ Antes de empezar, lee:
18
+
19
+ ```bash
20
+ cat .sdd/descubrimiento.md 2>/dev/null || echo "SIN_DISCOVERY"
21
+ ```
22
+
23
+ Si existe `descubrimiento.md`, úsalo como contexto adicional para enriquecer el IR.
24
+
25
+ ---
26
+
27
+ ## Flujo en 2 fases
28
+
29
+ ### FASE A — Razonamiento libre (sin JSON)
30
+
31
+ Analiza la idea en prosa libre. **No generes JSON todavía.** Solo piensa:
32
+
33
+ ```
34
+ Analizando: "[idea del usuario]"
35
+ Contexto de discovery: [resumen de descubrimiento.md si existe]
36
+
37
+ ANÁLISIS:
38
+ - Tipo de producto: [web app / mobile / api / cli / saas / other]
39
+ - Usuarios principales: [quién lo usa]
40
+ - Problema que resuelve: [qué dolor alivia]
41
+ - Features core (los más críticos para V1): [lista priorizada]
42
+ - Features secundarios (futuro): [lista]
43
+ - Restricciones evidentes: [técnicas, de negocio, de tiempo]
44
+ - Ambigüedades detectadas: [qué no está claro]
45
+ - Asunciones que haré: [cómo resuelvo las ambigüedades]
46
+ - Confianza estimada: [0.0–1.0] por qué
47
+ ```
48
+
49
+ Sé honesto con la confianza. Una idea vaga tiene confidence 0.5–0.65. Una idea clara tiene 0.8–0.9. Nunca 1.0.
50
+
51
+ ### FASE B — Extracción a IR JSON
52
+
53
+ Solo después del análisis, extrae el IR JSON:
54
+
55
+ ```json
56
+ {
57
+ "id": "ir-[slug-del-producto]-001",
58
+ "created_at": "[ISO timestamp]",
59
+ "raw_input": "[idea literal del usuario]",
60
+ "confidence": [0.0–1.0],
61
+
62
+ "product": {
63
+ "name": "[Nombre descriptivo del producto]",
64
+ "type": "[saas|mobile|web|api|cli|other]",
65
+ "tagline": "[Una línea que describe el valor en <10 palabras]",
66
+ "value_proposition": "[Por qué existe este producto, en 1 oración]",
67
+ "target_users": "[Quién lo usa, en lenguaje natural]"
68
+ },
69
+
70
+ "features": {
71
+ "core": [
72
+ "[Feature 1 — lo más esencial del MVP]",
73
+ "[Feature 2]",
74
+ "[Feature 3]",
75
+ "[Feature 4 si aplica]",
76
+ "[Feature 5 si aplica — máximo 5]"
77
+ ],
78
+ "nice_to_have": [
79
+ "[Feature futuro 1]",
80
+ "[Feature futuro 2]"
81
+ ]
82
+ },
83
+
84
+ "constraints": {
85
+ "budget": "[bajo|medio|alto|ilimitado|null]",
86
+ "timeline": "[ASAP|semanas|meses|flexible|null]",
87
+ "team_size": "[1 persona|equipo pequeño|equipo grande|null]",
88
+ "tech_preference": "[React|Python|Node|null — null si no mencionó]"
89
+ },
90
+
91
+ "assumptions": [
92
+ "[Asunción 1 — lo que decidiste sin que el usuario lo dijera]",
93
+ "[Asunción 2]"
94
+ ],
95
+
96
+ "ambiguities": [
97
+ {
98
+ "field": "[campo afectado]",
99
+ "issue": "[qué no estaba claro]",
100
+ "resolution": "[cómo lo resolviste]"
101
+ }
102
+ ],
103
+
104
+ "requires_clarification": [true|false],
105
+ "questions_for_user": [
106
+ "[Pregunta 1 si confidence < 0.7 — máximo 1 pregunta]"
107
+ ]
108
+ }
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Reglas de validación del IR
114
+
115
+ El IR es válido si:
116
+
117
+ - ✅ `product.type` es uno de: `saas`, `mobile`, `web`, `api`, `cli`, `other`
118
+ - ✅ `features.core` tiene **2–5 items** (no 0, no 6+)
119
+ - ✅ `confidence` está entre `0.0` y `1.0`
120
+ - ✅ `assumptions[]` es un array (puede estar vacío)
121
+ - ✅ `ambiguities[]` es un array (puede estar vacío)
122
+ - ✅ Si `confidence < 0.7` → `requires_clarification: true` y `questions_for_user` tiene **máximo 1 pregunta**
123
+
124
+ Si el IR no cumple alguna regla, corrígelo antes de guardarlo.
125
+
126
+ ---
127
+
128
+ ## Cuándo preguntar vs. asumir
129
+
130
+ **Asumir siempre** cuando:
131
+ - El usuario no mencionó tecnología → asumir `tech_preference: null`
132
+ - El usuario no mencionó presupuesto → asumir `budget: null`
133
+ - Es obvio por el contexto (ej: "app de citas para peluquería" → `type: web`)
134
+
135
+ **Preguntar solo cuando**:
136
+ - `confidence < 0.7` (la idea es genuinamente ambigua)
137
+ - Y solo **1 pregunta**, la más crítica para desambiguar
138
+
139
+ **Ejemplos de preguntas válidas**:
140
+ - "¿Es para tú negocio personal o para múltiples negocios?"
141
+ - "¿Los usuarios pagan por el servicio o es gratuito?"
142
+
143
+ **Ejemplos de preguntas inválidas** (nunca hacer):
144
+ - "¿Qué tecnología prefieres?" (técnico, no relevante para el IR)
145
+ - "¿Cuántas funcionalidades quieres?" (abierto, sin respuesta útil)
146
+ - "¿Tienes algún prototipo?" (fuera de scope)
147
+
148
+ ---
149
+
150
+ ## Output final
151
+
152
+ ### Si `confidence ≥ 0.7`:
153
+
154
+ 1. Muestra el IR en formato legible:
155
+
156
+ ```
157
+ ═══════════════════════════════════════════
158
+ 🎯 TU IDEA INTERPRETADA
159
+ ═══════════════════════════════════════════
160
+
161
+ Producto: [product.name]
162
+ Tipo: [product.type en español: "aplicación web" / "app móvil" / etc.]
163
+ Para: [target_users]
164
+
165
+ Qué hace: [value_proposition]
166
+
167
+ Features del MVP:
168
+ ✦ [core[0]]
169
+ ✦ [core[1]]
170
+ ✦ [core[2]]
171
+ [... hasta 5]
172
+
173
+ Para más adelante:
174
+ · [nice_to_have[0] si existe]
175
+
176
+ Confianza: [██████████░░] [confidence*100]%
177
+
178
+ Asunciones que hice:
179
+ → [assumption[0]]
180
+ → [assumption[1] si existe]
181
+
182
+ [Si hay ambiguities:]
183
+ Preguntas resueltas:
184
+ ✓ [ambiguity[0].issue] → [ambiguity[0].resolution]
185
+
186
+ ═══════════════════════════════════════════
187
+ ¿Es esto lo que querías?
188
+ Escribe "sí" para continuar al diseño
189
+ Escribe "no, cambia [qué]" para corregir
190
+ ═══════════════════════════════════════════
191
+ ```
192
+
193
+ 2. Guarda en `.sdd/ir.json` (solo tras confirmación del usuario)
194
+ 3. Guarda el análisis de Fase A en `.sdd/ir-analysis.md`
195
+
196
+ ### Si `confidence < 0.7`:
197
+
198
+ 1. Muestra la pregunta de clarificación antes de continuar:
199
+
200
+ ```
201
+ Antes de continuar, necesito una aclaración:
202
+
203
+ [questions_for_user[0]]
204
+ ```
205
+
206
+ 2. Espera la respuesta
207
+ 3. Incorpora la respuesta al análisis
208
+ 4. Re-genera el IR con la nueva información
209
+ 5. Ahora confidence debería ser ≥ 0.7 → muestra el IR y pide confirmación
210
+
211
+ ---
212
+
213
+ ## Guardar archivos
214
+
215
+ ### `.sdd/ir.json`
216
+ El IR JSON completo. Se guarda solo después de que el usuario confirme.
217
+
218
+ ### `.sdd/ir-analysis.md`
219
+ El análisis de Fase A. Se guarda siempre (útil para auditoría).
220
+
221
+ ```markdown
222
+ # IR Analysis — [product.name]
223
+
224
+ **Fecha**: [timestamp]
225
+ **Idea original**: [raw_input]
226
+
227
+ ## Análisis libre (Fase A)
228
+
229
+ [Texto completo del análisis en prosa]
230
+
231
+ ## IR generado (Fase B)
232
+
233
+ ```json
234
+ [IR JSON completo]
235
+ ```
236
+
237
+ ## Validación
238
+
239
+ - confidence: [valor]
240
+ - requires_clarification: [true/false]
241
+ - errores de validación: [lista o "ninguno"]
242
+ ```
243
+
244
+ ---
245
+
246
+ ## Casos de prueba esperados
247
+
248
+ | Idea | Confidence esperado | requires_clarification |
249
+ |------|---------------------|----------------------|
250
+ | "App para dentistas que gestionen citas" | 0.82–0.88 | false |
251
+ | "Quiero algo para mis pedidos" | 0.55–0.65 | true |
252
+ | "Plataforma de e-commerce con pagos, inventario y envíos" | 0.80–0.88 | false |
253
+ | "No sé bien, algo para organizar cosas" | 0.40–0.55 | true |
254
+ | "API REST para un sistema de autenticación con JWT y refresh tokens" | 0.88–0.95 | false |
@@ -0,0 +1,114 @@
1
+ ---
2
+ description: Comprime los archivos .sdd/memoria/agente-*.md cuando superan 80 entradas o 50KB. Elimina duplicados (misma ruta, fecha distinta — conserva la más reciente) y aplica el diccionario caveman de compresion-tokens (Nivel Full). Produce backup .original antes de comprimir.
3
+ model: claude-haiku-4-5-20251001
4
+ allowed-tools: Read, Write, Bash
5
+ ---
6
+
7
+ # Skill: Memory Compactor
8
+
9
+ ## Propósito
10
+
11
+ Los archivos de memoria de agentes crecen indefinidamente a lo largo de proyectos largos. Una memoria de 200 entradas consume ~30KB de ventana de contexto en cada invocación del agente — contexto que podría usarse para la tarea real. Esta skill comprime esos archivos sin perder las decisiones clave.
12
+
13
+ **Cuándo ejecutar:**
14
+ - Cuando el hook `agent-memory.js` emite: `⚠️ Memoria de {agente} supera 50KB`
15
+ - Cuando `/sdd.optimizar memoria` detecta archivos por encima del umbral
16
+ - Manualmente si el agente empieza a ignorar instrucciones (señal de contexto saturado)
17
+
18
+ ---
19
+
20
+ ## PASO 1 — Detectar archivos que superan el umbral
21
+
22
+ ```bash
23
+ # Listar archivos de memoria con su tamaño
24
+ ls -la .sdd/memoria/agente-*.md 2>/dev/null || echo "SIN_ARCHIVOS_MEMORIA"
25
+
26
+ # Contar entradas por archivo (cada entrada empieza con "## ")
27
+ for f in .sdd/memoria/agente-*.md; do
28
+ [ -f "$f" ] || continue
29
+ entradas=$(grep -c "^## " "$f" 2>/dev/null || echo 0)
30
+ bytes=$(wc -c < "$f" 2>/dev/null || echo 0)
31
+ echo "$f: $entradas entradas, $bytes bytes"
32
+ done
33
+ ```
34
+
35
+ **Umbral de intervención:** >80 entradas O >50KB. Si ningún archivo supera el umbral, reportar "✅ Memorias dentro del umbral — no se requiere compresión" y terminar.
36
+
37
+ ---
38
+
39
+ ## PASO 2 — Para cada archivo que supera el umbral
40
+
41
+ ### 2a. Crear backup
42
+
43
+ ```bash
44
+ cp .sdd/memoria/agente-{nombre}.md .sdd/memoria/agente-{nombre}.md.original
45
+ ```
46
+
47
+ ### 2b. Leer el archivo completo
48
+
49
+ Parsear línea a línea. Cada entrada tiene este formato:
50
+ ```markdown
51
+ ## 2026-06-13 — ruta/del/archivo.md
52
+ > resumen de la acción tomada
53
+ ```
54
+
55
+ ### 2c. Eliminar duplicados
56
+
57
+ Agrupar entradas por `archivo` (la parte después del `—` en el encabezado `##`). De cada grupo, conservar **solo la entrada más reciente** (la de fecha más alta). Las fechas están en formato ISO 8601 `YYYY-MM-DD` — ordenar lexicográficamente es suficiente.
58
+
59
+ **Ejemplo:**
60
+ ```
61
+ ## 2026-06-01 — .sdd/especificaciones/auth/spec.md ← ELIMINAR (más antigua)
62
+ ## 2026-06-10 — .sdd/especificaciones/auth/spec.md ← CONSERVAR (más reciente)
63
+ ```
64
+
65
+ ### 2d. Aplicar compresión Nivel Full al cuerpo de cada entrada
66
+
67
+ El diccionario completo vive en `{PLUGIN_DIR}/skills/compresion-tokens/SKILL.md`. No duplicar los pares aquí — leer la sección "Diccionario Nivel Full" de esa skill y aplicar los mismos 80+ reemplazos sobre el texto de cada línea `>`.
68
+
69
+ **Patrones que NUNCA comprimir** (igual que en `compresion-tokens`):
70
+ - Rutas de archivo (la parte después del `—` en `##`)
71
+ - Código entre backticks
72
+ - Nombres de variables, funciones, clases
73
+ - URLs y comandos
74
+
75
+ ### 2e. Reescribir el archivo comprimido
76
+
77
+ ```markdown
78
+ # Memoria del agente: {nombre}
79
+
80
+ [Comprimido por memory-compactor el {fecha}. Backup en .original]
81
+ Léelo al inicio de cada sesión para mantener continuidad entre conversaciones.
82
+
83
+ ---
84
+
85
+ {entradas deduplicadas y comprimidas, ordenadas por fecha descendente}
86
+ ```
87
+
88
+ ---
89
+
90
+ ## PASO 3 — Reporte
91
+
92
+ ```
93
+ ╔══════════════════════════════════════════════════════════════╗
94
+ ║ 🧠 MEMORY COMPACTOR — Resultado ║
95
+ ╠══════════════════════════════════════════════════════════════╣
96
+ ║ AGENTE | ANTES | DESPUÉS | REDUCCIÓN ║
97
+ ║ ─────────────────┼──────────────┼──────────────┼─────────── ║
98
+ ║ {nombre} | {N} entr. | {M} entr. | {%}% ║
99
+ ║ | {KB_antes}KB | {KB_desp}KB | ║
100
+ ╠══════════════════════════════════════════════════════════════╣
101
+ ║ Backups guardados en: .sdd/memoria/*.md.original ║
102
+ ║ Para restaurar: cp agente-{nombre}.md.original agente-... ║
103
+ ╚══════════════════════════════════════════════════════════════╝
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Notas
109
+
110
+ - Esta skill reutiliza el diccionario de `compresion-tokens` — no lo reinventa.
111
+ - La deduplicación es la técnica más efectiva: en proyectos largos, el 40-60% de las entradas son re-escrituras del mismo archivo.
112
+ - Nunca borrar el `.original` automáticamente — el usuario decide cuándo hacerlo.
113
+ - Si un archivo tiene <20 entradas y <20KB, saltar silenciosamente aunque se haya invocado la skill.
114
+ - Esta skill se invoca desde `/sdd.optimizar memoria` y desde `/sdd.comprimir memoria`.
@@ -20,7 +20,7 @@ grep -q '"perfil": *"guiado"' .sdd/estado.json 2>/dev/null && echo GUIADO
20
20
  grep -q '^perfil: *guiado' .sdd/sdd.config.yaml 2>/dev/null && echo GUIADO
21
21
  ```
22
22
 
23
- ## Reglas de comunicación (las 6 reglas)
23
+ ## Reglas de comunicación (las 8 reglas)
24
24
 
25
25
  1. **Sin jerga.** Nunca digas "endpoint", "schema", "ORM", "deploy", "lint", "CI". Di "dirección donde vive el dato", "estructura de la información", "guardar en disco", "publicar en internet", "revisión automática de calidad". Si un término técnico es inevitable, defínelo en la misma frase con una analogía.
26
26
 
@@ -34,6 +34,15 @@ grep -q '^perfil: *guiado' .sdd/sdd.config.yaml 2>/dev/null && echo GUIADO
34
34
 
35
35
  6. **Explica el resultado en términos de lo que el usuario puede hacer ahora.** Al terminar un paso: *"Ya puedes crear tareas y marcarlas como hechas. ¿Quieres que lo publiquemos en internet para usarlo desde el móvil?"* — no *"implementé el CRUD con 14 tests, cobertura 87%"*.
36
36
 
37
+ 7. **Pausar y explicar cuando hay confusión.** Si el usuario dice "no entiendo", "explícame", o "no sé qué significa eso", **pausa inmediatamente** y explica con una analogía del mundo real ANTES de continuar. No hagas jerga. Ejemplo:
38
+ - Usuario: "¿Qué es una base de datos?"
39
+ - Tú (❌ MAL): "Es un SGBD relacional que persiste datos en forma normalizada."
40
+ - Tú (✅ BIEN): "Piensa en una base de datos como una hoja de cálculo (como Excel). Guarda toda la información de tu proyecto — usuarios, productos, mensajes, etc. El sistema la usa para encontrar información rápidamente cuando la necesita."
41
+
42
+ 8. **Cierre explícito de cada fase.** Al final de cada FASE (especificar, planificar, implementar, verificar), explica exactamente qué puede hacer el usuario AHORA con lo que se construyó. Ejemplo:
43
+ - ❌ "Implementé el módulo de autenticación con JWT y bcrypt."
44
+ - ✅ "✅ Tu código está listo. Ahora puedes: (1) verlo en GitHub, (2) probarlo en internet, (3) cambiar algo si no te gusta, (4) invitar a otros a trabajar contigo."
45
+
37
46
  ## Cómo traducir los pasos del flujo
38
47
 
39
48
  | Paso técnico interno | Cómo lo nombras al usuario |
@@ -72,7 +81,8 @@ Si una verificación falla, NO digas "el test X falló con assertion error". Di:
72
81
 
73
82
  ## Cierre de cada interacción
74
83
 
75
- Termina siempre ofreciendo el siguiente paso como una acción en lenguaje natural, no como un comando:
84
+ Termina siempre ofreciendo el siguiente paso como una acción en lenguaje natural, no como un comando. Usa la Regla 8 para enumerar explícitamente qué puede hacer el usuario ahora:
76
85
 
77
86
  > ✅ Ya está. Tu lista de tareas funciona.
87
+ > Ahora puedes: (1) usarla ahora mismo, (2) invitar a otros a colaborar, (3) cambiar cómo se ve.
78
88
  > ¿Quieres que **la publique en internet** para usarla desde cualquier lado? (responde *sí*)
@@ -0,0 +1,164 @@
1
+ ---
2
+ description: Lee .sdd/observabilidad/consumo.jsonl y genera un reporte de actividad de agentes — invocaciones por agente, archivos tocados, picos y señales de fan-out excesivo. Referencia cruzada con orquestacion-ptc y compresion-tokens.
3
+ model: claude-haiku-4-5-20251001
4
+ allowed-tools: Read, Bash
5
+ ---
6
+
7
+ # Skill: Observabilidad de Consumo
8
+
9
+ ## Propósito
10
+
11
+ Convertir el ledger de consumo en información accionable: ver cuántos agentes se activaron, qué archivos tocaron, en qué momentos hubo picos de actividad y si hay señales de fan-out excesivo que conviene corregir.
12
+
13
+ El ledger es un proxy de magnitud (bytes escritos), no una facturación exacta de tokens — Claude Code no expone el conteo real de tokens al hook. Pero es suficiente para detectar patrones problemáticos.
14
+
15
+ ---
16
+
17
+ ## Lo que lees
18
+
19
+ ```bash
20
+ # Ledger completo
21
+ cat .sdd/observabilidad/consumo.jsonl 2>/dev/null || echo "SIN_LEDGER"
22
+
23
+ # Conteo rápido de líneas
24
+ wc -l .sdd/observabilidad/consumo.jsonl 2>/dev/null || echo "0"
25
+ ```
26
+
27
+ ---
28
+
29
+ ## Análisis que produces
30
+
31
+ ### 1. Resumen por agente
32
+
33
+ ```
34
+ node -e "
35
+ const fs = require('fs');
36
+ const path = '.sdd/observabilidad/consumo.jsonl';
37
+ if (!fs.existsSync(path)) { console.log('Sin datos aún.'); process.exit(0); }
38
+
39
+ const lineas = fs.readFileSync(path, 'utf8').trim().split('\n').filter(Boolean);
40
+ const porAgente = {};
41
+ for (const l of lineas) {
42
+ try {
43
+ const e = JSON.parse(l);
44
+ const a = e.agente || 'main';
45
+ if (!porAgente[a]) porAgente[a] = { invocaciones: 0, bytes: 0, archivos: new Set() };
46
+ porAgente[a].invocaciones++;
47
+ porAgente[a].bytes += e.bytes || 0;
48
+ porAgente[a].archivos.add(e.archivo);
49
+ } catch {}
50
+ }
51
+
52
+ console.log('AGENTE | INVOC | BYTES | ARCHIVOS ÚNICOS');
53
+ console.log('-'.repeat(60));
54
+ for (const [a, d] of Object.entries(porAgente).sort((x,y) => y[1].invocaciones - x[1].invocaciones)) {
55
+ console.log(\`\${a.padEnd(19)} | \${String(d.invocaciones).padStart(5)} | \${String(d.bytes).padStart(6)} | \${d.archivos.size}\`);
56
+ }
57
+ console.log('');
58
+ console.log('Total eventos:', lineas.length);
59
+ "
60
+ ```
61
+
62
+ ### 2. Detección de fan-out excesivo
63
+
64
+ Umbrales por defecto (ajustables en `.sdd/sdd.config.yaml`):
65
+
66
+ | Señal | Umbral | Acción sugerida |
67
+ |-------|--------|-----------------|
68
+ | >5 agentes distintos en una fase | Alto | Revisar si la orquestación PTC puede colapsar en menos agentes |
69
+ | >20 invocaciones de un mismo agente | Medio | Revisar si el agente entra en loop o hace trabajo redundante |
70
+ | >500 KB de bytes escritos totales | Informativo | Considerar comprimir memoria con `compresion-tokens` |
71
+
72
+ ```
73
+ node -e "
74
+ const fs = require('fs');
75
+ const path = '.sdd/observabilidad/consumo.jsonl';
76
+ if (!fs.existsSync(path)) process.exit(0);
77
+
78
+ const lineas = fs.readFileSync(path, 'utf8').trim().split('\n').filter(Boolean);
79
+ const agentes = new Set();
80
+ const invocPorAgente = {};
81
+ let bytesTotal = 0;
82
+
83
+ for (const l of lineas) {
84
+ try {
85
+ const e = JSON.parse(l);
86
+ const a = e.agente || 'main';
87
+ agentes.add(a);
88
+ invocPorAgente[a] = (invocPorAgente[a] || 0) + 1;
89
+ bytesTotal += e.bytes || 0;
90
+ } catch {}
91
+ }
92
+
93
+ const alertas = [];
94
+ if (agentes.size > 5) alertas.push('⚠️ Fan-out alto: ' + agentes.size + ' agentes distintos activos');
95
+ for (const [a, n] of Object.entries(invocPorAgente)) {
96
+ if (n > 20) alertas.push('⚠️ Agente en loop posible: ' + a + ' (' + n + ' invocaciones)');
97
+ }
98
+ if (bytesTotal > 500_000) alertas.push('ℹ️ Escritura alta: ' + Math.round(bytesTotal/1024) + ' KB — considera compresion-tokens');
99
+
100
+ if (alertas.length === 0) {
101
+ console.log('✅ Sin alertas de fan-out');
102
+ } else {
103
+ for (const a of alertas) console.log(a);
104
+ }
105
+ "
106
+ ```
107
+
108
+ ### 3. Picos de actividad (top 5 momentos)
109
+
110
+ ```
111
+ node -e "
112
+ const fs = require('fs');
113
+ const path = '.sdd/observabilidad/consumo.jsonl';
114
+ if (!fs.existsSync(path)) process.exit(0);
115
+
116
+ const lineas = fs.readFileSync(path, 'utf8').trim().split('\n').filter(Boolean);
117
+ const parsed = lineas.map(l => { try { return JSON.parse(l); } catch { return null; } }).filter(Boolean);
118
+
119
+ // Agrupar por minuto
120
+ const porMinuto = {};
121
+ for (const e of parsed) {
122
+ const minuto = e.ts?.slice(0,16) || 'desconocido';
123
+ porMinuto[minuto] = (porMinuto[minuto] || 0) + 1;
124
+ }
125
+
126
+ const top = Object.entries(porMinuto).sort((a,b) => b[1] - a[1]).slice(0, 5);
127
+ console.log('TOP 5 MINUTOS DE MAYOR ACTIVIDAD:');
128
+ for (const [m, n] of top) console.log(' ' + m + ' → ' + n + ' eventos');
129
+ "
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Formato del reporte completo
135
+
136
+ ```
137
+ ╔══════════════════════════════════════════════════════╗
138
+ ║ 📊 CONSUMO DE AGENTES — SDD-ES ║
139
+ ╠══════════════════════════════════════════════════════╣
140
+ ║ AGENTE | INVOC | BYTES | ARCHIVOS ║
141
+ ║ [tabla generada] ║
142
+ ╠══════════════════════════════════════════════════════╣
143
+ ║ ALERTAS DE FAN-OUT ║
144
+ ║ [alertas o "✅ Sin alertas"] ║
145
+ ╠══════════════════════════════════════════════════════╣
146
+ ║ TOP MOMENTOS DE ACTIVIDAD ║
147
+ ║ [top 5 minutos] ║
148
+ ╠══════════════════════════════════════════════════════╣
149
+ ║ RECOMENDACIONES ║
150
+ ║ → Si fan-out alto: revisar skill orquestacion-ptc ║
151
+ ║ → Si bytes altos: ejecutar /sdd.comprimir ║
152
+ ║ → Si loop agente: revisar el agente con /sdd.estado║
153
+ ╚══════════════════════════════════════════════════════╝
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Notas
159
+
160
+ - El ledger se escribe en tiempo real por el hook `agent-memory.js` (PostToolUse)
161
+ - Los `bytes` miden el contenido de cada escritura — son un **proxy de magnitud**, no el consumo real de tokens del modelo
162
+ - Para vaciar el ledger al inicio de una sesión nueva: `echo "" > .sdd/observabilidad/consumo.jsonl`
163
+ - Cruzar con `orquestacion-ptc` para decidir cuándo paralelizar vs. serializar agentes
164
+ - Cruzar con `compresion-tokens` para decidir cuándo comprimir los archivos `.sdd/memoria/`