@saulwade/swl-ses 1.0.0 → 1.1.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 +8 -5
- package/README.md +2 -2
- package/agentes/accesibilidad-wcag-swl.md +5 -7
- package/agentes/arquitecto-swl.md +5 -3
- package/agentes/auto-evolucion-swl.md +42 -12
- package/agentes/backend-api-swl.md +5 -3
- package/agentes/backend-csharp-swl.md +5 -3
- package/agentes/backend-go-swl.md +5 -3
- package/agentes/backend-java-swl.md +5 -3
- package/agentes/backend-node-swl.md +5 -3
- package/agentes/backend-python-swl.md +5 -3
- package/agentes/backend-rust-swl.md +5 -3
- package/agentes/backend-workers-swl.md +5 -3
- package/agentes/cloud-infra-swl.md +5 -6
- package/agentes/consolidador-swl.md +5 -3
- package/agentes/datos-swl.md +5 -7
- package/agentes/depurador-swl.md +6 -3
- package/agentes/devops-ci-swl.md +5 -3
- package/agentes/disenador-ui-swl.md +5 -7
- package/agentes/documentador-swl.md +5 -3
- package/agentes/frontend-angular-swl.md +5 -11
- package/agentes/frontend-css-swl.md +5 -9
- package/agentes/frontend-react-swl.md +5 -9
- package/agentes/frontend-swl.md +5 -9
- package/agentes/frontend-tailwind-swl.md +5 -9
- package/agentes/implementador-swl.md +6 -3
- package/agentes/investigador-swl.md +5 -3
- package/agentes/investigador-ux-swl.md +5 -9
- package/agentes/llm-apps-swl.md +5 -3
- package/agentes/migrador-swl.md +6 -3
- package/agentes/mobile-android-swl.md +5 -3
- package/agentes/mobile-cross-swl.md +5 -3
- package/agentes/mobile-ios-swl.md +5 -3
- package/agentes/mobile-testing-swl.md +5 -3
- package/agentes/notificador-swl.md +5 -3
- package/agentes/observabilidad-swl.md +5 -3
- package/agentes/orquestador-swl.md +29 -8
- package/agentes/pagos-swl.md +5 -3
- package/agentes/perfilador-usuario-swl.md +4 -2
- package/agentes/planificador-swl.md +5 -3
- package/agentes/producto-prd-swl.md +5 -3
- package/agentes/red-team-swl.md +4 -2
- package/agentes/release-manager-swl.md +6 -8
- package/agentes/rendimiento-swl.md +5 -6
- package/agentes/resolutor-build-swl.md +5 -3
- package/agentes/revisor-angular-swl.md +5 -3
- package/agentes/revisor-codigo-swl.md +5 -3
- package/agentes/revisor-csharp-swl.md +5 -3
- package/agentes/revisor-go-swl.md +5 -3
- package/agentes/revisor-java-swl.md +5 -3
- package/agentes/revisor-kotlin-swl.md +5 -3
- package/agentes/revisor-nextjs-swl.md +5 -3
- package/agentes/revisor-php-swl.md +5 -3
- package/agentes/revisor-react-swl.md +5 -3
- package/agentes/revisor-rust-swl.md +5 -3
- package/agentes/revisor-seguridad-swl.md +5 -3
- package/agentes/revisor-swift-swl.md +5 -3
- package/agentes/revisor-typescript-swl.md +5 -3
- package/agentes/sre-swl.md +5 -3
- package/agentes/tdd-qa-swl.md +5 -3
- package/agentes/ux-disenador-swl.md +5 -9
- package/bin/swl-ses.js +27 -6
- package/comandos/swl/evaluar-skill.md +18 -0
- package/comandos/swl/evolucion-estado.md +49 -0
- package/comandos/swl/release.md +41 -0
- package/comandos/swl/salud.md +23 -0
- package/hooks/auto-evolucion.js +35 -1
- package/hooks/clasificador-mensajes.js +50 -3
- package/hooks/lib/agent-routing.js +107 -0
- package/hooks/lib/delegation-tracker.js +162 -44
- package/hooks/lib/evolution-tracker.js +12 -3
- package/hooks/lib/memory-search.js +59 -1
- package/hooks/lib/nudge-tracker.js +10 -1
- package/hooks/lib/provenance-tracker.js +11 -3
- package/hooks/lib/text-similarity.js +241 -0
- package/hooks/metricas-evolucion.js +168 -1
- package/hooks/monitor-contexto.js +54 -6
- package/hooks/preservar-estado-pre-compact.js +11 -1
- package/hooks/risk-scoring.js +10 -1
- package/hooks/tracking-costos.js +10 -1
- package/hooks/validar-formato-post-subagente.js +140 -0
- package/hooks/validar-memoria-hook.js +218 -0
- package/manifiestos/agent-output-schemas.json +57 -0
- package/manifiestos/hooks-config.json +18 -0
- package/manifiestos/modulos.json +5 -1
- package/manifiestos/skills-lock.json +1065 -0
- package/package.json +4 -6
- package/plugin.json +1 -1
- package/reglas/arquitectura.md +20 -0
- package/reglas/fragmentos-compartidos.md +152 -0
- package/reglas/gobernanza.md +10 -1
- package/reglas/seguridad-agentes.md +12 -0
- package/reglas/skills-estandar.md +19 -0
- package/reglas/usar-context7.md +226 -0
- package/schemas/agent-frontmatter.schema.json +18 -0
- package/scripts/auditar-agentes-gaps.js +9 -1
- package/scripts/auditar-cobertura-frameworks.js +9 -1
- package/scripts/auditar-skills-gaps.js +9 -1
- package/scripts/bootstrap-instintos.js +11 -1
- package/scripts/generar-inventario.js +112 -9
- package/scripts/generar-matriz-lenguajes.js +271 -0
- package/scripts/generar-skills-lock.js +190 -0
- package/scripts/lib/estado.js +12 -2
- package/scripts/lib/gitignore-manifest.js +32 -2
- package/scripts/lib/semantic-search.js +10 -0
- package/scripts/migrar-csv-a-array.js +168 -0
- package/scripts/migrar-fase-dominio.js +201 -0
- package/scripts/validar-userland-vacio.js +110 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saulwade/swl-ses",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Sistema de ingenieria de software auto-evolutivo multi-runtime polyglot con 59 agentes, 151 habilidades, 42 comandos, 60 reglas y 37 hooks. Soporta 11 lenguajes y 5 runtimes: Claude Code, Copilot, OpenCode, Codex y Gemini CLI. 100% en espanol (Mexico). Incluye gateway bidireccional con relay Telegram a Claude Code.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"swl-ses": "bin/swl-ses.js",
|
|
@@ -31,9 +31,10 @@
|
|
|
31
31
|
"test:smoke": "node scripts/smoke-test.js",
|
|
32
32
|
"test:aislamiento": "node scripts/validar-tests-aislamiento.js",
|
|
33
33
|
"test:all": "npm test && node scripts/validar.js && node scripts/validar-manifest.js",
|
|
34
|
-
"test:
|
|
34
|
+
"test:userland": "node scripts/validar-userland-vacio.js",
|
|
35
|
+
"test:release": "npm run test:all && npm run test:userland && npm run test:smoke",
|
|
35
36
|
"doctor": "node scripts/doctor.js",
|
|
36
|
-
"prepack": "node scripts/limpiar-artefactos-python.js",
|
|
37
|
+
"prepack": "node scripts/limpiar-artefactos-python.js && node scripts/validar-userland-vacio.js",
|
|
37
38
|
"prepublishOnly": "npm run test:release",
|
|
38
39
|
"publish:all": "node scripts/publicar.js",
|
|
39
40
|
"publish:github": "node scripts/publicar.js --solo-github",
|
|
@@ -76,9 +77,6 @@
|
|
|
76
77
|
"dependencies": {
|
|
77
78
|
"docx": "^9.6.1"
|
|
78
79
|
},
|
|
79
|
-
"optionalDependencies": {
|
|
80
|
-
"@xenova/transformers": "^2.17.2"
|
|
81
|
-
},
|
|
82
80
|
"overrides": {
|
|
83
81
|
"pako": "^2.1.0",
|
|
84
82
|
"readable-stream": "^4.7.0"
|
package/plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swl-ses",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Sistema de ingenieria de software auto-evolutivo multi-runtime polyglot. 59 agentes, 151 habilidades, 42 comandos, 60 reglas y 37 hooks. 60 librerias. 11 lenguajes. Soporta Claude Code, Copilot, OpenCode, Codex y Gemini CLI.",
|
|
5
5
|
"author": "Saul Wade Leon",
|
|
6
6
|
"license": "MIT",
|
package/reglas/arquitectura.md
CHANGED
|
@@ -214,6 +214,26 @@ de abstracciones (protocolos, interfaces, clases abstractas).
|
|
|
214
214
|
|
|
215
215
|
---
|
|
216
216
|
|
|
217
|
+
## Tres capas de reutilización: regla, skill, fragmento
|
|
218
|
+
|
|
219
|
+
El sistema SWL distingue tres capas para evitar duplicación. La elección de la
|
|
220
|
+
capa correcta depende de cuándo y cómo se carga el contenido:
|
|
221
|
+
|
|
222
|
+
- **Regla** (`reglas/X.md`): política global cargada por matcher de archivos.
|
|
223
|
+
Aplicable a múltiples agentes y skills. Ejemplo: `reglas/seguridad.md`.
|
|
224
|
+
- **Skill** (`habilidades/X/SKILL.md`): conocimiento operacional invocado
|
|
225
|
+
dinámicamente con `Skill("X")`. Tiene frontmatter, descripción y carga
|
|
226
|
+
bajo demanda. Ejemplo: `habilidades/tdd-workflow/SKILL.md`.
|
|
227
|
+
- **Fragmento** (`agentes/_X.md`): bloque de prompt compartido por varios
|
|
228
|
+
agentes que se incrusta literalmente en su system prompt. Sin overhead
|
|
229
|
+
runtime, sin frontmatter operacional, no routable por el orquestador.
|
|
230
|
+
Ejemplo: `agentes/_hitl-alto-riesgo.md`.
|
|
231
|
+
|
|
232
|
+
Antes de crear texto compartido entre agentes, decidir cuál capa aplica. Ver
|
|
233
|
+
`reglas/fragmentos-compartidos.md` para la convención completa.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
217
237
|
## DRY — Don't Repeat Yourself
|
|
218
238
|
|
|
219
239
|
Si una regla de negocio, una validación, un cálculo o una transformación cambia,
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Regla: Fragmentos compartidos no-routables
|
|
2
|
+
|
|
3
|
+
Esta regla es **OBLIGATORIA** para autores y mantenedores de agentes y reglas
|
|
4
|
+
del sistema SWL. Define un tercer tier entre reglas y skills: bloques de prompt
|
|
5
|
+
compartidos que se incrustan literalmente en agentes/reglas para eliminar
|
|
6
|
+
duplicación textual sin convertirse en componentes invocables.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## El problema que resuelve
|
|
11
|
+
|
|
12
|
+
Hoy cuando dos agentes necesitan repetir el mismo párrafo (protocolo HITL para
|
|
13
|
+
nivelRiesgo ALTO, anti-fallback silencioso, regla de paralelización, mención
|
|
14
|
+
de "aplica brevedad-output"), las opciones existentes son:
|
|
15
|
+
|
|
16
|
+
| Mecanismo | Problema |
|
|
17
|
+
|-----------|----------|
|
|
18
|
+
| Copiar y pegar el bloque | Drift textual: una copia se actualiza, la otra no. |
|
|
19
|
+
| Convertirlo en regla obligatoria | Las reglas son globales (cargadas por matchers), no se incrustan literal en un agente concreto. |
|
|
20
|
+
| Convertirlo en skill | Las skills se invocan dinámicamente con `Skill("nombre")` y consumen tokens; un fragmento de 6 líneas no justifica el overhead. |
|
|
21
|
+
| Convertirlo en agente | Los agentes son routables; un guard compartido no debe aparecer en la tabla de routing del orquestador. |
|
|
22
|
+
|
|
23
|
+
Faltaba una capa para "texto compartido que vive en el system prompt del agente,
|
|
24
|
+
sin overhead runtime ni routing". Esta regla la formaliza.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Convención
|
|
29
|
+
|
|
30
|
+
### Ubicación y naming
|
|
31
|
+
|
|
32
|
+
| Tipo | Ubicación | Naming |
|
|
33
|
+
|------|-----------|--------|
|
|
34
|
+
| Fragmento para agentes | `agentes/_*.md` | prefijo `_`, kebab-case, **sin sufijo `-swl`** |
|
|
35
|
+
| Fragmento para reglas | `reglas/_fragmentos/_*.md` | prefijo `_`, kebab-case |
|
|
36
|
+
|
|
37
|
+
**Ejemplos válidos**:
|
|
38
|
+
- `agentes/_hitl-alto-riesgo.md`
|
|
39
|
+
- `agentes/_anti-fallback-silencioso.md`
|
|
40
|
+
- `agentes/_brevedad-output-ref.md`
|
|
41
|
+
- `reglas/_fragmentos/_descarga-progresiva.md`
|
|
42
|
+
|
|
43
|
+
**Ejemplos inválidos**:
|
|
44
|
+
- `agentes/_scope-guard-swl.md` (no usar sufijo `-swl` — no es un agente)
|
|
45
|
+
- `agentes/scope_guard.md` (snake_case prohibido)
|
|
46
|
+
- `agentes/_ScopeGuard.md` (camelCase prohibido)
|
|
47
|
+
|
|
48
|
+
### Reglas duras
|
|
49
|
+
|
|
50
|
+
1. **NO routable**: el orquestador NO incluye `agentes/_*.md` en su tabla de
|
|
51
|
+
rutas. El prefijo `_` señala al loader que ese archivo es un fragmento, no
|
|
52
|
+
un agente. La validación `scripts/validar-manifest.js` rechaza si un
|
|
53
|
+
`agentes/_*.md` aparece en `manifiestos/modulos.json` como agente.
|
|
54
|
+
|
|
55
|
+
2. **NO invocable**: no se carga con `Skill("...")`. No tiene frontmatter
|
|
56
|
+
`name`/`description` ni schema. Es texto puro Markdown.
|
|
57
|
+
|
|
58
|
+
3. **Importación declarativa via frontmatter**: el agente que usa el fragmento
|
|
59
|
+
lo declara en su frontmatter:
|
|
60
|
+
```yaml
|
|
61
|
+
fragmentos: [_hitl-alto-riesgo, _anti-fallback-silencioso]
|
|
62
|
+
```
|
|
63
|
+
El campo `fragmentos` está definido en `schemas/agent-frontmatter.schema.json`.
|
|
64
|
+
El loader (al cargar el agente) lee cada fragmento referenciado y lo concatena
|
|
65
|
+
al final del system prompt.
|
|
66
|
+
|
|
67
|
+
4. **Tamaño máximo 100 líneas**: si un fragmento crece más, probablemente debe
|
|
68
|
+
ser una regla obligatoria o una skill. Los fragmentos son párrafos, no
|
|
69
|
+
documentos.
|
|
70
|
+
|
|
71
|
+
5. **Sin frontmatter operacional**: el archivo `_*.md` puede tener un comentario
|
|
72
|
+
YAML opcional al inicio con metadata humana (autor, agentes que lo usan), pero
|
|
73
|
+
NO tiene campos como `nivelRiesgo` o `permisosRed` — los hereda del agente
|
|
74
|
+
que lo importa.
|
|
75
|
+
|
|
76
|
+
6. **Auditoría obligatoria**: cuando se crea un fragmento, el script
|
|
77
|
+
`scripts/validar-manifest.js` verifica que el fragmento es referenciado por
|
|
78
|
+
≥2 agentes. Un fragmento usado por un solo agente no justifica su existencia
|
|
79
|
+
y debe re-incrustarse en el agente.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Cuándo crear un fragmento
|
|
84
|
+
|
|
85
|
+
✅ Crear cuando:
|
|
86
|
+
- El mismo bloque de ≥3 líneas aparece literalmente en ≥3 agentes.
|
|
87
|
+
- El bloque es estructural (protocolo, regla operativa) — no contenido de
|
|
88
|
+
dominio variable.
|
|
89
|
+
- Cambiar el bloque en el futuro debe propagarse a todos los agentes.
|
|
90
|
+
|
|
91
|
+
❌ NO crear cuando:
|
|
92
|
+
- El texto solo aparece en 1-2 agentes (no hay ahorro real).
|
|
93
|
+
- El bloque ya existe como regla obligatoria (cargada por matcher).
|
|
94
|
+
- El comportamiento se invoca dinámicamente (eso es una skill).
|
|
95
|
+
- Es un párrafo de menos de 80 caracteres (no justifica el overhead de gestión).
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Diferencia con reglas y skills
|
|
100
|
+
|
|
101
|
+
| Capa | Cuándo carga | Cómo se usa | Ejemplo |
|
|
102
|
+
|------|-------------|-------------|---------|
|
|
103
|
+
| **Regla** (`reglas/X.md`) | Por matcher cuando se tocan ciertos archivos | Cargada al contexto global de la sesión | `reglas/seguridad.md` aplica a `*.py`, `auth/`, etc. |
|
|
104
|
+
| **Skill** (`habilidades/X/SKILL.md`) | Cuando un agente invoca `Skill("X")` | Carga bajo demanda, contiene instrucciones operativas | `habilidades/tdd-workflow/SKILL.md` |
|
|
105
|
+
| **Fragmento** (`agentes/_X.md`) | Al cargar un agente que lo declara en `fragmentos` | Se incrusta literalmente en system prompt — sin overhead runtime | `agentes/_hitl-alto-riesgo.md` |
|
|
106
|
+
|
|
107
|
+
Los fragmentos son la opción más barata: cero tokens runtime adicional, máxima
|
|
108
|
+
consistencia textual entre agentes que comparten un bloque.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Migración desde duplicación existente
|
|
113
|
+
|
|
114
|
+
Para extraer un bloque duplicado a fragmento:
|
|
115
|
+
|
|
116
|
+
1. **Identificar**: con `Grep` confirmar que el texto aparece literal en ≥3 agentes.
|
|
117
|
+
2. **Crear** el archivo `agentes/_nombre.md` con el bloque en el estado más
|
|
118
|
+
reciente/completo de las copias existentes.
|
|
119
|
+
3. **Reemplazar** en cada agente la duplicación por una referencia mínima:
|
|
120
|
+
```markdown
|
|
121
|
+
<!-- fragmento: _nombre -->
|
|
122
|
+
```
|
|
123
|
+
El loader sustituye este marcador por el contenido del fragmento al cargar.
|
|
124
|
+
4. **Declarar** en el frontmatter del agente:
|
|
125
|
+
```yaml
|
|
126
|
+
fragmentos: [_nombre]
|
|
127
|
+
```
|
|
128
|
+
5. **Verificar** con `node scripts/validar-manifest.js` que el fragmento está
|
|
129
|
+
referenciado por ≥2 agentes.
|
|
130
|
+
6. **Commit atómico**: `refactor(fragmentos): extraer X a _nombre — usado en N agentes`.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Origen y referencias
|
|
135
|
+
|
|
136
|
+
- Patrón inspirado en `_scope-guard.md` de Bug-Bounty-Agents
|
|
137
|
+
(https://github.com/anthropics/bug-bounty-agents) — convención `_` como
|
|
138
|
+
shared prompt block no-routable.
|
|
139
|
+
- Decisión documentada en ADR-XXX (ver `.planning/adrs/`).
|
|
140
|
+
- Schema: `schemas/agent-frontmatter.schema.json` campo `fragmentos`.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Checklist antes de crear un fragmento
|
|
145
|
+
|
|
146
|
+
- [ ] El texto aparece literal en ≥3 agentes
|
|
147
|
+
- [ ] El nombre sigue convención `_kebab-case.md` (sin sufijo `-swl`)
|
|
148
|
+
- [ ] Tamaño ≤100 líneas
|
|
149
|
+
- [ ] No reemplaza a una regla obligatoria existente
|
|
150
|
+
- [ ] No es contenido invocable dinámicamente (eso es skill)
|
|
151
|
+
- [ ] Cada agente que lo usa lo declara en `fragmentos: [...]`
|
|
152
|
+
- [ ] `scripts/validar-manifest.js` no reporta errores
|
package/reglas/gobernanza.md
CHANGED
|
@@ -32,7 +32,16 @@ Los skills generados por `auto-evolucion-swl` o `/swl:evolucionar`:
|
|
|
32
32
|
- Requieren validación en al menos 3 sesiones de trabajo independientes
|
|
33
33
|
antes de ser promovidos al perfil `completo`.
|
|
34
34
|
- Deben pasar la verificación de `/swl:salud` sin degradar el score actual.
|
|
35
|
-
-
|
|
35
|
+
- **Gate G8 — evidencia de calidad obligatoria**: antes de mover un skill
|
|
36
|
+
desde `_userland/plugins/` a `habilidades/`, ejecutar
|
|
37
|
+
`/swl:evaluar-skill <nombre>` y exigir badge ≥ **Plata** (score ≥ 70).
|
|
38
|
+
Skills con Bronce o sin badge se devuelven a `_userland/` con feedback
|
|
39
|
+
de qué dimensiones bajan el score. Detalle del flujo en
|
|
40
|
+
`agentes/auto-evolucion-swl.md` sección "Gate G8". Origen ADR 0013
|
|
41
|
+
sección 3C.
|
|
42
|
+
- La promoción se registra en `.planning/AUDITORIA.md` con justificación
|
|
43
|
+
Y en `.planning/evolucion/evoluciones.jsonl` con evento
|
|
44
|
+
`tipo: "promocion-skill"` y `score`.
|
|
36
45
|
|
|
37
46
|
### Reglas nuevas obligatorias
|
|
38
47
|
|
|
@@ -34,6 +34,18 @@ Cada agente recibe exclusivamente los permisos que necesita para su función.
|
|
|
34
34
|
- Un agente sin `permisosComandos` no debe ejecutar Bash bajo ninguna circunstancia.
|
|
35
35
|
- El `toolBudget` limita la cantidad de herramientas por invocación. Agentes
|
|
36
36
|
con presupuesto `simple` (1-3 tools) no deben recibir tareas que requieran más.
|
|
37
|
+
- El `maxTurnos` (definido en `schemas/agent-frontmatter.schema.json`) declara
|
|
38
|
+
el tope explícito de iteraciones (tool calls) que el agente puede ejecutar
|
|
39
|
+
antes de pausar y escalar. **OBLIGATORIO** declararlo en frontmatter para
|
|
40
|
+
agentes con patrón evaluator-optimizer, recovery catalog, debugging
|
|
41
|
+
iterativo, o cualquier loop autónomo. Valores recomendados según patrón
|
|
42
|
+
observado: thin orchestrator/QA lineal: 10; debugging iterativo: 12;
|
|
43
|
+
implementación con write-complete-test-once: 15; release multi-fase: 18;
|
|
44
|
+
auto-evolución con gates G1-G8: 20; migración expand-contract: 25.
|
|
45
|
+
Agentes one-shot (revisores, documentadores, diseñadores) NO requieren
|
|
46
|
+
`maxTurnos` — son no-iterativos por diseño. Patrón inspirado en *Building
|
|
47
|
+
Effective AI Agents* (Anthropic, p.10) — "stopping conditions, maximum
|
|
48
|
+
number of iterations".
|
|
37
49
|
|
|
38
50
|
### Anti-escalación en cadenas de delegación
|
|
39
51
|
|
|
@@ -239,6 +239,25 @@ CLAUDE.md el orquestador no sabe que existe.
|
|
|
239
239
|
|
|
240
240
|
---
|
|
241
241
|
|
|
242
|
+
## Diferencia con fragmentos compartidos
|
|
243
|
+
|
|
244
|
+
Las skills NO son la única capa de reutilización del sistema SWL. Existen tres
|
|
245
|
+
capas distintas — cada una con su propósito:
|
|
246
|
+
|
|
247
|
+
| Capa | Cuándo usar | Cómo se carga |
|
|
248
|
+
|------|-------------|---------------|
|
|
249
|
+
| **Regla** (`reglas/X.md`) | Política transversal aplicable por matcher de archivos | Carga global cuando el matcher se cumple |
|
|
250
|
+
| **Skill** (`habilidades/X/SKILL.md`) | Conocimiento operacional invocable bajo demanda | Carga al invocar `Skill("X")` |
|
|
251
|
+
| **Fragmento** (`agentes/_X.md`) | Bloque de texto compartido por ≥3 agentes en su system prompt | Se incrusta literalmente al cargar el agente — sin overhead runtime |
|
|
252
|
+
|
|
253
|
+
NO crear una skill cuando el contenido es:
|
|
254
|
+
- Texto compartido entre múltiples agentes que no se invoca dinámicamente → es fragmento.
|
|
255
|
+
- Política aplicable a archivos del codebase → es regla.
|
|
256
|
+
|
|
257
|
+
Ver `reglas/fragmentos-compartidos.md` para la convención completa de fragmentos.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
242
261
|
## Convención de naming para skills nuevos
|
|
243
262
|
|
|
244
263
|
Todo skill nuevo DEBE usar prefijo de dominio. Facilita agrupación lógica sin
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# Regla: Consultar Context7 antes de generar código con dependencias externas
|
|
2
|
+
|
|
3
|
+
Esta regla es OBLIGATORIA para todo agente o skill del sistema SWL que
|
|
4
|
+
genere código que use librerías, frameworks, SDKs o APIs externas. La regla
|
|
5
|
+
se carga automáticamente para los agentes de stack (`backend-*-swl`,
|
|
6
|
+
`frontend-*-swl`, `mobile-*-swl`, `implementador-swl`, `llm-apps-swl`,
|
|
7
|
+
`pagos-swl`, `datos-swl`) y para skills de implementación.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Por qué existe esta regla
|
|
12
|
+
|
|
13
|
+
El conocimiento del modelo sobre librerías de terceros tiene fecha de
|
|
14
|
+
corte. Una librería que en el corte estaba en la versión X y era la
|
|
15
|
+
recomendación, hoy puede estar:
|
|
16
|
+
|
|
17
|
+
- En una versión Y mayor con cambios incompatibles
|
|
18
|
+
- Deprecada y reemplazada por otra librería
|
|
19
|
+
- Con vulnerabilidades conocidas que requieren un parche
|
|
20
|
+
- Renombrada o migrada a otra organización
|
|
21
|
+
|
|
22
|
+
Generar código sin verificar la versión actual genera tres clases de
|
|
23
|
+
defectos en producción:
|
|
24
|
+
|
|
25
|
+
1. **Imports a APIs deprecadas** que arrastran warnings o se eliminan
|
|
26
|
+
en próximas versiones (ejemplo histórico: `@xenova/transformers`
|
|
27
|
+
migrado a `@huggingface/transformers`).
|
|
28
|
+
2. **Dependencias transitivas obsoletas** que el usuario ve como
|
|
29
|
+
warnings al instalar (ejemplo: `prebuild-install@7.1.3` arrastrada
|
|
30
|
+
por una librería que el sistema eligió sin verificar la salud).
|
|
31
|
+
3. **Vulnerabilidades CVE conocidas** que están parchadas en versiones
|
|
32
|
+
más nuevas que el modelo no conoce.
|
|
33
|
+
|
|
34
|
+
Context7 (MCP `mcp__claude_ai_Context7__query-docs` y
|
|
35
|
+
`mcp__claude_ai_Context7__resolve-library-id`) provee documentación
|
|
36
|
+
actualizada de librerías y frameworks. Su uso es la primera línea de
|
|
37
|
+
defensa contra estos tres problemas.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Cuándo consultar Context7 (OBLIGATORIO)
|
|
42
|
+
|
|
43
|
+
Antes de:
|
|
44
|
+
|
|
45
|
+
1. **Agregar una nueva dependencia** a `package.json`, `requirements.txt`,
|
|
46
|
+
`pom.xml`, `Cargo.toml`, `go.mod`, `composer.json`, `Package.swift` o
|
|
47
|
+
equivalente.
|
|
48
|
+
2. **Generar código que importe o use una librería externa** que no
|
|
49
|
+
estaba ya en uso en el proyecto, aunque la librería ya esté
|
|
50
|
+
instalada.
|
|
51
|
+
3. **Actualizar la versión** de una dependencia existente.
|
|
52
|
+
4. **Migrar de una librería a otra** alternativa (ej.
|
|
53
|
+
`axios` → `fetch`, `moment` → `date-fns`, `jest` → `vitest`).
|
|
54
|
+
5. **Resolver un warning de deprecación** de una dependencia
|
|
55
|
+
transitiva.
|
|
56
|
+
6. **Implementar un patrón nuevo** del framework (ej. Server Actions
|
|
57
|
+
en Next.js, Signals en Angular, Suspense en React) — la API
|
|
58
|
+
correcta cambia rápido.
|
|
59
|
+
|
|
60
|
+
NO es necesario consultar Context7 cuando:
|
|
61
|
+
|
|
62
|
+
- La librería es interna al proyecto SWL (`scripts/lib/*`,
|
|
63
|
+
`hooks/lib/*`).
|
|
64
|
+
- Es la biblioteca estándar del lenguaje (Node `fs`, Python `os`).
|
|
65
|
+
- Es código que no usa dependencias externas (algoritmos, lógica de
|
|
66
|
+
negocio sin librerías de terceros).
|
|
67
|
+
- El cambio es trivial (renombrar variable, formatear).
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Cómo consultar Context7
|
|
72
|
+
|
|
73
|
+
El MCP de Context7 expone dos herramientas principales:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
mcp__claude_ai_Context7__resolve-library-id(libraryName)
|
|
77
|
+
→ Resuelve un nombre de librería (ej. "react", "next.js") al ID
|
|
78
|
+
canónico que Context7 usa internamente.
|
|
79
|
+
|
|
80
|
+
mcp__claude_ai_Context7__query-docs(library, topic, version?)
|
|
81
|
+
→ Devuelve documentación actualizada de la librería sobre el
|
|
82
|
+
topic específico. Acepta versión opcional.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Flujo típico:
|
|
86
|
+
|
|
87
|
+
1. Resolver el ID de la librería:
|
|
88
|
+
```
|
|
89
|
+
const id = mcp__claude_ai_Context7__resolve-library-id({
|
|
90
|
+
libraryName: "next.js"
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
2. Consultar el tema específico:
|
|
95
|
+
```
|
|
96
|
+
const docs = mcp__claude_ai_Context7__query-docs({
|
|
97
|
+
library: id,
|
|
98
|
+
topic: "Server Actions",
|
|
99
|
+
version: "16"
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
3. Verificar:
|
|
104
|
+
- ¿La librería sigue siendo la recomendada o está deprecada?
|
|
105
|
+
- ¿Hay una alternativa migrada que deberíamos usar?
|
|
106
|
+
- ¿La API que voy a generar es la actual o cambió?
|
|
107
|
+
- ¿La versión que recomienda Context7 coincide con la del
|
|
108
|
+
`package.json` del proyecto?
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Reglas estrictas
|
|
113
|
+
|
|
114
|
+
### NUNCA agregar dependencia sin verificar
|
|
115
|
+
|
|
116
|
+
Antes de escribir `npm install <paquete>`, `pip install <paquete>`,
|
|
117
|
+
`go get <paquete>` o equivalente:
|
|
118
|
+
|
|
119
|
+
- Consultar Context7 para confirmar que la librería sigue activa.
|
|
120
|
+
- Confirmar la versión más reciente compatible con el resto del
|
|
121
|
+
stack del proyecto.
|
|
122
|
+
- Si Context7 reporta deprecación, **NO la uses**. Buscar la
|
|
123
|
+
alternativa migrada.
|
|
124
|
+
|
|
125
|
+
### NUNCA generar código con API obsoleta
|
|
126
|
+
|
|
127
|
+
Si el usuario pide implementar X usando librería Y:
|
|
128
|
+
|
|
129
|
+
- Consultar Context7 sobre cómo se hace X en la versión actual de Y.
|
|
130
|
+
- Si la API que aparece en el contexto del modelo difiere de la que
|
|
131
|
+
Context7 reporta como actual, **usar la de Context7**.
|
|
132
|
+
- Documentar en un comentario corto la versión consultada y la
|
|
133
|
+
fecha si la API es notable.
|
|
134
|
+
|
|
135
|
+
### NUNCA copiar ejemplos de la web sin verificar versión
|
|
136
|
+
|
|
137
|
+
Stack Overflow, blogs y tutoriales tienen alta probabilidad de
|
|
138
|
+
mostrar código deprecado. Si el agente consulta una web (vía
|
|
139
|
+
WebSearch o WebFetch) y obtiene un ejemplo, ese ejemplo debe
|
|
140
|
+
validarse contra Context7 antes de incorporarlo.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Excepción: Context7 no responde o no tiene la librería
|
|
145
|
+
|
|
146
|
+
Si Context7 no tiene documentación disponible para una librería
|
|
147
|
+
específica:
|
|
148
|
+
|
|
149
|
+
1. **Documentar en el código** que Context7 no respondió y la API se
|
|
150
|
+
tomó de la fuente oficial (npm registry, docs del repo).
|
|
151
|
+
2. **Verificar al menos**: la librería existe, no está deprecada en
|
|
152
|
+
npm/PyPI, su última publicación es reciente (≤ 12 meses).
|
|
153
|
+
3. **NO bloquear** el flujo del usuario por este caso — proceder con
|
|
154
|
+
diligencia razonable.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Auditoría retroactiva
|
|
159
|
+
|
|
160
|
+
Esta regla aplica también al código existente del proyecto SWL:
|
|
161
|
+
|
|
162
|
+
- Si durante un refactor se detecta una dependencia que arrastra
|
|
163
|
+
warnings de deprecación, abrir un ticket para auditarla con
|
|
164
|
+
Context7 y migrar si hay alternativa actual.
|
|
165
|
+
- El comando `/swl:auditar-deps` (cuando esté disponible) debe
|
|
166
|
+
cruzar las dependencias del proyecto contra Context7 para
|
|
167
|
+
detectar deprecaciones silenciosas.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Aplicabilidad por agente
|
|
172
|
+
|
|
173
|
+
| Agente | Aplica | Cuándo |
|
|
174
|
+
|---|---|---|
|
|
175
|
+
| `backend-python-swl` | SÍ | Al generar código FastAPI/Django/SQLAlchemy |
|
|
176
|
+
| `backend-node-swl` | SÍ | Al generar código Express/Fastify/NestJS |
|
|
177
|
+
| `backend-java-swl` | SÍ | Al generar código Spring Boot/JPA |
|
|
178
|
+
| `backend-go-swl` | SÍ | Al generar código Go con frameworks |
|
|
179
|
+
| `backend-rust-swl` | SÍ | Al generar código Axum/Actix |
|
|
180
|
+
| `backend-csharp-swl` | SÍ | Al generar código ASP.NET Core |
|
|
181
|
+
| `frontend-react-swl` | SÍ | Al generar código React/Next.js |
|
|
182
|
+
| `frontend-angular-swl` | SÍ | Al generar código Angular |
|
|
183
|
+
| `frontend-css-swl` | SÍ | Al usar PostCSS/Tailwind plugins |
|
|
184
|
+
| `frontend-tailwind-swl` | SÍ | Al usar Tailwind v4+ APIs |
|
|
185
|
+
| `frontend-swl` | SÍ | Al usar Vue/Svelte/Lit |
|
|
186
|
+
| `mobile-android-swl` | SÍ | Al usar Jetpack Compose libs |
|
|
187
|
+
| `mobile-ios-swl` | SÍ | Al usar SwiftUI/Combine |
|
|
188
|
+
| `mobile-cross-swl` | SÍ | Al usar React Native/Flutter |
|
|
189
|
+
| `implementador-swl` | SÍ | Generalista — siempre |
|
|
190
|
+
| `llm-apps-swl` | SÍ | LangChain, OpenAI SDK, Anthropic SDK |
|
|
191
|
+
| `pagos-swl` | SÍ | Stripe SDK actualizado |
|
|
192
|
+
| `datos-swl` | SÍ | ORMs y drivers de BD |
|
|
193
|
+
| `arquitecto-swl` | RECOMENDADO | Al evaluar tradeoffs entre librerías |
|
|
194
|
+
| `revisor-codigo-swl` | RECOMENDADO | Al detectar deps deprecadas en review |
|
|
195
|
+
| `revisor-seguridad-swl` | OBLIGATORIO | Al verificar CVEs de dependencias |
|
|
196
|
+
| Resto de agentes | NO | No generan código con dependencias externas |
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Checklist de consulta Context7
|
|
201
|
+
|
|
202
|
+
Antes de marcar una tarea como completa:
|
|
203
|
+
|
|
204
|
+
- [ ] ¿Las dependencias agregadas/usadas se verificaron contra Context7?
|
|
205
|
+
- [ ] ¿La versión usada está alineada con la que Context7 reporta como actual?
|
|
206
|
+
- [ ] ¿No hay imports de APIs deprecadas según Context7?
|
|
207
|
+
- [ ] ¿Las dependencias transitivas conocidas no son warnings de
|
|
208
|
+
deprecación al instalar?
|
|
209
|
+
- [ ] Si Context7 no tenía la librería, ¿se documentó el motivo?
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Origen de esta regla
|
|
214
|
+
|
|
215
|
+
Esta regla se formalizó tras observar en la primera instalación pública
|
|
216
|
+
de `@saulwade/swl-ses@1.0.0` (2026-04-30) un warning de
|
|
217
|
+
`prebuild-install@7.1.3 deprecated` arrastrado por
|
|
218
|
+
`@xenova/transformers` que estaba en `optionalDependencies`. La
|
|
219
|
+
dependencia se eligió en una iteración anterior sin verificar Context7;
|
|
220
|
+
la migración oficial era `@huggingface/transformers`. El warning se vio
|
|
221
|
+
en cada `npm install` del paquete distribuido. Resuelto en v1.0.1
|
|
222
|
+
eliminando la dependencia opcional y elevando esta regla a obligatoria
|
|
223
|
+
para que no se repita.
|
|
224
|
+
|
|
225
|
+
Memoria asociada: `feedback_usar_context7.md` (preferencia previa del
|
|
226
|
+
usuario, formalizada como regla).
|
|
@@ -143,6 +143,24 @@
|
|
|
143
143
|
"type": "array",
|
|
144
144
|
"items": { "type": "string" },
|
|
145
145
|
"description": "Situaciones donde este agente NO debe invocarse aunque parezca relevante superficialmente. Campo propio de swl-ses; previene activacion tangencial (agent hijacking) por similitud de terminos en description. Equivalente estructural de la seccion 'Cuando NO invocarme' en el cuerpo, legible por herramientas de analisis sin parsear markdown. Aditivo, no breaking, aplicable a agentes con evolvable:false (metadata defensiva, no evolucion AGP — ver ADR-0004)."
|
|
146
|
+
},
|
|
147
|
+
"fase": {
|
|
148
|
+
"type": "string",
|
|
149
|
+
"enum": ["discover", "plan", "implement", "verify", "release", "learn", "meta", "cross"],
|
|
150
|
+
"description": "Fase del SDLC en que opera el agente. Vocabulario controlado para routing deterministico del orquestador sin parsear description. discover=research/UX/discovery; plan=arquitectura/planificacion; implement=codigo/implementacion; verify=revision/testing/seguridad; release=deploy/release; learn=auto-evolucion/aprendizaje; meta=componentes del sistema SWL mismo; cross=transversal a varias fases. Aditivo, opcional. Inspirado en patron Phase de Bug-Bounty-Agents/AGENTS.md y patron Workflow-vs-Agent del articulo Anthropic 'Building Effective AI Agents'."
|
|
151
|
+
},
|
|
152
|
+
"dominio": {
|
|
153
|
+
"type": "string",
|
|
154
|
+
"enum": ["backend", "frontend", "mobile", "data", "infra", "security", "ux", "quality", "docs", "process", "meta", "general"],
|
|
155
|
+
"description": "Dominio tecnico primario del agente. Vocabulario controlado para filtrado y matching. backend=APIs/servidores; frontend=UI/web; mobile=Android/iOS/cross; data=BD/ETL/datos; infra=cloud/CI/devops; security=auditoria/OWASP; ux=diseno/usabilidad; quality=tests/QA/code review; docs=documentacion; process=workflow/orquestacion; meta=sistema SWL; general=transversal. Aditivo, opcional."
|
|
156
|
+
},
|
|
157
|
+
"fragmentos": {
|
|
158
|
+
"type": "array",
|
|
159
|
+
"items": {
|
|
160
|
+
"type": "string",
|
|
161
|
+
"pattern": "^_[a-z][a-z0-9-]*$"
|
|
162
|
+
},
|
|
163
|
+
"description": "Lista de bloques de prompt compartidos no-routables (archivos agentes/_*.md) que este agente importa literalmente en su system prompt. Permite centralizar texto repetido entre multiples agentes sin duplicacion. Los fragmentos NO son skills (no se invocan dinamicamente) ni agentes (no son routables por el orquestador). Convencion: prefijo _ en kebab-case, sin sufijo -swl. Ejemplo: ['_brevedad-output-ref', '_hitl-alto-riesgo']. Inspirado en patron _scope-guard.md de Bug-Bounty-Agents."
|
|
146
164
|
}
|
|
147
165
|
},
|
|
148
166
|
"additionalProperties": true
|
|
@@ -24,6 +24,14 @@
|
|
|
24
24
|
var fs = require('fs');
|
|
25
25
|
var path = require('path');
|
|
26
26
|
|
|
27
|
+
// Escritura atómica obligatoria (regla CLAUDE.md). Fallback defensivo.
|
|
28
|
+
var atomicWriteJSON;
|
|
29
|
+
try {
|
|
30
|
+
atomicWriteJSON = require(path.join(__dirname, '..', 'hooks', 'lib', 'atomic-write.js')).atomicWriteJSON;
|
|
31
|
+
} catch (_) {
|
|
32
|
+
atomicWriteJSON = function (p, o) { fs.writeFileSync(p, JSON.stringify(o, null, 2), 'utf8'); };
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
var RAIZ_AGENTES = path.resolve(__dirname, '..', 'agentes');
|
|
28
36
|
var DESTINO_PLANNING = path.resolve(
|
|
29
37
|
__dirname, '..', '.planning', 'evolucion', 'audit-agentes-gaps.json'
|
|
@@ -140,7 +148,7 @@ if (argv.indexOf('--resumen') !== -1) {
|
|
|
140
148
|
} else if (argv.indexOf('--save') !== -1) {
|
|
141
149
|
var dir = path.dirname(DESTINO_PLANNING);
|
|
142
150
|
fs.mkdirSync(dir, { recursive: true });
|
|
143
|
-
|
|
151
|
+
atomicWriteJSON(DESTINO_PLANNING, resultado);
|
|
144
152
|
imprimirResumen(resultado);
|
|
145
153
|
process.stderr.write('Inventario persistido en: ' + DESTINO_PLANNING + '\n');
|
|
146
154
|
} else {
|
|
@@ -25,6 +25,14 @@
|
|
|
25
25
|
const fs = require('fs');
|
|
26
26
|
const path = require('path');
|
|
27
27
|
|
|
28
|
+
// Escritura atómica obligatoria (regla CLAUDE.md). Fallback defensivo.
|
|
29
|
+
let atomicWriteJSON;
|
|
30
|
+
try {
|
|
31
|
+
({ atomicWriteJSON } = require(path.join(__dirname, '..', 'hooks', 'lib', 'atomic-write.js')));
|
|
32
|
+
} catch {
|
|
33
|
+
atomicWriteJSON = (p, o) => fs.writeFileSync(p, JSON.stringify(o, null, 2), 'utf8');
|
|
34
|
+
}
|
|
35
|
+
|
|
28
36
|
const RAIZ_SKILLS = path.resolve(__dirname, '..', 'habilidades');
|
|
29
37
|
const DESTINO = path.resolve(
|
|
30
38
|
__dirname, '..', '.planning', 'evolucion', 'cobertura-frameworks.json'
|
|
@@ -232,7 +240,7 @@ if (argv.includes('--resumen')) {
|
|
|
232
240
|
} else if (argv.includes('--save')) {
|
|
233
241
|
const dir = path.dirname(DESTINO);
|
|
234
242
|
fs.mkdirSync(dir, { recursive: true });
|
|
235
|
-
|
|
243
|
+
atomicWriteJSON(DESTINO, resultado);
|
|
236
244
|
imprimirResumen(resultado);
|
|
237
245
|
process.stderr.write(`Inventario persistido en: ${DESTINO}\n`);
|
|
238
246
|
} else {
|
|
@@ -20,6 +20,14 @@
|
|
|
20
20
|
const fs = require('fs');
|
|
21
21
|
const path = require('path');
|
|
22
22
|
|
|
23
|
+
// Escritura atómica obligatoria (regla CLAUDE.md). Fallback defensivo.
|
|
24
|
+
let atomicWriteJSON;
|
|
25
|
+
try {
|
|
26
|
+
({ atomicWriteJSON } = require(path.join(__dirname, '..', 'hooks', 'lib', 'atomic-write.js')));
|
|
27
|
+
} catch {
|
|
28
|
+
atomicWriteJSON = (p, o) => fs.writeFileSync(p, JSON.stringify(o, null, 2), 'utf8');
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
const RAIZ_SKILLS = path.resolve(__dirname, '..', 'habilidades');
|
|
24
32
|
const DESTINO_PLANNING = path.resolve(
|
|
25
33
|
__dirname, '..', '.planning', 'evolucion', 'audit-skills-gaps.json'
|
|
@@ -197,7 +205,7 @@ if (argv.includes('--resumen')) {
|
|
|
197
205
|
} else if (argv.includes('--save')) {
|
|
198
206
|
const dir = path.dirname(DESTINO_PLANNING);
|
|
199
207
|
fs.mkdirSync(dir, { recursive: true });
|
|
200
|
-
|
|
208
|
+
atomicWriteJSON(DESTINO_PLANNING, resultado);
|
|
201
209
|
imprimirResumen(resultado);
|
|
202
210
|
process.stderr.write(`Inventario persistido en: ${DESTINO_PLANNING}\n`);
|
|
203
211
|
} else {
|
|
@@ -30,6 +30,16 @@ const CWD = process.cwd();
|
|
|
30
30
|
const APRENDIZAJES_PATH = path.join(CWD, '.planning', 'APRENDIZAJES.md');
|
|
31
31
|
const INSTINTOS_PATH = path.join(CWD, 'instintos', 'proyecto.yaml');
|
|
32
32
|
|
|
33
|
+
// Escritura atómica obligatoria — instintos/proyecto.yaml es el catálogo
|
|
34
|
+
// vivo de instintos del proyecto; corromperlo equivale a perder la memoria
|
|
35
|
+
// inductiva del sistema. Fallback defensivo si el módulo no está disponible.
|
|
36
|
+
let atomicWriteSync;
|
|
37
|
+
try {
|
|
38
|
+
({ atomicWriteSync } = require(path.join(CWD, 'hooks', 'lib', 'atomic-write.js')));
|
|
39
|
+
} catch {
|
|
40
|
+
atomicWriteSync = (p, c, e) => fs.writeFileSync(p, c, e);
|
|
41
|
+
}
|
|
42
|
+
|
|
33
43
|
const flags = {
|
|
34
44
|
write: process.argv.includes('--write'),
|
|
35
45
|
force: process.argv.includes('--force'),
|
|
@@ -250,7 +260,7 @@ function main() {
|
|
|
250
260
|
}
|
|
251
261
|
|
|
252
262
|
const yaml = serializarYaml(instintos);
|
|
253
|
-
|
|
263
|
+
atomicWriteSync(INSTINTOS_PATH, yaml, 'utf8');
|
|
254
264
|
console.log(`\nOK: ${instintos.length} instintos escritos en ${INSTINTOS_PATH}`);
|
|
255
265
|
}
|
|
256
266
|
|