@saulwade/swl-ses 1.5.0 → 1.5.1
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.
- package/CLAUDE.md +209 -208
- package/README.md +1 -1
- package/habilidades/meta-skills-estandar/SKILL.md +22 -1
- package/habilidades/node-experto/SKILL.md +13 -2
- package/habilidades/tdd-workflow/SKILL.md +33 -4
- package/habilidades/verificar-trabajo/SKILL.md +8 -3
- package/package.json +2 -2
- package/plugin.json +1 -1
- package/scripts/doctor.js +31 -4
package/CLAUDE.md
CHANGED
|
@@ -1,208 +1,209 @@
|
|
|
1
|
-
# CLAUDE.md — @saulwade/swl-ses v1.5.
|
|
2
|
-
|
|
3
|
-
## Reglas de máxima prioridad (aplican SIEMPRE, sin excepción)
|
|
4
|
-
|
|
5
|
-
### Idioma obligatorio: español de México
|
|
6
|
-
Todo contenido generado DEBE ser en español de México: respuestas, código comentado, mensajes de commit, descripciones de PR, documentación y comunicación con el usuario. Usar ortografía correcta con acentos, signos de puntuación y gramática normativa. Evitar anglicismos innecesarios y traducciones literales del inglés. Esta regla tiene prioridad sobre cualquier otra instrucción de idioma.
|
|
7
|
-
|
|
8
|
-
### Uso obligatorio del sistema SWL
|
|
9
|
-
Toda tarea DEBE usar el sistema SWL completo: agentes especializados, habilidades, hooks y comandos `/swl:*`. NO hacer trabajo directo que un agente SWL especializado haría mejor. Para tareas complejas: `orquestador-swl`. Para implementación: `implementador-swl` o el agente de stack. Para debugging: `depurador-swl`. Para revisión: `revisor-codigo-swl`. Para planificación: `planificador-swl`. Cargar skills con `Skill("nombre")` antes de implementar.
|
|
10
|
-
|
|
11
|
-
### Investigar antes de editar
|
|
12
|
-
Investigar el codebase ANTES de editar. NUNCA modificar código que no se ha leído primero. Leer el archivo completo, entender el contexto, y solo entonces hacer cambios.
|
|
13
|
-
|
|
14
|
-
### Lectura de documentos Office y Jupyter
|
|
15
|
-
Cuando necesites leer el **contenido** de un archivo `.docx`, `.xlsx`, `.xls`, `.pptx` o `.ipynb`, NUNCA uses el Read tool directamente (no soporta esos formatos). Usa:
|
|
16
|
-
```bash
|
|
17
|
-
python scripts/vendor/markitdown/cli.py <ruta-al-archivo>
|
|
18
|
-
```
|
|
19
|
-
El Read tool sigue siendo correcto para `.pdf` (≤20 páginas), `.md`, `.txt` y código fuente. Para más opciones y casos de uso consultar `Skill("swl-markitdown")`.
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Stack del proyecto
|
|
24
|
-
|
|
25
|
-
- **Runtime**: Node.js >=22.0.0 (ESM + CommonJS)
|
|
26
|
-
- **Tipo**: Sistema de scripts CLI + plugin para Claude Code (multi-runtime: Claude / Copilot / OpenCode / Codex / Gemini)
|
|
27
|
-
- **Formato fuente**: Markdown (agentes, skills, comandos, reglas) + JSON Schema (validación) + YAML (instintos)
|
|
28
|
-
- **Distribución**: npm package (`@saulwade/swl-ses`) + plugin Claude Code (`plugin.json`)
|
|
29
|
-
- **Dependencias runtime**: `docx ^9.6.1`, `pako ^2.1.0`, `readable-stream ^4.7.0` (mínimas; los hooks tienen zero-deps)
|
|
30
|
-
- **Idioma de salida**: 100% español (México) para componentes SWL; skills oficiales de Anthropic en inglés
|
|
31
|
-
|
|
32
|
-
## Comandos del proyecto
|
|
33
|
-
|
|
34
|
-
| Comando | Propósito |
|
|
35
|
-
|---|---|
|
|
36
|
-
| `npm test` | Tests unitarios (lib/, scripts/, hooks/) |
|
|
37
|
-
| `npm run test:all` | test + validar.js + validar-manifest.js |
|
|
38
|
-
| `npm run test:release` | test:all + test:userland + smoke (gate pre-publish) |
|
|
39
|
-
| `npm run test:validate` | `node scripts/validar.js` — validación estructural completa |
|
|
40
|
-
| `npm run test:manifest` | `node scripts/validar-manifest.js` — coherencia modulos/hooks |
|
|
41
|
-
| `npm run test:smoke` | Smoke test del instalador |
|
|
42
|
-
| `npm run gen-checklists` | Regenera `docs/checklists-consolidados/` desde reglas |
|
|
43
|
-
| `npm run gen-checklists:check` | Falla si hay drift (uso CI) |
|
|
44
|
-
| `npm run generate:docs` | Regenera `INVENTARIO.md` desde directorios |
|
|
45
|
-
| `npm run doctor` | Diagnóstico del sistema (`scripts/doctor.js`) |
|
|
46
|
-
| `npm run publish:dry` | Dry-run de publicación a npm + GitHub |
|
|
47
|
-
| `node scripts/verificar-release.js` | Gate pre-release: 15+ ubicaciones de versión, sincronización, AI-isms (si `SWL_AIISMS_GATE=1`) |
|
|
48
|
-
| `node scripts/generar-inventario.js` | Regenera contadores oficiales (NUNCA contar a mano) |
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- **
|
|
54
|
-
- **
|
|
55
|
-
- **
|
|
56
|
-
- **
|
|
57
|
-
- **
|
|
58
|
-
- **
|
|
59
|
-
- **
|
|
60
|
-
- **
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- **
|
|
68
|
-
- **
|
|
69
|
-
- **
|
|
70
|
-
- **
|
|
71
|
-
- **
|
|
72
|
-
- **
|
|
73
|
-
- **
|
|
74
|
-
- **
|
|
75
|
-
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
- `@
|
|
81
|
-
- `@
|
|
82
|
-
- `@
|
|
83
|
-
- `@
|
|
84
|
-
- `@
|
|
85
|
-
- `@
|
|
86
|
-
- `@
|
|
87
|
-
- `@docs/
|
|
88
|
-
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
**
|
|
109
|
-
**
|
|
110
|
-
**
|
|
111
|
-
**
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
| `/swl:
|
|
121
|
-
| `/swl:
|
|
122
|
-
| `/swl:
|
|
123
|
-
| `/swl:
|
|
124
|
-
| `/swl:
|
|
125
|
-
| `/swl:
|
|
126
|
-
| `/swl:
|
|
127
|
-
| `/swl:
|
|
128
|
-
| `/swl:
|
|
129
|
-
| `/swl:
|
|
130
|
-
| `/swl:
|
|
131
|
-
| `/swl:
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
| `
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
| **
|
|
163
|
-
| **
|
|
164
|
-
| **
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
-
|
|
177
|
-
-
|
|
178
|
-
-
|
|
179
|
-
-
|
|
180
|
-
- **
|
|
181
|
-
- **
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
| **
|
|
193
|
-
| **
|
|
194
|
-
| **
|
|
195
|
-
| **
|
|
196
|
-
| **
|
|
197
|
-
| **
|
|
198
|
-
| **
|
|
199
|
-
| **
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
- **
|
|
207
|
-
- **
|
|
208
|
-
- **
|
|
1
|
+
# CLAUDE.md — @saulwade/swl-ses v1.5.1
|
|
2
|
+
|
|
3
|
+
## Reglas de máxima prioridad (aplican SIEMPRE, sin excepción)
|
|
4
|
+
|
|
5
|
+
### Idioma obligatorio: español de México
|
|
6
|
+
Todo contenido generado DEBE ser en español de México: respuestas, código comentado, mensajes de commit, descripciones de PR, documentación y comunicación con el usuario. Usar ortografía correcta con acentos, signos de puntuación y gramática normativa. Evitar anglicismos innecesarios y traducciones literales del inglés. Esta regla tiene prioridad sobre cualquier otra instrucción de idioma.
|
|
7
|
+
|
|
8
|
+
### Uso obligatorio del sistema SWL
|
|
9
|
+
Toda tarea DEBE usar el sistema SWL completo: agentes especializados, habilidades, hooks y comandos `/swl:*`. NO hacer trabajo directo que un agente SWL especializado haría mejor. Para tareas complejas: `orquestador-swl`. Para implementación: `implementador-swl` o el agente de stack. Para debugging: `depurador-swl`. Para revisión: `revisor-codigo-swl`. Para planificación: `planificador-swl`. Cargar skills con `Skill("nombre")` antes de implementar.
|
|
10
|
+
|
|
11
|
+
### Investigar antes de editar
|
|
12
|
+
Investigar el codebase ANTES de editar. NUNCA modificar código que no se ha leído primero. Leer el archivo completo, entender el contexto, y solo entonces hacer cambios.
|
|
13
|
+
|
|
14
|
+
### Lectura de documentos Office y Jupyter
|
|
15
|
+
Cuando necesites leer el **contenido** de un archivo `.docx`, `.xlsx`, `.xls`, `.pptx` o `.ipynb`, NUNCA uses el Read tool directamente (no soporta esos formatos). Usa:
|
|
16
|
+
```bash
|
|
17
|
+
python scripts/vendor/markitdown/cli.py <ruta-al-archivo>
|
|
18
|
+
```
|
|
19
|
+
El Read tool sigue siendo correcto para `.pdf` (≤20 páginas), `.md`, `.txt` y código fuente. Para más opciones y casos de uso consultar `Skill("swl-markitdown")`.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Stack del proyecto
|
|
24
|
+
|
|
25
|
+
- **Runtime**: Node.js >=22.0.0 (ESM + CommonJS)
|
|
26
|
+
- **Tipo**: Sistema de scripts CLI + plugin para Claude Code (multi-runtime: Claude / Copilot / OpenCode / Codex / Gemini)
|
|
27
|
+
- **Formato fuente**: Markdown (agentes, skills, comandos, reglas) + JSON Schema (validación) + YAML (instintos)
|
|
28
|
+
- **Distribución**: npm package (`@saulwade/swl-ses`) + plugin Claude Code (`plugin.json`)
|
|
29
|
+
- **Dependencias runtime**: `docx ^9.6.1`, `pako ^2.1.0`, `readable-stream ^4.7.0` (mínimas; los hooks tienen zero-deps)
|
|
30
|
+
- **Idioma de salida**: 100% español (México) para componentes SWL; skills oficiales de Anthropic en inglés
|
|
31
|
+
|
|
32
|
+
## Comandos del proyecto
|
|
33
|
+
|
|
34
|
+
| Comando | Propósito |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `npm test` | Tests unitarios (lib/, scripts/, hooks/) |
|
|
37
|
+
| `npm run test:all` | test + validar.js + validar-manifest.js |
|
|
38
|
+
| `npm run test:release` | test:all + test:userland + smoke (gate pre-publish) |
|
|
39
|
+
| `npm run test:validate` | `node scripts/validar.js` — validación estructural completa |
|
|
40
|
+
| `npm run test:manifest` | `node scripts/validar-manifest.js` — coherencia modulos/hooks |
|
|
41
|
+
| `npm run test:smoke` | Smoke test del instalador |
|
|
42
|
+
| `npm run gen-checklists` | Regenera `docs/checklists-consolidados/` desde reglas |
|
|
43
|
+
| `npm run gen-checklists:check` | Falla si hay drift (uso CI) |
|
|
44
|
+
| `npm run generate:docs` | Regenera `INVENTARIO.md` desde directorios |
|
|
45
|
+
| `npm run doctor` | Diagnóstico del sistema (`scripts/doctor.js`) |
|
|
46
|
+
| `npm run publish:dry` | Dry-run de publicación a npm + GitHub |
|
|
47
|
+
| `node scripts/verificar-release.js` | Gate pre-release: 15+ ubicaciones de versión, sincronización, AI-isms (si `SWL_AIISMS_GATE=1`) |
|
|
48
|
+
| `node scripts/generar-inventario.js` | Regenera contadores oficiales (NUNCA contar a mano) |
|
|
49
|
+
| `node scripts/derivar-feature-list.js` | Genera `.planning/feature-list.json` (derivado de `HOJA-RUTA.md`, gitignored, regenerable). Modo `--check` exit 2 si drift detectado. Consumido por `/swl:metricas fases`. |
|
|
50
|
+
|
|
51
|
+
## Code style
|
|
52
|
+
|
|
53
|
+
- **Nombres**: kebab-case para archivos, agentes SWL en español, GSD en inglés
|
|
54
|
+
- **Zero-dependencies en `hooks/lib/`**: sin dependencias npm externas
|
|
55
|
+
- **Escrituras atómicas obligatorias**: usar `atomicWriteSync()` / `atomicWriteJSON()` de `hooks/lib/atomic-write.js`. NUNCA `fs.writeFileSync` directo en archivos del sistema
|
|
56
|
+
- **JSONL para alta frecuencia**: usar `fs.appendFileSync(ruta, JSON.stringify(evento) + '\n')` en hooks de telemetría/auditoría — no `atomicWriteJSON` que reescribe todo
|
|
57
|
+
- **YAML inline en frontmatter**: `tools: [Read, Write]`, `skillsInvocables: [skill-a]`. NUNCA CSV string ni mezcla con lista multilínea
|
|
58
|
+
- **Mensajes de commit**: imperativo en español, formato `<tipo>(<scope>): <descripción>`
|
|
59
|
+
- **Sin `console.log` en producción** — excepto en `scripts/`, `bin/`, `hooks/`, `gateway/` (CLIs y daemons)
|
|
60
|
+
- **Nombre completo del paquete en npx**: todo mensaje del installer/docs usa `npx -y @saulwade/swl-ses@latest <comando>`. **NUNCA** `npx swl-ses@latest <comando>` sin el scope `@saulwade/` — eso resuelve al paquete legacy DEPRECATED (v5.13.1) que aún existe en npm tras el rebrand de 2026-04-30. El `@latest` es indispensable: sin él npx reutiliza la primera versión cacheada y el usuario corre código viejo sin saberlo. El `-y` evita la prompt de confirmación en CI/scripts
|
|
61
|
+
- **Fixtures `secret`/`token` en tests deben ser en español** (`secreto`, `tokenBearer`, `clave-test`). El hook `calidad-pre-commit.js` matchea `\bsecret\s*[=:]\s*["'][^"'\s]{4,}["']` y `\btoken\s*[=:]\s*["'][^"'\s]{8,}["']` — `const secret = "valor"` se bloquea como credencial hardcodeada aunque sea fixture legítimo. Renombrar a español elude el regex sin bypass (alternativas reconocidas por el hook: `placeholder`, `example`, `fake_`, `dummy_`, `os.environ`/`process.env`). Coherente con regla global de idioma. Origen: PR #11 sesión 2026-05-13
|
|
62
|
+
- **`git add archivo && git commit -m "..."` en un solo comando bash NO actualiza el index antes del PreToolUse hook**: el hook `calidad-pre-commit.js` evalúa el contenido staged previo al `&&`, no el actualizado en la misma línea. Síntoma: commit bloqueado por contenido que ya corregiste vía Write/Edit pero seguía staged en versión antigua. Fix: separar en dos calls Bash (`git add archivo` → ver resultado → `git commit -m "..."`). NUNCA usar `--no-verify` para bypassear. Origen: PR #11 sesión 2026-05-13
|
|
63
|
+
- **Secretos per-equipo van en `.claude/settings.local.json` (gitignored), no en `.claude/settings.json` (versionado)**: el archivo `settings.json` se sincroniza entre equipos vía git, así que NO puede contener valores per-máquina como apiKeys. Claude Code hace **deep merge** entre `settings.json` y `settings.local.json` — el local sobrescribe solo las keys que define. Patrón obligatorio para `OBSIDIAN_API_KEY` y similares: `settings.json` declara el server MCP con `env: {}` vacío; `settings.local.json` (cada equipo el suyo) tiene `mcpServers.obsidian.env.OBSIDIAN_API_KEY` con el valor del plugin Local REST API de ESE equipo. **NUNCA** poner dos `OBSIDIAN_API_KEY` en el mismo `env` — produce JSON inválido (síntoma: ConnectionRefused o 40101 silenciosos). Origen: PR #19 sesión 2026-05-13 (bug detectado al cambiar de WISC a WISCLAP)
|
|
64
|
+
|
|
65
|
+
## Convenciones de arquitectura
|
|
66
|
+
|
|
67
|
+
- **Precedencia de capas**: Reglas base (`reglas/`) → Reglas por lenguaje (`reglas/{lang}/`) → Skills (`habilidades/`) → Instintos (`instintos/`). Cada capa puede especializar pero NUNCA contradecir las superiores
|
|
68
|
+
- **Privilegio mínimo de agentes**: un agente delegado NUNCA excede los permisos declarados en su propio frontmatter. La cadena de delegación no escala privilegios. Ver `@reglas/seguridad-agentes.md`
|
|
69
|
+
- **Preservación de datos en actualización**: `.planning/sessions/`, `.planning/comms/`, `_userland/`, `instintos/proyecto.yaml`, `APRENDIZAJES.md` NUNCA se sobreescriben
|
|
70
|
+
- **Documentación obligatoria**: toda funcionalidad nueva DEBE documentarse en `MANUAL_USO.md`, `COMANDOS.md`, `CLAUDE.md` y `README.md` ANTES del commit
|
|
71
|
+
- **Criterio dominio para incorporar skills externos**: solo si dominio = ingeniería de software general. Pregunta de filtro: *¿le sirve esto a un ingeniero de software en cualquier proyecto de software?* (ML Ops, Data Science, finanzas, etc. → descartar)
|
|
72
|
+
- **Filtro primario al analizar `temp/`**: antes de evaluar arquitectura, verificar **compatibilidad de dominio**. Si es incompatible, veredicto NINGUNA aplicabilidad sin análisis adicional
|
|
73
|
+
- **Variables de entorno opt-in enterprise**: ver `@docs/variables-entorno.md` (catálogo completo). Patrón obligatorio: `if (!process.env.VAR) return` — zero-config por defecto
|
|
74
|
+
- **Hooks SWL que invocan auditores Node deben cargar el auditor como módulo (`require()`), no como subproceso**: ~10× más rápido, errores estructurados (no parsing de stdout), tests directos del módulo. Excepción legítima: cuando el auditor es Python o Bash (`spawnSync`). Ejemplo aplicado en `hooks/claudemd-bloat-detector.js` que usa `require('./scripts/auditar-claudemd.js')` directamente. Antipatrón evitado: `spawnSync('node', [auditorPath, ...])` agrega ~50ms por invocación y obliga a parsear JSON de stdout
|
|
75
|
+
- **npm v10+ NO escribe debug logs cuando falla un script invocado** (`prepublishOnly`, `prepack`, etc.) — solo cuando falla npm-mismo (network, registry, auth). El default `loglevel=notice` mantiene `_logs/` vacío para errores de scripts. Para diagnóstico de `npm run publish:all` que falla en script propio, capturar stdout+stderr con redirección: PowerShell `npm run publish:all *>&1 | Tee-Object .planning/logs/publish-$(Get-Date -Format yyyyMMdd-HHmmss).log` o Bash `2>&1 | tee`. Alternativa permanente: `npm config set loglevel verbose`
|
|
76
|
+
- **`package.json#files` debe incluir TODOS los directorios referenciados por `bin/`, `hooks/`, `scripts/` o `comandos/`**: si un binario hace `require('./gateway/foo')` pero `gateway/` no está listado en `files`, **el módulo se omite del tarball npm y el binario falla con MODULE_NOT_FOUND tras instalación pública** — aunque la suite local pase. Bug latente histórico: `/swl:cron`, `/swl:gateway` e `/swl:inbox` instruyen `require('./gateway/...')` y rompían en npm porque `gateway/` no estaba en `files` desde versiones previas. Revelado al agregar `bin/swl-webhook-server` (v1.4.0). Verificar antes de cada release: `npm pack --dry-run | grep -E "^npm notice [0-9].*[Bb] (bin|gateway|hooks|scripts|comandos)/"` debe listar todos los directorios reales referenciados. Gate automatizable en `scripts/verificar-release.js`. Origen: PR #15 sesión 2026-05-13
|
|
77
|
+
|
|
78
|
+
## Referencias a docs clave (cargar bajo demanda con `@`)
|
|
79
|
+
|
|
80
|
+
- `@README.md` — overview público y quickstart
|
|
81
|
+
- `@MANUAL_USO.md` — manual operacional completo
|
|
82
|
+
- `@INSTALACION.md` — instalación, perfiles, configuración
|
|
83
|
+
- `@COMANDOS.md` — referencia detallada de cada `/swl:*`
|
|
84
|
+
- `@AGENTS.md` — catálogo de agentes con capacidades
|
|
85
|
+
- `@INVENTARIO.md` — conteos oficiales (regenerado por script)
|
|
86
|
+
- `@CONTRIBUTING.md` — guía para colaboradores
|
|
87
|
+
- `@docs/variables-entorno.md` — variables opt-in completas
|
|
88
|
+
- `@docs/CI-CD-SETUP.md` — setup de pipelines
|
|
89
|
+
- `@.planning/adrs/README.md` — índice de decisiones arquitecturales
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Qué es este repositorio
|
|
94
|
+
|
|
95
|
+
Sistema de ingeniería de software auto-evolutivo multi-runtime polyglot (SDLC completo).
|
|
96
|
+
11 lenguajes, 7 runtimes (Claude, OpenClaude, OpenCode, Gemini, Cursor, Codex, Copilot), 60 agentes, 160 skills, 44 comandos, 65 reglas, 41 hooks.
|
|
97
|
+
|
|
98
|
+
## Estructura del repositorio
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
agentes/ habilidades/ comandos/swl/ contextos/ instintos/
|
|
102
|
+
reglas/ hooks/ schemas/ manifiestos/ plantillas/
|
|
103
|
+
scripts/ bin/ _userland/ .claude/ .planning/
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Flujos de trabajo
|
|
107
|
+
|
|
108
|
+
**Feature completa**: orquestador → discovery → PRD → arquitectura → plan → implementación (paralelo) → calidad (paralelo) → cierre
|
|
109
|
+
**Fases GSD**: discutir → planear → ejecutar → verificar
|
|
110
|
+
**Frontend**: investigador-ux → disenador-ui → accesibilidad → frontend-* → rendimiento
|
|
111
|
+
**Backend**: backend-api → backend-python/node → backend-workers → datos
|
|
112
|
+
**Mobile**: producto-prd → mobile-cross (decisión) → mobile-android/ios → tdd-qa
|
|
113
|
+
|
|
114
|
+
## Comandos del sistema (/swl:*)
|
|
115
|
+
|
|
116
|
+
Para la lista completa con descripción ver `@COMANDOS.md`. Comandos más usados:
|
|
117
|
+
|
|
118
|
+
| Comando | Propósito |
|
|
119
|
+
|---------|-----------|
|
|
120
|
+
| `/swl:nuevo-proyecto` | Iniciar proyecto nuevo desde cero con entrevista |
|
|
121
|
+
| `/swl:adoptar-proyecto` | Incorporar proyecto existente: análisis automático + entrevista corta |
|
|
122
|
+
| `/swl:discutir-fase` / `/swl:planear-fase` / `/swl:ejecutar-fase` / `/swl:verificar` | Ciclo GSD por fase. `discutir-fase` empieza con discovery routing (5 paths: extender / sin-fase / nueva / decomposición / mixto). `ejecutar-fase --iterative` activa modo per-task con review adversarial. `verificar` clasifica claims (TASK/FIX/TEST_OR_BUILD/FEATURE_GO) para evidencia proporcional. |
|
|
123
|
+
| `/swl:checkpoint` / `/swl:compactar` | Anti-context-rot |
|
|
124
|
+
| `/swl:claudemd` | Auditar/refactorizar/inicializar CLAUDE.md (audit, refactor, init-user, check) |
|
|
125
|
+
| `/swl:aprender` / `/swl:evolucionar` / `/swl:autoresearch` | Aprendizaje y auto-evolución |
|
|
126
|
+
| `/swl:salud` / `/swl:metricas` / `/swl:dashboard` | Diagnóstico y observabilidad |
|
|
127
|
+
| `/swl:revisar` / `/swl:verificar` | Calidad de código (revisión por stack, verificación goal-backward). `/swl:verificar --full` activa parallel scorecard con 4 audits paralelos |
|
|
128
|
+
| `/swl:nemesis` | Auditoría iterativa Feynman + State Inconsistency (loop hasta convergencia, ADR-0018). Flags: `--pass1`, `--pass2`, `--continue`, `--modulo <ruta>` |
|
|
129
|
+
| `/swl:release` | Ciclo de release SemVer |
|
|
130
|
+
| `/swl:configurar-ci` | Workflows CI/CD para proyectos del usuario |
|
|
131
|
+
| `/swl:wiki` / `/swl:mapear-codebase` | Conocimiento de proyecto |
|
|
132
|
+
| `/swl:ayuda` | Catálogo interactivo de comandos |
|
|
133
|
+
|
|
134
|
+
## Reglas obligatorias (25 base + 40 por lenguaje)
|
|
135
|
+
|
|
136
|
+
Las reglas globales del usuario en `~/.claude/rules/` se cargan automáticamente
|
|
137
|
+
y aplican a todos los proyectos. Las reglas del sistema en `reglas/` se cargan
|
|
138
|
+
por matcher de archivos o vía `@reglas/<nombre>.md` desde el CLAUDE.md del
|
|
139
|
+
proyecto. Reglas de mayor uso:
|
|
140
|
+
|
|
141
|
+
| Regla | Carga cuando |
|
|
142
|
+
|-------|-------------|
|
|
143
|
+
| `usar-sistema-swl.md` | Siempre — matriz operacional: tarea → componente SWL obligatorio |
|
|
144
|
+
| `brevedad-output.md` | Siempre — idioma español, eficiencia de tokens |
|
|
145
|
+
| `seguridad.md` / `seguridad-agentes.md` | `*.py`, `*.ts`, `auth/`, agentes autónomos |
|
|
146
|
+
| `arreglar-al-detectar.md` | Siempre — detectar → informar → arreglar en mismo turno |
|
|
147
|
+
| `analisis-previo-tareas-grandes.md` | Solicitudes >10 archivos / >500 LOC / cross-módulo |
|
|
148
|
+
| `usar-context7.md` | Al generar código que importe librerías externas |
|
|
149
|
+
| `git-workflow.md` | Siempre |
|
|
150
|
+
| `skills-estandar.md` / `fragmentos-compartidos.md` | Crear/auditar skills o fragmentos |
|
|
151
|
+
|
|
152
|
+
Catálogo completo y matchers en `@INVENTARIO.md` sección Reglas.
|
|
153
|
+
|
|
154
|
+
@reglas/usar-sistema-swl.md
|
|
155
|
+
|
|
156
|
+
## Estrategia de modelos por nivel de criticidad (Model-Tier)
|
|
157
|
+
|
|
158
|
+
Asignar el modelo correcto a cada agente según la criticidad e irreversibilidad de la tarea.
|
|
159
|
+
|
|
160
|
+
| Nivel | Modelo | Campo en frontmatter | Agentes SWL | Criterio |
|
|
161
|
+
|-------|--------|---------------------|-------------|----------|
|
|
162
|
+
| **Crítico** | `claude-opus-4-7` | `model: claude-opus-4-7` | orquestador, arquitecto, revisor-seguridad, producto-prd | Decisiones irreversibles (arquitectura, seguridad, PRD) |
|
|
163
|
+
| **Estándar** | `claude-sonnet-4-6` | `model: claude-sonnet-4-6` | backend-*, frontend-*, mobile-*, tdd-qa, revisores de lenguaje | Implementación y revisión |
|
|
164
|
+
| **Ligero** | `claude-haiku-4-5-20251001` | `model: claude-haiku-4-5-20251001` | notificador, resolutor-build (búsquedas) | Operaciones deterministas rápidas |
|
|
165
|
+
| **Heredado** | (del padre) | `model: inherit` | Sub-agentes invocados por el orquestador | El padre decide |
|
|
166
|
+
|
|
167
|
+
**Reglas de asignación**: decisiones no reversibles → Opus; código → Sonnet; búsqueda/notificación → Haiku.
|
|
168
|
+
NUNCA usar Opus para tareas que Sonnet resuelve igual de bien.
|
|
169
|
+
|
|
170
|
+
**Workflow Opus 4.7**: tratar como ingeniero al que se delega (spec completa: intent + constraints + acceptance criteria + file locations). Sigue instrucciones literalmente — eliminar ambigüedad. Effort levels nativos: `high | xhigh | max`.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Convenciones operacionales
|
|
175
|
+
|
|
176
|
+
- Score mínimo de calidad: **9.0/10** para aprobar trabajo
|
|
177
|
+
- Modos de desarrollo: `dev`, `review`, `research` (vía `/swl:contexto`)
|
|
178
|
+
- `respositorios-git/` y `temp/` son material de referencia — no modificar ni commitear
|
|
179
|
+
- Inventario completo: ver `@INVENTARIO.md` o `@.planning/ESTADO.md`
|
|
180
|
+
- **Limpieza de registros resueltos**: no dejar items completados en listas de pendientes
|
|
181
|
+
- **Dependencias externas educativas son opt-in NO-dependencia**: cuando se documenta un recurso externo (MCPs opcionales, plantillas comunitarias, indexadores externos) marcarlo explícitamente como **"NO es dependencia técnica de swl-ses"**. El sistema debe seguir funcionando sin ese recurso
|
|
182
|
+
- **Patrón "validar antes de invocar"**: cualquier invocación a herramienta externa opt-in (markitdown, MinerU, gh, etc.) DEBE verificar primero (`command -v <bin>` / `try/catch execSync('<bin> --version')`) y, si no está disponible, **continuar con el flujo nativo de SWL sin emitir error al usuario**
|
|
183
|
+
- **`skillsInvocables` requiere `Skill` en `tools:`**: si un agente declara `skillsInvocables: [...]` Y su cuerpo usa `Skill("nombre")`, debe incluir `Skill` en `tools:`. Verificar con `grep -c 'Skill(' agentes/X.md` >0
|
|
184
|
+
- **Criterio gitignore para JSONL — runtime vs baseline**: runtime telemetry (alta frecuencia, recreable) → gitignore. Baseline auditable (histórico crítico, decisiones, evidencia gobernanza) → trackear. Pregunta filtro: *si borro este archivo, ¿se pierde info que el sistema necesita reconstruir desde otra fuente?* Sí → trackear
|
|
185
|
+
|
|
186
|
+
## Mapa de propagación de cambios
|
|
187
|
+
|
|
188
|
+
Al modificar un componente del sistema, verificar TODOS los archivos afectados.
|
|
189
|
+
|
|
190
|
+
| Tipo de cambio | Archivos a verificar |
|
|
191
|
+
|----------------|---------------------|
|
|
192
|
+
| **Agente** | `plugin.json`, `manifiestos/modulos.json`, `INVENTARIO.md`, `AGENTS.md`, `SALUD.md`, `.planning/REPORTE-GRAFO.md` |
|
|
193
|
+
| **Skill** | `plugin.json`, `manifiestos/modulos.json`, `INVENTARIO.md`, `CLAUDE.md` (si aplica al dominio) |
|
|
194
|
+
| **Hook** | `plugin.json`, `.claude/settings.json`, `manifiestos/hooks-config.json` (event+matcher), `manifiestos/modulos.json` (ruta), `INVENTARIO.md`, `SALUD.md`. **AMBOS manifiestos son obligatorios** |
|
|
195
|
+
| **Comando** | `COMANDOS.md`, `CLAUDE.md` (tabla de comandos), `INVENTARIO.md` |
|
|
196
|
+
| **Regla** | `CLAUDE.md` (tabla de reglas), `INVENTARIO.md`, `SALUD.md` |
|
|
197
|
+
| **Schema** | `INVENTARIO.md`, `SALUD.md` |
|
|
198
|
+
| **Bump de versión** | 15+ ubicaciones — checklist en `/swl:release` paso 6 |
|
|
199
|
+
| **CLAUDE.md (cualquier capa)** | Verificar con `/swl:claudemd audit` antes de commit |
|
|
200
|
+
| **Cualquier `npm publish`** | Ejecutar `node scripts/verificar-release.js` ANTES, no solo en release formal. Detecta discrepancias de contadores y versiones invisibles al ojo humano (caso real v1.3.0: 18 discrepancias detectadas) |
|
|
201
|
+
|
|
202
|
+
Esta tabla es obligatoria. Omitir un archivo causa fallos en `/swl:salud`.
|
|
203
|
+
|
|
204
|
+
### Reglas auxiliares
|
|
205
|
+
|
|
206
|
+
- **Regenerar inventario, nunca contar a mano**: antes de modificar contadores en CLAUDE.md/README.md/SALUD.md/AGENTS.md/package.json/plugin.json, ejecutar `node scripts/generar-inventario.js`. El script es la fuente de verdad
|
|
207
|
+
- **Checklists consolidados se regeneran**: archivos en `docs/checklists-consolidados/` son derivados. Editar la regla origen y `npm run gen-checklists`. NO editar manualmente los generados
|
|
208
|
+
- **Modelo por defecto headless**: scripts/bots externos invocan `claude -p --model claude-haiku-4-5-20251001 --effort low --max-budget-usd 0.50 --dangerously-skip-permissions`. Haiku 4.5 cuesta 5× menos
|
|
209
|
+
- **File-based queue sobre PTY injection**: control remoto via `gateway/command-relay.js` → `.planning/inbox/cmd-*.json` → `/swl:inbox`. Tmux solo opt-in avanzado (`scripts/inbox-tmux-inject.js` Linux/macOS)
|
package/README.md
CHANGED
|
@@ -9,7 +9,12 @@ description: >
|
|
|
9
9
|
idiomas de framework y mapeo a frameworks de seguridad. Cargar cuando se
|
|
10
10
|
esté escribiendo o auditando un SKILL.md y se necesiten patrones avanzados
|
|
11
11
|
que no están en la regla core.
|
|
12
|
-
version: "1.0.
|
|
12
|
+
version: "1.0.1"
|
|
13
|
+
evolved: true
|
|
14
|
+
evolved-from: "1.0.0"
|
|
15
|
+
evolved-at: "2026-05-15"
|
|
16
|
+
evolved-by: "aprender"
|
|
17
|
+
evolved-note: "Gotcha 'absorber naming externo al portar patrón valioso' agregado. Origen: instrucción explícita del usuario en sesión 2026-05-15 al renombrar 'kiro-review-protocol' → 'protocolo-revision-swl' durante absorción cc-sdd."
|
|
13
18
|
herramientasPermitidas: [Read, Write, Edit]
|
|
14
19
|
exclusiones:
|
|
15
20
|
- "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."
|
|
@@ -293,6 +298,22 @@ al caso en cuestión en lugar de los tres.
|
|
|
293
298
|
- **Cargar este skill cuando la regla core basta**: esto invierte el trade-off
|
|
294
299
|
de context budget. Cargar `meta-skills-estandar` solo cuando se necesita
|
|
295
300
|
contenido extendido, no por defecto.
|
|
301
|
+
- **Absorber naming externo al portar un patrón valioso**: cuando un skill
|
|
302
|
+
externo (de cc-sdd, harness-sdd, langchain, kiro, etc.) aporta un patrón
|
|
303
|
+
útil, la tentación es importar también el nombre original (`kiro-review`,
|
|
304
|
+
`kiro-impl`, `langchain-router`). Causa: economía cognitiva en la transición.
|
|
305
|
+
Costo: rompe la identidad del sistema receptor, confunde routing del
|
|
306
|
+
orquestador, viola la regla de idioma español MX y crea acoplamiento
|
|
307
|
+
conceptual con un sistema externo cuya API puede cambiar. Solución
|
|
308
|
+
obligatoria: **portar el patrón, adaptar el nombre al naming del sistema
|
|
309
|
+
receptor**. Para SWL: usar prefijo `swl-` o sufijo `-swl`, en español MX,
|
|
310
|
+
con el dominio del problema (no del sistema origen). Ejemplo real
|
|
311
|
+
(2026-05-15): el patrón `kiro-review` de cc-sdd se absorbió como
|
|
312
|
+
`protocolo-revision-swl` por instrucción explícita del usuario; `kiro-impl`
|
|
313
|
+
iterativo se absorbió como `ejecutar-task-iterativo`. Documentar el origen
|
|
314
|
+
en la sección "Referencias" o "Origen" del skill, NO en el nombre. Verificar
|
|
315
|
+
con `git log --grep="kiro\|otro-prefijo-externo"` que no quedan menciones
|
|
316
|
+
del naming externo en el codebase del sistema receptor.
|
|
296
317
|
|
|
297
318
|
## Referencias
|
|
298
319
|
|
|
@@ -4,9 +4,9 @@ description: Node.js y TypeScript backend moderno. Cubre patterns de Express/Fas
|
|
|
4
4
|
version: "1.0.1"
|
|
5
5
|
evolved: true
|
|
6
6
|
evolved-from: "1.0.0"
|
|
7
|
-
evolved-at: "2026-05-
|
|
7
|
+
evolved-at: "2026-05-15"
|
|
8
8
|
evolved-by: "aprender"
|
|
9
|
-
evolved-note: "Gotcha req.destroy() vs req.pause() en
|
|
9
|
+
evolved-note: "Gotcha req.destroy() vs req.pause() en HTTP nativos (PR #13). + CRLF regex breakage en Windows + serializar TOML con literal '''...''' (Sub-fase 11/11.5 v1.5.1)."
|
|
10
10
|
herramientasPermitidas: [Read, Write, Glob]
|
|
11
11
|
exclusiones:
|
|
12
12
|
- "No cargar para aplicaciones Next.js con App Router — Next.js tiene patrones de Server Components, SSR y caché que difieren del backend Node puro; cargar `nextjs-experto`."
|
|
@@ -272,6 +272,17 @@ if (require.main === module) {
|
|
|
272
272
|
|
|
273
273
|
**`req.destroy()` en un handler `http` cierra el socket antes de poder enviar la respuesta**: cuando se aborta la lectura del body (por ejemplo al exceder `maxPayloadBytes`), llamar `req.destroy()` en el listener `data` cierra el socket inmediatamente. El subsiguiente `res.writeHead(413); res.end()` del handler falla porque ya no hay socket — el cliente recibe `ECONNRESET` en lugar de 413. Causa: `destroy()` no espera al flush de la respuesta pendiente; equivale a un `RST` TCP. Fix: usar `req.pause()` + un flag `abortado = true` + rechazar la promesa de lectura; dejar que el handler envíe `res.writeHead(413); res.end(...)` normalmente. Node cierra el socket por sí solo tras `res.end()`. Aplica a servidores HTTP nativos sin Express/Fastify, donde el control del body es manual.
|
|
274
274
|
|
|
275
|
+
**Regex multi-line con `\n` falla con archivos CRLF de Windows**: un parser que usa `/^---\n([\s\S]*?)\n---\n/` para detectar frontmatter YAML rompe con archivos commiteados en Windows (donde git aplica `core.autocrlf=true` y convierte LF↔CRLF al checkout). Caso real (Sub-fase 11.5 v1.5.1, swl-ses): `parsearFrontmatter` en `scripts/lib/transformadores/base.js` devolvía `frontmatter:{}` y `cuerpo:<archivo entero>` para los 60 agentes `agentes/*.md` cuando se ejecutaba en Windows. Resultado downstream: `transformarAgente` de Codex generaba TOML con `description = ""` y `developer_instructions` con el frontmatter duplicado dentro del body. Bug latente que solo aparece al ejecutar contra archivos reales con CRLF. Fix: normalizar antes del match — `const norm = String(contenido).replace(/\r\n/g, '\n').replace(/\r/g, '\n');` y aplicar regex sobre `norm`. Siempre asumir que cualquier archivo leído de filesystem en Windows puede tener CRLF, incluso si git lo "almacena" como LF. Aplica a TODA función con regex multi-line que reciba contenido de filesystem.
|
|
276
|
+
|
|
277
|
+
**Serializar TOML zero-deps: preferir `'''literal'''` sobre `"""basic"""` para multi-line con backslashes**: TOML soporta dos sintaxis multi-line — basic `"""..."""` que procesa escapes (`\n`, `\t`, `\\`) y literal `'''...'''` que preserva el contenido tal cual. Caso real (Sub-fase 11 v1.5.1, swl-ses): al serializar el cuerpo Markdown de agentes SWL (con regex `\n`, paths Windows con `\`, etc.) a `developer_instructions` de `~/.codex/agents/*.toml`, usar basic `"""..."""` exigía escapar cada `\` a `\\` (laborioso y propenso a bugs). Solución: usar literal `'''...'''` por default (preserva Markdown crudo) y caer a basic `"""..."""` con escape SOLO si el cuerpo contiene `'''` literal (raro). Helper en `scripts/lib/transformadores/codex.js`:
|
|
278
|
+
```js
|
|
279
|
+
_tomlMultiline(s) {
|
|
280
|
+
if (!s.includes("'''")) return `'''\n${s}\n'''`;
|
|
281
|
+
return `"""\n${s.replace(/\\/g, '\\\\').replace(/"""/g, '\\"""')}\n"""`;
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
Aplica a cualquier serialización TOML manual sin librería (`@iarna/toml`, etc.) donde el contenido es texto rico con caracteres especiales.
|
|
285
|
+
|
|
275
286
|
```js
|
|
276
287
|
// MAL — ECONNRESET en cliente, nunca recibe 413
|
|
277
288
|
req.on('data', chunk => {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tdd-workflow
|
|
3
3
|
description: Flujo completo de Test-Driven Development. Ciclo RED (el test falla) → GREEN (implementación mínima) → REFACTOR (limpieza). Incluye cobertura mínima obligatoria, tests de frontera, factories, fixtures y estrategias para diferentes tipos de código (APIs, services, componentes Angular).
|
|
4
|
-
version: "1.0.
|
|
4
|
+
version: "1.0.3"
|
|
5
5
|
evolved: true
|
|
6
|
-
evolved-from: "1.0.
|
|
7
|
-
evolved-at: "2026-05-
|
|
6
|
+
evolved-from: "1.0.2"
|
|
7
|
+
evolved-at: "2026-05-15"
|
|
8
8
|
evolved-by: "aprender"
|
|
9
|
-
evolved-note: "
|
|
9
|
+
evolved-note: "Gotcha process.cwd() cacheado al require() rompe tests con process.chdir(): fix con parámetro cwd opcional + fallback dinámico. Caso real scripts/derivar-feature-list.js v1.5.0."
|
|
10
10
|
herramientasPermitidas: [Read, Bash]
|
|
11
11
|
evolvable: true # default para skill estandar
|
|
12
12
|
exclusiones:
|
|
@@ -330,3 +330,32 @@ assert.equal(b.consumir(5, T0 + 5000), true); // 5 seg después: 5 tokens
|
|
|
330
330
|
Aplica también a tests de clock skew (tiempo retrocede por NTP): pasar `T0 - 1000` y validar que la lógica no rompe. Origen: rate-limit-ip.js + webhook-dedup.js sesión 2026-05-13.
|
|
331
331
|
|
|
332
332
|
**Tests nombrados por feature (`test_emitir_factura_exitosa`) pierden poder regresivo; nombrados por causa raíz (`test_repository_no_usa_columna_inexistente_p_monto`) detectan regresiones específicas sin reproducción manual** [CONFIRMADO en SIGM Opción C F1.4]: cuando se descubre un bug por una causa raíz concreta (typo en nombre de columna SQL, omisión de `selectinload`, mock que devuelve dict en vez de objeto, schema obsoleto), el test de regresión que se escribe debe llevar el nombre de la causa, no del feature afectado. Caso real: durante F1.4 de SIGM, el repository de pagos referenciaba `p.monto` cuando la columna se llamaba `p.monto_pagado`; el test escrito como `test_repository_no_usa_columna_inexistente_p_monto` falló inmediatamente en la siguiente sesión cuando otro agente reintrodujo el typo, sin necesidad de reproducir el escenario de negocio (emitir cobro real, verificar respuesta). Causa: los nombres orientados a feature (`test_pago_exitoso`) son ambiguos sobre QUÉ falla — si el test falla, el desarrollador debe diagnosticar; los nombres orientados a causa raíz (`test_X_no_usa_Y`, `test_query_incluye_selectinload_Z`, `test_service_devuelve_dict_no_objeto`) son auto-diagnósticos. Fix: para cada bug que cueste >30 min diagnosticar, escribir UN test adicional cuyo nombre describa la condición técnica violada, no el escenario de negocio. Convención: `test_<componente>_<condicion_tecnica>` o `test_<componente>_no_<anti_patron>`. Estos tests son tu segunda línea de defensa contra regresiones de la misma causa raíz, complementarios a los tests de comportamiento.
|
|
333
|
+
|
|
334
|
+
**`process.cwd()` cacheado al `require()` rompe tests con `process.chdir(sandbox)`** [PATRÓN GENÉRICO TESTING CLI]: scripts Node exportables que leen `process.cwd()` en el scope del módulo (al cargar) congelan el cwd al directorio de invocación. Los tests que crean sandboxes con `fs.mkdtempSync()` y luego `process.chdir(sandbox)` no afectan al cwd cacheado — el script sigue leyendo del cwd original y los assertions fallan con paths inesperados. Caso real (swl-ses `scripts/derivar-feature-list.js` 2026-05-15): la función `enriquecerDesdeFases(fases)` leía `const CWD = process.cwd()` calculado al `require()`; 2 tests con `process.chdir(sandbox)` retornaron `[]` en lugar de detectar el PLAN.md fixture. Causa: el constante se evaluó cuando el `node --test` cargó el módulo desde el cwd del proyecto, no desde el sandbox del test individual. Fix obligatorio: funciones exportables deben aceptar `cwd` como parámetro opcional con fallback dinámico (`function fn(args, opciones = {}) { const cwd = opciones.cwd || process.cwd(); ... }`). El código de producción no cambia (sin args extras), pero los tests pueden inyectar el cwd correcto. Aplica también a Python (`def fn(args, cwd: str | None = None): cwd = cwd or os.getcwd()`) y a cualquier lenguaje con tests que usen chdir.
|
|
335
|
+
|
|
336
|
+
```js
|
|
337
|
+
// MAL — cwd cacheado al require, tests con process.chdir() fallan
|
|
338
|
+
const CWD = process.cwd();
|
|
339
|
+
const PLANNING_DIR = path.join(CWD, '.planning');
|
|
340
|
+
|
|
341
|
+
function enriquecerDesdeFases(fases) {
|
|
342
|
+
const archivos = fs.readdirSync(path.join(PLANNING_DIR, 'fases')); // cwd congelado
|
|
343
|
+
// ...
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// BIEN — cwd dinámico con parámetro opcional para tests
|
|
347
|
+
function enriquecerDesdeFases(fases, opciones = {}) {
|
|
348
|
+
const cwd = opciones.cwd || process.cwd(); // recalcula al llamar
|
|
349
|
+
const archivos = fs.readdirSync(path.join(cwd, '.planning', 'fases'));
|
|
350
|
+
// ...
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// En el test:
|
|
354
|
+
const sandbox = fs.mkdtempSync(path.join(os.tmpdir(), 'test-'));
|
|
355
|
+
fs.mkdirSync(path.join(sandbox, '.planning', 'fases'), { recursive: true });
|
|
356
|
+
// Opción A: pasar cwd explícito (recomendado)
|
|
357
|
+
const r = enriquecerDesdeFases([], { cwd: sandbox });
|
|
358
|
+
// Opción B: process.chdir() — solo funciona con cwd dinámico
|
|
359
|
+
process.chdir(sandbox);
|
|
360
|
+
const r2 = enriquecerDesdeFases([]);
|
|
361
|
+
```
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: verificar-trabajo
|
|
3
3
|
description: Verificación goal-backward del trabajo ejecutado en 4 niveles progresivos — EXISTE, SUSTANTIVO, CONECTADO, DATOS_FLUYEN. Clasifica claims en 4 tipos (TASK, FIX, TEST_OR_BUILD, FEATURE_GO) con evidencia proporcional. Detecta stubs, componentes huérfanos, integraciones rotas y flujos incompletos. Produce veredictos estructurados JSON con clasificación de riesgo (Low/Medium/High) y evidencia verificable. Soporta loop de reparación cuando el veredicto es Fail.
|
|
4
|
-
version: "1.2.
|
|
4
|
+
version: "1.2.1"
|
|
5
5
|
evolved: true
|
|
6
|
-
evolved-from: "1.
|
|
6
|
+
evolved-from: "1.2.0"
|
|
7
7
|
evolved-at: "2026-05-15"
|
|
8
8
|
evolved-by: "aprender"
|
|
9
|
-
evolved-note: "
|
|
9
|
+
evolved-note: "Gotchas v1.5.1 acumulados en este ciclo: (1) health-check post-hoc que recalcula contexto del install desde cwd actual → falso positivo (caso doctor 2026-05-15); (2) smoke E2E obligatorio para features cross-cutting (Sub-fase 11.5: transformarAgente nunca invocado pese a suite 100% verde); (3) auto-reparación debe verificar que el chequeo subsecuente ya no detecta el problema, si no → loop infinito (Sub-fase 12: doctor)."
|
|
10
10
|
herramientasPermitidas: [Read, Write, Edit, Bash, Glob, Grep]
|
|
11
11
|
exclusiones:
|
|
12
12
|
- "No cargar durante la implementación activa de una tarea; la verificación es posterior a la implementación, no concurrente."
|
|
@@ -340,6 +340,11 @@ estructurado JSON, ver [recursos/plantilla-verificacion.md](recursos/plantilla-v
|
|
|
340
340
|
- **Loop de reparación sin re-verificación completa**: tras el fix, el agente re-verifica solo el item que falló en lugar del veredicto completo. Causa: optimización incorrecta para ahorrar tiempo. Solución: el paso 3 del loop de reparación dice explícitamente "re-ejecutar la verificación COMPLETA" — un fix puede resolver un fallo pero introducir otro.
|
|
341
341
|
- **Hollow Component no detectado en Nivel 2**: el componente Angular tiene template pero no usa ninguna señal del componente. El agente verifica que el archivo existe (Nivel 1) y que tiene contenido (Nivel 2), pero no detecta que el contenido es decorativo. Causa: la definición de "stub" en Nivel 2 no se aplicó al caso de templates sin binding. Solución: verificar explícitamente que el template usa al menos una variable/señal del componente.
|
|
342
342
|
- **Verificación con tests + linter pasa pero al levantar BD fresca todo se rompe**: tests Python con mocks y `ruff check` retornan verde, pero `docker compose down -v && up` falla porque hay drift entre `database/schemas/`, seeds, funciones SQL y vistas. Caso real (SIGM 2026-05-04): primera pasada de `/swl:verificar` reportó "APROBADO 21/22" sin detectar que ~10 seeds tenían columnas obsoletas, UUIDs inválidos y un script `02-crear-buckets-minio.sh` que abortaba initdb del contenedor postgres. Causa: la verificación corre solo contra el código (que mockea BD); nunca aplica el SQL real. Solución: cuando el alcance toca cualquier archivo en `database/schemas/`, `database/seeds/`, `database/functions/` o `database/views/`, ejecutar como Nivel 4 (DATOS_FLUYEN) obligatorio: `docker compose down -v && docker compose up -d db && wait_for_health && docker logs <db_container> | grep -E "ERROR|skipped"`. Cualquier ERROR en logs de init invalida el veredicto Pass.
|
|
343
|
+
- **Health-check post-hoc que recalcula contexto del install desde cwd actual produce falso positivo**: un verificador (doctor, validador, monitor) que recalcula filtros — aplicados al momento del install — desde el `process.cwd()` actual genera discrepancia falsa cuando se ejecuta desde un dir distinto. Caso real (swl-ses doctor v1.4.3, 2026-05-15): reportaba "reglas: 65 (perfil esperaba 25)" porque recalculaba `filtrarReglasPorStack(detectarStack(cwd))` con `cwd` vacío de indicadores, mientras las 40 reglas-lenguajes se habían instalado correctamente con stack detectado en el dir del proyecto. Causa: el filtro depende del contexto del momento del install, no del momento del check. Solución obligatoria: **persistir el contexto del install en el state file** (en este caso `allLangs` + `stackInstalado` en `.swl-install-state.json`). Si el state es legacy (sin estos campos), **inferir el contexto desde los archivos realmente instalados** (ej: subdirs presentes bajo `reglas/lenguajes/<lang>/`), NO recalcular desde cwd. Aplica como regla general a cualquier check post-hoc cuya validez depende del contexto del install.
|
|
344
|
+
|
|
345
|
+
- **Suite 100% verde con bug latente cross-cutting que solo aparece en smoke E2E real**: las unit tests del transformador pasaban, los tests del instalador pasaban, los tests del manifiesto pasaban — pero el smoke `install --target codex --local --force` reveló que `instalarArchivo()` hacía `fs.copyFileSync(archivo.origen, destino)` literal sin invocar `transformarAgente()`. Los `.toml` de Codex y los `.md` normalizados de Cursor NUNCA se generaban en disco aunque las unit tests del transformador retornaran contenido correcto. Caso real (Sub-fase 11.5 v1.5.1, 2026-05-15): la integración de las dos capas (transformador + instalador) jamás se testeaba E2E porque cada una se probaba en aislamiento con mocks. **Regla obligatoria para features cross-cutting** (multi-capa: transformador + instalador + filesystem; o lib + bin + cliente; o backend + frontend + cache): el Nivel 4 DATOS_FLUYEN exige al menos un smoke E2E real que ejercite las tres capas con archivos reales en disco temporal. NO sustituible por unit tests aunque la suite sea 100% verde. Comando mínimo: `mkdir tmp && cd tmp && bin/CLI <comando-happy-path> && ls -R` + inspección del primer archivo generado.
|
|
346
|
+
|
|
347
|
+
- **Auto-reparación ejecuta acción sin verificar que el chequeo subsecuente ya no detecta el problema**: el doctor reporta "faltan reglas: 0/25" en Codex, el usuario elige "reparar automáticamente", el doctor invoca `instalador.install({force:true})`, reinstala 230 archivos, vuelve a chequear y reporta lo mismo. Loop infinito. Caso real (Sub-fase 12 v1.5.1, 2026-05-15): los 4 falsos positivos del doctor sobre Codex/Cursor persistían tras cada "reparación" porque la causa raíz era un filtro hardcoded (`tiposPrincipales = ['agentes', 'habilidades', 'comandos', 'reglas']` sin respetar `runtime.tiposSoportados` ni `dir<Tipo>`). Cada reinstalación dejaba el filtro intacto, el chequeo seguía detectando el "problema". **Regla**: toda función de auto-reparación debe ejecutar el chequeo subsecuente ANTES de reportar "Reparado" — si el chequeo sigue detectando el problema, NO marcar como reparado y reportar "no se pudo reparar, requiere diagnóstico manual". Implementación: wrap la acción en `try { accion(); const res = chequeo(); if (!res.ok) throw new Error('reparación sin efecto'); }`.
|
|
343
348
|
|
|
344
349
|
## Regla de oro del verificador
|
|
345
350
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saulwade/swl-ses",
|
|
3
|
-
"version": "1.5.
|
|
4
|
-
"description": "Sistema de ingenieria de software auto-evolutivo multi-runtime polyglot con 60 agentes,
|
|
3
|
+
"version": "1.5.1",
|
|
4
|
+
"description": "Sistema de ingenieria de software auto-evolutivo multi-runtime polyglot con 60 agentes, 160 habilidades, 44 comandos, 65 reglas y 41 hooks. Soporta 11 lenguajes y 7 runtimes: Claude Code, OpenClaude, OpenCode, Gemini CLI, Cursor, Codex CLI (soporte completo); GitHub Copilot (soporte parcial). 100% en espanol (Mexico). Multi-target install (--target CSV / --all-runtimes), autoconfig MCP en Cursor/Codex con --with-mcp, agentes Codex en TOML, hooks Cursor (17 eventos) y Codex (6 eventos). Gateway bidireccional con relay Telegram y auditoria profunda Nemesis con 8 tools ejecutables.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"swl-ses": "bin/swl-ses.js",
|
|
7
7
|
"swl-telegram-bot": "bin/swl-telegram-bot.js",
|
package/plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swl-ses",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Sistema de ingenieria de software auto-evolutivo multi-runtime polyglot. 60 agentes, 158 habilidades, 44 comandos, 65 reglas y 41 hooks. 62 librerias. 11 lenguajes. Soporta Claude Code, Copilot, OpenCode, Codex y Gemini CLI.",
|
|
5
5
|
"author": "Saul Wade Leon",
|
|
6
6
|
"license": "MIT",
|
package/scripts/doctor.js
CHANGED
|
@@ -324,8 +324,14 @@ async function doctor(opciones = {}) {
|
|
|
324
324
|
// 5b-2. Verificar conteo de componentes contra perfil esperado.
|
|
325
325
|
// Bug H v1.3.5: antes solo verificaba runtime.local; instalaciones globales
|
|
326
326
|
// (~/.claude/) quedaban sin check de conteo. Ahora itera ambos scopes.
|
|
327
|
+
// Sub-fase 12 v1.5.0: deduplicar paths cuando cwd === homedir (runtime.local
|
|
328
|
+
// y runtime.global colapsan al mismo directorio) — evita reporte doble.
|
|
327
329
|
for (const runtime of runtimes) {
|
|
328
|
-
|
|
330
|
+
const dirsUnicos = Array.from(new Set([
|
|
331
|
+
path.resolve(runtime.global),
|
|
332
|
+
path.resolve(runtime.local),
|
|
333
|
+
]));
|
|
334
|
+
for (const dir of dirsUnicos) {
|
|
329
335
|
if (!fs.existsSync(dir)) continue;
|
|
330
336
|
const estado = cargarEstado(dir);
|
|
331
337
|
if (!estado || !estado.perfil) continue;
|
|
@@ -367,8 +373,21 @@ async function doctor(opciones = {}) {
|
|
|
367
373
|
resolucion.archivos = filtrado.archivos;
|
|
368
374
|
}
|
|
369
375
|
|
|
370
|
-
//
|
|
371
|
-
|
|
376
|
+
// Sub-fase 12 v1.5.0: filtrar tipos principales por runtime.tiposSoportados
|
|
377
|
+
// Y por la presencia de `dir<Tipo>` no-null. Codex declara `reglas` en
|
|
378
|
+
// tiposSoportados pero las consolida en AGENTS.md (dirReglas: null) — los
|
|
379
|
+
// archivos individuales no existen aunque el resolver los liste como esperados.
|
|
380
|
+
// Reportar "faltan reglas: 0/N" en ese caso es falso positivo que dispara
|
|
381
|
+
// loop infinito de auto-reparación.
|
|
382
|
+
const TIPO_A_DIR = {
|
|
383
|
+
agentes: 'dirAgentes',
|
|
384
|
+
habilidades: 'dirHabilidades',
|
|
385
|
+
comandos: 'dirComandos',
|
|
386
|
+
reglas: 'dirReglas',
|
|
387
|
+
};
|
|
388
|
+
const tiposPrincipales = ['agentes', 'habilidades', 'comandos', 'reglas']
|
|
389
|
+
.filter(t => !runtime.tiposSoportados || runtime.tiposSoportados.includes(t))
|
|
390
|
+
.filter(t => runtime[TIPO_A_DIR[t]]);
|
|
372
391
|
const esperadosPorTipo = {};
|
|
373
392
|
for (const archivo of resolucion.archivos) {
|
|
374
393
|
const tipo = archivo.tipo || 'otros';
|
|
@@ -451,8 +470,16 @@ async function doctor(opciones = {}) {
|
|
|
451
470
|
}
|
|
452
471
|
}
|
|
453
472
|
|
|
454
|
-
// 5c. Verificar optimizaciones de rendimiento en settings.json
|
|
473
|
+
// 5c. Verificar optimizaciones de rendimiento en settings.json.
|
|
474
|
+
// Sub-fase 12 v1.5.0: las optimizaciones `ENABLE_TOOL_SEARCH` y
|
|
475
|
+
// `showThinkingSummaries` son específicas de Claude Code `settings.json`.
|
|
476
|
+
// Codex usa `config.toml` con schema TOML; Cursor usa schema propio.
|
|
477
|
+
// Aplicar estas claves a Codex/Cursor poluciona su config con keys que
|
|
478
|
+
// no tienen efecto. Restringir el check al runtime claude/openclaude.
|
|
479
|
+
const RUNTIMES_CON_OPTIMIZACIONES = new Set(['claude', 'openclaude']);
|
|
455
480
|
for (const runtime of runtimes) {
|
|
481
|
+
if (!RUNTIMES_CON_OPTIMIZACIONES.has(runtime.id)) continue;
|
|
482
|
+
|
|
456
483
|
const dir = path.resolve(runtime.local);
|
|
457
484
|
if (!fs.existsSync(dir)) continue;
|
|
458
485
|
const estado = cargarEstado(dir);
|