@saulwade/swl-ses 1.8.0 → 2.0.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.
- package/CLAUDE.md +8 -8
- package/README.md +13 -13
- package/agentes/accesibilidad-wcag-swl.md +3 -3
- package/agentes/auto-evolucion-swl.md +908 -908
- package/agentes/disenador-ui-swl.md +6 -5
- package/agentes/frontend-angular-swl.md +2 -2
- package/agentes/frontend-css-swl.md +2 -2
- package/agentes/frontend-react-swl.md +4 -4
- package/agentes/frontend-swl.md +6 -6
- package/agentes/investigador-ux-swl.md +5 -5
- package/agentes/orquestador-swl.md +96 -8
- package/agentes/perfilador-usuario-swl.md +308 -308
- package/agentes/producto-prd-swl.md +1 -1
- package/agentes/red-team-swl.md +218 -218
- package/agentes/revisor-codigo-swl.md +34 -10
- package/agentes/revisor-seguridad-swl.md +7 -0
- package/agentes/tdd-qa-swl.md +39 -2
- package/comandos/swl/actualizar.md +1 -1
- package/comandos/swl/aprender.md +2 -2
- package/comandos/swl/aprobar-plan.md +152 -0
- package/comandos/swl/autoresearch.md +102 -6
- package/comandos/swl/ayuda.md +3 -3
- package/comandos/swl/discutir-fase.md +20 -2
- package/comandos/swl/ejecutar-fase.md +53 -6
- package/comandos/swl/evolucionar.md +1 -1
- package/comandos/swl/inbox.md +1 -1
- package/comandos/swl/instalar.md +1 -1
- package/comandos/swl/nemesis.md +42 -1
- package/comandos/swl/planear-fase.md +25 -1
- package/comandos/swl/plugins.md +1 -1
- package/comandos/swl/predecir.md +139 -0
- package/comandos/swl/release.md +1 -1
- package/comandos/swl/status.md +279 -0
- package/comandos/swl/verificar.md +75 -7
- package/habilidades/ai-runtime-security/SKILL.md +1 -1
- package/habilidades/angular-moderno/SKILL.md +44 -1
- package/habilidades/auto-evolucion-protocolo/SKILL.md +276 -276
- package/habilidades/autoresearch/SKILL.md +15 -1
- package/habilidades/benchmark-memoria/SKILL.md +1 -1
- package/habilidades/calidad-contract-testing/SKILL.md +165 -0
- package/habilidades/calidad-mutation-testing/SKILL.md +170 -0
- package/habilidades/changelog-generator/SKILL.md +9 -2
- package/habilidades/changelog-generator/scripts/parse-commits.js +12 -1
- package/habilidades/checklist-seguridad/SKILL.md +29 -1
- package/habilidades/checklist-seguridad/recursos/stride-cobertura.md +60 -0
- package/habilidades/css-moderno/SKILL.md +3 -1
- package/habilidades/diagrama-arquitectura/SKILL.md +1 -1
- package/habilidades/drift-detection/SKILL.md +179 -179
- package/habilidades/ejecutar-fase/SKILL.md +64 -14
- package/habilidades/estructura-proyecto-claude/SKILL.md +17 -14
- package/habilidades/estructura-proyecto-claude/recursos/configuracion-y-extensiones.md +34 -23
- package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +70 -53
- package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +57 -77
- package/habilidades/extractor-de-aprendizajes/SKILL.md +9 -5
- package/habilidades/fastapi-experto/SKILL.md +56 -5
- package/habilidades/harness-claude-code/SKILL.md +10 -7
- package/{reglas/harness-claude-code.md → habilidades/harness-claude-code/recursos/disciplina-harness-regla.md} +2 -2
- package/habilidades/instalar-sistema/SKILL.md +3 -3
- package/habilidades/meta-skills-estandar/recursos/frameworks-seguridad.md +1 -1
- package/habilidades/patrones-python/SKILL.md +8 -5
- package/habilidades/perfil-usuario/SKILL.md +200 -200
- package/habilidades/planear-fase/SKILL.md +25 -4
- package/habilidades/proceso-ddia-fundamentos/SKILL.md +1 -1
- package/habilidades/proceso-ddia-streaming/SKILL.md +4 -4
- package/habilidades/proceso-debate-adversarial/SKILL.md +164 -0
- package/habilidades/proceso-debate-adversarial/recursos/personas.md +105 -0
- package/habilidades/proceso-dynamic-workflows/SKILL.md +138 -0
- package/habilidades/proceso-dynamic-workflows/recursos/template-adversarial-verify.js +65 -0
- package/habilidades/proceso-dynamic-workflows/recursos/template-triage.js +65 -0
- package/habilidades/protocolo-revision-swl/SKILL.md +1 -1
- package/habilidades/seguridad-skills-ia/SKILL.md +1 -1
- package/habilidades/swl-claudemd/SKILL.md +50 -210
- package/habilidades/swl-claudemd/recursos/contrato-aprender.md +83 -0
- package/habilidades/swl-claudemd/recursos/duplicacion-reglas-globales.md +85 -0
- package/habilidades/swl-claudemd/recursos/plantillas-init.md +94 -0
- package/habilidades/swl-dashboard/SKILL.md +9 -9
- package/habilidades/swl-revisar-impacto/SKILL.md +1 -1
- package/habilidades/tdd-workflow/SKILL.md +58 -5
- package/habilidades/tdd-workflow/recursos/gherkin-bdd.md +111 -0
- package/habilidades/validacion-ci-sistema/SKILL.md +3 -3
- package/hooks/calidad-pre-commit.js +340 -3
- package/hooks/ciclo-evolucion-subagente.js +26 -0
- package/hooks/ciclo-evolucion.js +26 -0
- package/hooks/contexto-iteracion.js +144 -0
- package/hooks/extraccion-aprendizajes.js +13 -0
- package/hooks/lib/ciclo-evolucion.js +47 -0
- package/hooks/{auto-evolucion.js → lib/etapa-auto-evolucion.js} +701 -700
- package/hooks/{metricas-evolucion.js → lib/etapa-metricas.js} +388 -376
- package/hooks/{actualizar-perfil-usuario.js → lib/etapa-perfil-usuario.js} +376 -364
- package/hooks/lib/evolution-tracker.js +24 -3
- package/hooks/lib/loop-telemetry.js +321 -0
- package/hooks/notificacion-telegram.js +11 -3
- package/hooks/spec-gate.js +211 -0
- package/hooks/tdd-gate.js +241 -0
- package/hooks/validar-intent-spec.js +30 -10
- package/llms.txt +29 -0
- package/manifiestos/hooks-config.json +36 -18
- package/manifiestos/modulos.json +23 -14
- package/manifiestos/skills-lock.json +100 -72
- package/package.json +4 -3
- package/plugin.json +9 -10
- package/reglas/accesibilidad.md +10 -0
- package/reglas/api-diseno.md +9 -0
- package/reglas/arquitectura.evolved.json +7 -0
- package/reglas/arquitectura.md +65 -0
- package/reglas/auditorias-documentales-estructurales.md +7 -0
- package/reglas/cloud-infra.md +8 -0
- package/reglas/fragmentos-compartidos.md +5 -0
- package/reglas/gobernanza.md +4 -4
- package/reglas/hooks.md +6 -0
- package/reglas/intent-engineering.md +4 -0
- package/reglas/markitdown.md +8 -0
- package/reglas/memoria-consolidada.md +1 -1
- package/reglas/patrones.md +6 -0
- package/reglas/registro-componentes-nuevos.md +10 -1
- package/reglas/seguridad-agentes.md +1 -1
- package/reglas/seguridad.evolved.json +7 -0
- package/reglas/seguridad.md +144 -0
- package/reglas/skills-estandar.md +6 -0
- package/reglas/testing.md +7 -0
- package/reglas/tests-cleanup.md +4 -0
- package/reglas/usar-sistema-swl.md +1 -1
- package/scripts/generar-inventario.js +64 -1
- package/scripts/instalador.js +32 -2
- package/scripts/lib/gitignore-manifest.js +29 -1
- package/scripts/lib/plan-lock.js +275 -0
- package/scripts/migrar-fase-dominio.js +0 -1
- package/scripts/smoke-test.js +24 -2
- package/scripts/verificar-trazabilidad.js +292 -0
- package/agentes/ux-disenador-swl.md +0 -503
- package/comandos/swl/dashboard.md +0 -146
- package/comandos/swl/evolucion-estado.md +0 -191
- package/comandos/swl/metricas.md +0 -342
- package/comandos/swl/salud.md +0 -481
- package/reglas/verificar-citas-temporales.md +0 -139
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hook: tdd-gate.js (Gate G2 — TDD con evidencia RED)
|
|
6
|
+
* Tipo: PreToolUse (matcher: Bash)
|
|
7
|
+
*
|
|
8
|
+
* Ante un `git commit` de feature (código fuente + tests en el diff staged),
|
|
9
|
+
* verifica que exista evidencia de ciclo RED en la telemetría de loops
|
|
10
|
+
* (`iteraciones.tsv` dentro de `.planning/loops/tdd-…`, escrita por
|
|
11
|
+
* ejecutar-fase / tdd-workflow). Cierra F-TDD-6 de la Revisión Evolutiva 03:
|
|
12
|
+
* "TDD declarativo sin evidencia — el RED no deja rastro".
|
|
13
|
+
*
|
|
14
|
+
* Modo actual: WARN-ONLY (ADR-0035, decisión D-07 de 10-CONTEXTO.md).
|
|
15
|
+
* - Emite nudge `kind: tdd-red-evidence`; NUNCA exit 2 en este modo.
|
|
16
|
+
*
|
|
17
|
+
* Alcance deliberado (sin doble nudge ni falsos dominios):
|
|
18
|
+
* - Solo aplica con FASE ACTIVA (`.planning/locks/fase-activa.json`) — el
|
|
19
|
+
* enforcement TDD es parte del ciclo GSD, no de commits sueltos.
|
|
20
|
+
* - Solo cuando el diff staged toca fuente Y tests: el caso "fuente sin
|
|
21
|
+
* tests" es dominio del gate G3 (calidad-pre-commit) y ya tiene nudge.
|
|
22
|
+
* - Respeta el opt-out declarado del CONTEXTO (`**TDD**: off — razón: ...`).
|
|
23
|
+
* - Prefijos exentos: docs:/chore:/style: (mismos que G3).
|
|
24
|
+
*
|
|
25
|
+
* Evidencia RED válida: corrida `tdd-*` cuya `iteraciones.tsv` fue modificada
|
|
26
|
+
* dentro de la ventana (default 24h, `SWL_TDD_GATE_VENTANA_H`) con una fila
|
|
27
|
+
* de estado `baseline` con métrica > 0, o cuya descripción contenga "RED".
|
|
28
|
+
*
|
|
29
|
+
* Opt-out: SWL_TDD_GATE=0 desactiva completamente el hook.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
const fs = require('fs');
|
|
33
|
+
const path = require('path');
|
|
34
|
+
const { execFileSync } = require('child_process');
|
|
35
|
+
|
|
36
|
+
const VENTANA_HORAS_DEFAULT = 24;
|
|
37
|
+
|
|
38
|
+
/** ¿El comando es un git commit? (ignora git status/log/diff y comandos no-git) */
|
|
39
|
+
function esGitCommit(comando) {
|
|
40
|
+
if (typeof comando !== 'string') return false;
|
|
41
|
+
// Cinturón: un comando legítimo de commit no excede unos KB. Acotar evita
|
|
42
|
+
// costo lineal patológico del regex ante input gigante (hardening, no ReDoS).
|
|
43
|
+
if (comando.length > 10000) return false;
|
|
44
|
+
return /\bgit\b[^|&;]*\bcommit\b/.test(comando);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Lee el numero de fase activa y verifica el opt-out del CONTEXTO. */
|
|
48
|
+
function estadoTddDeFaseActiva(cwd) {
|
|
49
|
+
const rutaFaseActiva = path.join(cwd, '.planning', 'locks', 'fase-activa.json');
|
|
50
|
+
if (!fs.existsSync(rutaFaseActiva)) return { aplica: false, motivo: 'sin-fase-activa' };
|
|
51
|
+
|
|
52
|
+
let faseActiva;
|
|
53
|
+
try {
|
|
54
|
+
faseActiva = JSON.parse(fs.readFileSync(rutaFaseActiva, 'utf-8'));
|
|
55
|
+
} catch (_) {
|
|
56
|
+
return { aplica: false, motivo: 'fase-activa-corrupta' };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const numero = Number(faseActiva?.numero);
|
|
60
|
+
if (!Number.isFinite(numero)) return { aplica: false, motivo: 'fase-activa-sin-numero' };
|
|
61
|
+
|
|
62
|
+
const nn = String(numero).padStart(2, '0');
|
|
63
|
+
const contextoPath = path.join(cwd, '.planning', 'fases', `${nn}-CONTEXTO.md`);
|
|
64
|
+
if (fs.existsSync(contextoPath)) {
|
|
65
|
+
try {
|
|
66
|
+
const contexto = fs.readFileSync(contextoPath, 'utf-8');
|
|
67
|
+
if (/\*\*TDD\*\*:\s*off/i.test(contexto)) {
|
|
68
|
+
return { aplica: false, motivo: 'tdd-off-declarado' };
|
|
69
|
+
}
|
|
70
|
+
} catch (_) {
|
|
71
|
+
// CONTEXTO ilegible: asumir TDD on (default)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return { aplica: true, numero: nn };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Archivos staged del repo en cwd (lista vacía si no es repo o falla git). */
|
|
78
|
+
function archivosStaged(cwd) {
|
|
79
|
+
try {
|
|
80
|
+
const out = execFileSync('git', ['diff', '--cached', '--name-only'], {
|
|
81
|
+
cwd,
|
|
82
|
+
encoding: 'utf8',
|
|
83
|
+
timeout: 5000,
|
|
84
|
+
});
|
|
85
|
+
return out.split('\n').map((l) => l.trim()).filter(Boolean);
|
|
86
|
+
} catch (_) {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Busca evidencia RED en `.planning/loops/tdd-*` dentro de la ventana.
|
|
93
|
+
* @returns {boolean}
|
|
94
|
+
*/
|
|
95
|
+
function hayEvidenciaRed(cwd, ventanaHoras = VENTANA_HORAS_DEFAULT) {
|
|
96
|
+
const loopsDir = path.join(cwd, '.planning', 'loops');
|
|
97
|
+
if (!fs.existsSync(loopsDir)) return false;
|
|
98
|
+
|
|
99
|
+
let corridas;
|
|
100
|
+
try {
|
|
101
|
+
corridas = fs.readdirSync(loopsDir).filter((d) => d.startsWith('tdd-'));
|
|
102
|
+
} catch (_) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const limite = Date.now() - ventanaHoras * 3600 * 1000;
|
|
107
|
+
|
|
108
|
+
for (const corrida of corridas) {
|
|
109
|
+
const tsvPath = path.join(loopsDir, corrida, 'iteraciones.tsv');
|
|
110
|
+
let stat;
|
|
111
|
+
try {
|
|
112
|
+
stat = fs.statSync(tsvPath);
|
|
113
|
+
} catch (_) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (stat.mtimeMs < limite) continue;
|
|
117
|
+
|
|
118
|
+
let contenido;
|
|
119
|
+
try {
|
|
120
|
+
contenido = fs.readFileSync(tsvPath, 'utf-8');
|
|
121
|
+
} catch (_) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
for (const linea of contenido.split('\n')) {
|
|
126
|
+
if (linea.startsWith('#') || linea.startsWith('iteracion')) continue;
|
|
127
|
+
const cols = linea.split('\t');
|
|
128
|
+
if (cols.length < 6) continue;
|
|
129
|
+
const metrica = Number(cols[2]);
|
|
130
|
+
const estado = (cols[4] || '').trim();
|
|
131
|
+
const descripcion = cols[5] || '';
|
|
132
|
+
if ((estado === 'baseline' && metrica > 0) || /\bRED\b/.test(descripcion)) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Decide si el commit amerita advertencia G2.
|
|
142
|
+
* @returns {null | { fuentes: string[], tests: string[] }}
|
|
143
|
+
*/
|
|
144
|
+
function evaluarCommit({ cwd, comando, helpers }) {
|
|
145
|
+
if (!esGitCommit(comando)) return null;
|
|
146
|
+
|
|
147
|
+
const mensaje = helpers.extraerMensajeCommit(comando);
|
|
148
|
+
if (helpers.esPrefijoExentoDeTests(mensaje)) return null;
|
|
149
|
+
|
|
150
|
+
const fase = estadoTddDeFaseActiva(cwd);
|
|
151
|
+
if (!fase.aplica) return null;
|
|
152
|
+
|
|
153
|
+
const staged = archivosStaged(cwd);
|
|
154
|
+
const fuentes = staged.filter(helpers.esArchivoFuente);
|
|
155
|
+
const tests = staged.filter(helpers.esArchivoTest);
|
|
156
|
+
// Solo el caso feature-con-tests: "fuente sin tests" es dominio de G3.
|
|
157
|
+
if (fuentes.length === 0 || tests.length === 0) return null;
|
|
158
|
+
|
|
159
|
+
const ventana = Number(process.env.SWL_TDD_GATE_VENTANA_H) || VENTANA_HORAS_DEFAULT;
|
|
160
|
+
if (hayEvidenciaRed(cwd, ventana)) return null;
|
|
161
|
+
|
|
162
|
+
return { fuentes, tests };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function emitirNudge({ cwd, hallazgo }) {
|
|
166
|
+
let emit;
|
|
167
|
+
try {
|
|
168
|
+
({ emit } = require(path.join(__dirname, 'lib', 'nudge-tracker.js')));
|
|
169
|
+
} catch (_) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
const muestra = hallazgo.tests.slice(0, 2).join(', ');
|
|
174
|
+
emit({
|
|
175
|
+
kind: 'tdd-red-evidence',
|
|
176
|
+
target: hallazgo.tests[0],
|
|
177
|
+
source: 'hooks/tdd-gate.js',
|
|
178
|
+
message:
|
|
179
|
+
`Gate G2 (warn): commit de feature con tests (${muestra}) sin evidencia de ciclo ` +
|
|
180
|
+
`RED en .planning/loops/tdd-*/ — el TDD exige registrar el test fallando ANTES de ` +
|
|
181
|
+
`implementar (Skill("tdd-workflow") § Evidencia RED en telemetría). Este aviso ` +
|
|
182
|
+
`calibra la promoción a blocking (ADR-0035). Opt-out: SWL_TDD_GATE=0 o ` +
|
|
183
|
+
`'**TDD**: off — razón: ...' en el CONTEXTO de la fase.`,
|
|
184
|
+
data: { fuentes: hallazgo.fuentes, tests: hallazgo.tests, gate: 'G2' },
|
|
185
|
+
mutation_category: 'optimize',
|
|
186
|
+
risk_level: 'low',
|
|
187
|
+
});
|
|
188
|
+
} catch (_) {
|
|
189
|
+
// La observabilidad nunca bloquea el trabajo productivo.
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function main() {
|
|
194
|
+
if (process.env.SWL_TDD_GATE === '0') process.exit(0);
|
|
195
|
+
|
|
196
|
+
let hookInput = '';
|
|
197
|
+
try {
|
|
198
|
+
hookInput = fs.readFileSync(0, 'utf-8');
|
|
199
|
+
} catch (_) {
|
|
200
|
+
process.exit(0);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
let evento;
|
|
204
|
+
try {
|
|
205
|
+
evento = JSON.parse(hookInput);
|
|
206
|
+
} catch (_) {
|
|
207
|
+
process.exit(0);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (evento?.tool_name !== 'Bash') process.exit(0);
|
|
211
|
+
const comando = evento?.tool_input?.command;
|
|
212
|
+
const cwd = process.cwd();
|
|
213
|
+
|
|
214
|
+
// Zero-config: sin .planning/ no hay ciclo GSD que vigilar.
|
|
215
|
+
if (!fs.existsSync(path.join(cwd, '.planning'))) process.exit(0);
|
|
216
|
+
|
|
217
|
+
let helpers;
|
|
218
|
+
try {
|
|
219
|
+
helpers = require(path.join(__dirname, 'calidad-pre-commit.js'));
|
|
220
|
+
} catch (_) {
|
|
221
|
+
process.exit(0);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
let hallazgo = null;
|
|
225
|
+
try {
|
|
226
|
+
hallazgo = evaluarCommit({ cwd, comando, helpers });
|
|
227
|
+
} catch (_) {
|
|
228
|
+
process.exit(0);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (hallazgo) emitirNudge({ cwd, hallazgo });
|
|
232
|
+
|
|
233
|
+
// WARN-ONLY (ADR-0035): jamás exit 2 en este modo.
|
|
234
|
+
process.exit(0);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (require.main === module) {
|
|
238
|
+
main();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
module.exports = { esGitCommit, estadoTddDeFaseActiva, hayEvidenciaRed, evaluarCommit };
|
|
@@ -14,9 +14,12 @@
|
|
|
14
14
|
* - fragmentos: [_intent-spec]
|
|
15
15
|
* - maxTurnos (Parte 8 — Stop Rules)
|
|
16
16
|
*
|
|
17
|
-
* Comportamiento:
|
|
18
|
-
* -
|
|
19
|
-
*
|
|
17
|
+
* Comportamiento (modo blocking desde ADR-0033):
|
|
18
|
+
* - BLOQUEA (exit 2) cuando un agente ALTO tiene frontmatter incompleto.
|
|
19
|
+
* El Write/Edit ya ocurrió (PostToolUse); el exit 2 surface el error a
|
|
20
|
+
* Claude para que complete el intent spec. Sigue emitiendo el nudge para
|
|
21
|
+
* trazabilidad antes de bloquear.
|
|
22
|
+
* - Sale 0 (sin ruido) cuando el agente ALTO está completo o no es ALTO.
|
|
20
23
|
* - Solo se dispara con archivos `agentes/*.md` (no fragmentos `_*.md`)
|
|
21
24
|
* - Respeta exclusiones: temp/, node_modules/, respositorios-git/, _userland/
|
|
22
25
|
*
|
|
@@ -34,9 +37,10 @@
|
|
|
34
37
|
* accionado: false
|
|
35
38
|
* }
|
|
36
39
|
*
|
|
37
|
-
* Origen: ADR-0027 (
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
+
* Origen: ADR-0027 (warn-only) → ADR-0033 (promoción a blocking, 2026-06-11).
|
|
41
|
+
* Promoción justificada: 24 días estable en warn-only, 8/8 agentes ALTO con
|
|
42
|
+
* frontmatter completo al momento de la promoción (cero falsos positivos sobre
|
|
43
|
+
* el estado actual). Opt-out preservado: SWL_INTENT_SPEC=0.
|
|
40
44
|
*/
|
|
41
45
|
|
|
42
46
|
const fs = require('fs');
|
|
@@ -216,7 +220,23 @@ try {
|
|
|
216
220
|
}
|
|
217
221
|
fs.appendFileSync(nudgesFile, JSON.stringify(nudge) + '\n');
|
|
218
222
|
} catch (_) {
|
|
219
|
-
// Si falla persistir, no romper el flujo del
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
+
// Si falla persistir, no romper el flujo del bloqueo
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ─── Modo blocking (ADR-0033) ─────────────────────────────────────────────
|
|
227
|
+
// El agente ALTO tiene frontmatter incompleto: bloquear (exit 2) y surface el
|
|
228
|
+
// detalle a Claude por stderr para que complete el intent spec. Opt-out global
|
|
229
|
+
// SWL_INTENT_SPEC=0 ya cortó arriba; aquí el bloqueo es activo.
|
|
230
|
+
const razon = [
|
|
231
|
+
`Intent spec incompleto en agente ALTO riesgo: ${nombreAgente}`,
|
|
232
|
+
`Faltan campos obligatorios: ${faltan.join(', ')}.`,
|
|
233
|
+
``,
|
|
234
|
+
`Completa el frontmatter según reglas/intent-engineering.md:`,
|
|
235
|
+
` strategy, healthMetrics, steering, hardGuardrails, maxTurnos,`,
|
|
236
|
+
` y fragmentos: [_intent-spec].`,
|
|
237
|
+
`Carga Skill("proceso-intent-engineering") para la guía completa.`,
|
|
238
|
+
``,
|
|
239
|
+
`Para omitir esta verificación: SWL_INTENT_SPEC=0 (registra la excepción).`,
|
|
240
|
+
].join('\n');
|
|
241
|
+
process.stderr.write(razon);
|
|
242
|
+
process.exit(2);
|
package/llms.txt
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# swl-ses (@saulwade/swl-ses)
|
|
2
|
+
|
|
3
|
+
> Sistema de ingeniería de software auto-evolutivo multi-runtime polyglot (SDLC completo), distribuido como paquete npm y plugin de Claude Code. 60 agentes, 182 habilidades, 43 comandos, 29 reglas base y 46 hooks. Soporta 11 lenguajes y 7 runtimes (Claude Code, OpenClaude, OpenCode, Gemini, Cursor, Codex, Copilot). Versión 2.0.0.
|
|
4
|
+
|
|
5
|
+
Archivo generado por `node scripts/generar-inventario.js` — no editar a mano. Las cifras se sincronizan con INVENTARIO.md en cada regeneración.
|
|
6
|
+
|
|
7
|
+
## Documentación
|
|
8
|
+
|
|
9
|
+
- [README](README.md): overview público y quickstart
|
|
10
|
+
- [Manual de uso](MANUAL_USO.md): manual operacional completo
|
|
11
|
+
- [Comandos](COMANDOS.md): referencia detallada de cada comando `/swl:*`
|
|
12
|
+
- [Agentes](AGENTS.md): catálogo de agentes con capacidades
|
|
13
|
+
- [Inventario](INVENTARIO.md): conteos oficiales de todos los componentes
|
|
14
|
+
- [Instalación](INSTALACION.md): instalación, perfiles y configuración
|
|
15
|
+
- [Instrucciones del proyecto](CLAUDE.md): convenciones, stack y reglas
|
|
16
|
+
|
|
17
|
+
## Componentes
|
|
18
|
+
|
|
19
|
+
- 60 agentes especializados en `agentes/` (orquestación, implementación por stack, revisión, calidad, diseño)
|
|
20
|
+
- 182 habilidades cargables bajo demanda en `habilidades/` (conocimiento operacional con divulgación progresiva)
|
|
21
|
+
- 43 comandos `/swl:*` en `comandos/swl/` (ciclo GSD, calidad, release, diagnóstico)
|
|
22
|
+
- 29 reglas base + 40 reglas por lenguaje en `reglas/` (políticas obligatorias por matcher)
|
|
23
|
+
- 46 hooks en `hooks/` (telemetría, validación, seguridad; zero-deps, escrituras atómicas)
|
|
24
|
+
|
|
25
|
+
## Opcional
|
|
26
|
+
|
|
27
|
+
- [CHANGELOG](CHANGELOG.md): historial de versiones
|
|
28
|
+
- [Índice de ADRs](.planning/adrs/README.md): decisiones de arquitectura
|
|
29
|
+
- [Variables de entorno](docs/variables-entorno.md): configuración opt-in
|
|
@@ -168,19 +168,10 @@
|
|
|
168
168
|
"maxConsecutiveFailures": 5,
|
|
169
169
|
"degradeOnFailure": "skip"
|
|
170
170
|
},
|
|
171
|
-
"
|
|
171
|
+
"ciclo-evolucion.js": {
|
|
172
172
|
"event": "Stop",
|
|
173
173
|
"matcher": "",
|
|
174
|
-
"description": "
|
|
175
|
-
"blocking": false,
|
|
176
|
-
"async": true,
|
|
177
|
-
"maxConsecutiveFailures": 5,
|
|
178
|
-
"degradeOnFailure": "skip"
|
|
179
|
-
},
|
|
180
|
-
"metricas-evolucion.js": {
|
|
181
|
-
"event": "Stop",
|
|
182
|
-
"matcher": "",
|
|
183
|
-
"description": "Consolida métricas del ciclo de evolución (nudges accionados/pendientes, instintos, fallos de agentes, evoluciones aplicadas/revertidas) y actualiza .planning/evolution/metricas.json con health_score compuesto. Dispara escalamiento a alertas persistentes si >=5 nudges del mismo tipo ignorados en 14d.",
|
|
174
|
+
"description": "Ciclo de evolución (evento Stop): en un solo proceso ejecuta las sub-etapas de métricas (consolida .planning/evolution/metricas.json con health_score; escala alertas persistentes si >=5 nudges del mismo tipo ignorados en 14d) y perfil de usuario (acumula dirty-bit en .planning/user-profile/; nudge a perfilador-usuario-swl al cruzar umbral). Fusión de metricas-evolucion.js + actualizar-perfil-usuario.js (Fase 11, D-12). Lógica en hooks/lib/etapa-{metricas,perfil-usuario}.js.",
|
|
184
175
|
"blocking": false,
|
|
185
176
|
"async": true,
|
|
186
177
|
"maxConsecutiveFailures": 5,
|
|
@@ -195,10 +186,10 @@
|
|
|
195
186
|
"maxConsecutiveFailures": 5,
|
|
196
187
|
"degradeOnFailure": "skip"
|
|
197
188
|
},
|
|
198
|
-
"
|
|
189
|
+
"ciclo-evolucion-subagente.js": {
|
|
199
190
|
"event": "SubagentStop",
|
|
200
191
|
"matcher": "",
|
|
201
|
-
"description": "
|
|
192
|
+
"description": "Ciclo de evolución (evento SubagentStop): registra cada terminación de subagente SWL en .planning/auto-evolution/agentes.jsonl y emite nudge a /swl:evolucionar cuando un agente acumula fallos, volumen de runs, loop o drift (ventana 14 días, throttle 24h). Renombrado de auto-evolucion.js (Fase 11, D-12). Lógica en hooks/lib/etapa-auto-evolucion.js.",
|
|
202
193
|
"blocking": false,
|
|
203
194
|
"async": true,
|
|
204
195
|
"maxConsecutiveFailures": 5,
|
|
@@ -301,6 +292,15 @@
|
|
|
301
292
|
"maxConsecutiveFailures": 5,
|
|
302
293
|
"degradeOnFailure": "skip"
|
|
303
294
|
},
|
|
295
|
+
"contexto-iteracion.js": {
|
|
296
|
+
"event": "UserPromptSubmit",
|
|
297
|
+
"matcher": "",
|
|
298
|
+
"description": "Anti-context-rot para loops iterativos: inyecta el estado de la corrida activa en .planning/loops/ (iteración, últimas filas del TSV, plateau/recomendación de trayectoria). Throttled a 1 inyección cada 4 min por corrida. Opt-out: SWL_CONTEXTO_ITERACION=0.",
|
|
299
|
+
"blocking": false,
|
|
300
|
+
"async": true,
|
|
301
|
+
"maxConsecutiveFailures": 5,
|
|
302
|
+
"degradeOnFailure": "skip"
|
|
303
|
+
},
|
|
304
304
|
"guardrail-modelo.js": {
|
|
305
305
|
"event": "PreToolUse",
|
|
306
306
|
"matcher": "Task|Agent",
|
|
@@ -365,14 +365,32 @@
|
|
|
365
365
|
"maxConsecutiveFailures": 5,
|
|
366
366
|
"degradeOnFailure": "skip"
|
|
367
367
|
},
|
|
368
|
+
"tdd-gate.js": {
|
|
369
|
+
"event": "PreToolUse",
|
|
370
|
+
"matcher": "Bash",
|
|
371
|
+
"description": "Gate G2 (TDD): ante git commit de feature (fuente+tests staged) verifica evidencia de ciclo RED en .planning/loops/tdd-* (telemetria escrita por ejecutar-fase/tdd-workflow). Sin evidencia emite nudge kind:tdd-red-evidence (warn-only, NUNCA exit 2 en este modo). Solo aplica con fase activa (ciclo GSD); 'fuente sin tests' es dominio de G3 (sin doble nudge). Respeta opt-out declarado del CONTEXTO (**TDD**: off) y prefijos docs:/chore:/style:. Ventana de evidencia: 24h (SWL_TDD_GATE_VENTANA_H). Opt-out: SWL_TDD_GATE=0. Promocion a blocking via ADR-0035 (D-07).",
|
|
372
|
+
"blocking": false,
|
|
373
|
+
"async": false,
|
|
374
|
+
"maxConsecutiveFailures": 5,
|
|
375
|
+
"degradeOnFailure": "warn"
|
|
376
|
+
},
|
|
377
|
+
"spec-gate.js": {
|
|
378
|
+
"event": "PreToolUse",
|
|
379
|
+
"matcher": "Write|Edit|MultiEdit",
|
|
380
|
+
"description": "Gate G0 (SDD): detecta Write/Edit a codigo fuente sin fase activa con PLAN aprobado. Lee .planning/locks/fase-activa.json (escrito por /swl:aprobar-plan) y re-computa SHA256 del plan referenciado; sin fase activa o plan mutado emite nudge kind:spec-gate (warn-only, NUNCA exit 2 en este modo). Zero-config: sin .planning/ sale silencioso. Excluye tests/generados/docs (clasificador esArchivoFuente de calidad-pre-commit) y temp/, node_modules/, _userland/, respositorios-git/. Opt-out: SWL_SPEC_GATE=0. Promocion a blocking via ADR-0034 tras ~2 semanas de calibracion (D-07).",
|
|
381
|
+
"blocking": false,
|
|
382
|
+
"async": false,
|
|
383
|
+
"maxConsecutiveFailures": 5,
|
|
384
|
+
"degradeOnFailure": "warn"
|
|
385
|
+
},
|
|
368
386
|
"validar-intent-spec.js": {
|
|
369
387
|
"event": "PostToolUse",
|
|
370
388
|
"matcher": "Write|Edit|MultiEdit",
|
|
371
|
-
"description": "Verifica que agentes nivelRiesgo:ALTO declaren las 6 partes del framework Intent Engineering (strategy, healthMetrics, steering, hardGuardrails, maxTurnos, fragmentos:[_intent-spec]) segun reglas/intent-engineering.md. Solo aplica a agentes/*.md no fragmentos. Emite nudge a .planning/evolution/nudges.jsonl
|
|
372
|
-
"blocking":
|
|
373
|
-
"async":
|
|
389
|
+
"description": "Verifica que agentes nivelRiesgo:ALTO declaren las 6 partes del framework Intent Engineering (strategy, healthMetrics, steering, hardGuardrails, maxTurnos, fragmentos:[_intent-spec]) segun reglas/intent-engineering.md. Solo aplica a agentes/*.md no fragmentos. Emite nudge a .planning/evolution/nudges.jsonl y BLOQUEA (exit 2) si faltan campos. Excluye temp/, node_modules/, respositorios-git/, _userland/, .planning/. Opt-out: SWL_INTENT_SPEC=0. ADR-0027 (warn-only) -> ADR-0033 (blocking, 2026-06-11).",
|
|
390
|
+
"blocking": true,
|
|
391
|
+
"async": false,
|
|
374
392
|
"maxConsecutiveFailures": 5,
|
|
375
|
-
"degradeOnFailure": "
|
|
393
|
+
"degradeOnFailure": "warn"
|
|
376
394
|
},
|
|
377
395
|
"notificacion-telegram.js": {
|
|
378
396
|
"event": "Stop",
|
|
@@ -395,7 +413,7 @@
|
|
|
395
413
|
"notificacion-telegram-subagent.js": {
|
|
396
414
|
"event": "SubagentStop",
|
|
397
415
|
"matcher": "",
|
|
398
|
-
"description": "Envía notificación Telegram cuando un subagente termina su turno. Best-effort: siempre exit 0.
|
|
416
|
+
"description": "Envía notificación Telegram cuando un subagente termina su turno. INERTE por default: SubagentStop no está en los eventos default del script compartido porque duplica la notificación del Stop final (mismo cuerpo, dos mensajes). Activar con CLAUDE_NOTIFY_EVENTS=Stop,Notification,SubagentStop. Best-effort: siempre exit 0. Opt-out global: SWL_NOTIFICACIONES_TELEGRAM=0.",
|
|
399
417
|
"blocking": false,
|
|
400
418
|
"async": true,
|
|
401
419
|
"maxConsecutiveFailures": 5,
|
package/manifiestos/modulos.json
CHANGED
|
@@ -40,7 +40,6 @@
|
|
|
40
40
|
"agentes/frontend-angular-swl.md",
|
|
41
41
|
"agentes/frontend-css-swl.md",
|
|
42
42
|
"agentes/frontend-tailwind-swl.md",
|
|
43
|
-
"agentes/ux-disenador-swl.md",
|
|
44
43
|
"agentes/disenador-ui-swl.md",
|
|
45
44
|
"agentes/accesibilidad-wcag-swl.md"
|
|
46
45
|
],
|
|
@@ -244,9 +243,13 @@
|
|
|
244
243
|
"habilidades/proceso-ddia-fundamentos",
|
|
245
244
|
"habilidades/proceso-ddia-streaming",
|
|
246
245
|
"habilidades/proceso-discovery-machote",
|
|
246
|
+
"habilidades/proceso-dynamic-workflows",
|
|
247
247
|
"habilidades/proceso-modular-split",
|
|
248
248
|
"habilidades/agent-deep-links",
|
|
249
|
-
"habilidades/changelog-generator"
|
|
249
|
+
"habilidades/changelog-generator",
|
|
250
|
+
"habilidades/proceso-debate-adversarial",
|
|
251
|
+
"habilidades/calidad-mutation-testing",
|
|
252
|
+
"habilidades/calidad-contract-testing"
|
|
250
253
|
],
|
|
251
254
|
"targets": [
|
|
252
255
|
"claude",
|
|
@@ -804,11 +807,12 @@
|
|
|
804
807
|
},
|
|
805
808
|
"comandos-core": {
|
|
806
809
|
"descripcion": "Comandos esenciales del flujo SWL",
|
|
807
|
-
"tipo": "
|
|
810
|
+
"tipo": "mixto",
|
|
808
811
|
"archivos": [
|
|
809
812
|
"comandos/swl/nuevo-proyecto.md",
|
|
810
813
|
"comandos/swl/instalar.md",
|
|
811
814
|
"comandos/swl/planear-fase.md",
|
|
815
|
+
"comandos/swl/aprobar-plan.md",
|
|
812
816
|
"comandos/swl/ejecutar-fase.md",
|
|
813
817
|
"comandos/swl/verificar.md",
|
|
814
818
|
"comandos/swl/discutir-fase.md",
|
|
@@ -816,7 +820,9 @@
|
|
|
816
820
|
"comandos/swl/adoptar-proyecto.md",
|
|
817
821
|
"comandos/swl/checkpoint.md",
|
|
818
822
|
"comandos/swl/compactar.md",
|
|
819
|
-
"comandos/swl/aprender.md"
|
|
823
|
+
"comandos/swl/aprender.md",
|
|
824
|
+
"scripts/lib/plan-lock.js",
|
|
825
|
+
"scripts/verificar-trazabilidad.js"
|
|
820
826
|
],
|
|
821
827
|
"targets": [
|
|
822
828
|
"claude",
|
|
@@ -833,23 +839,21 @@
|
|
|
833
839
|
"archivos": [
|
|
834
840
|
"comandos/swl/actualizar.md",
|
|
835
841
|
"comandos/swl/evolucionar.md",
|
|
836
|
-
"comandos/swl/
|
|
837
|
-
"comandos/swl/salud.md",
|
|
842
|
+
"comandos/swl/status.md",
|
|
838
843
|
"comandos/swl/release.md",
|
|
839
844
|
"comandos/swl/auditar-deps.md",
|
|
840
845
|
"comandos/swl/crear-skill.md",
|
|
841
846
|
"comandos/swl/autoresearch.md",
|
|
847
|
+
"comandos/swl/predecir.md",
|
|
842
848
|
"comandos/swl/contexto.md",
|
|
843
849
|
"comandos/swl/sesiones.md",
|
|
844
850
|
"comandos/swl/instintos.md",
|
|
845
851
|
"comandos/swl/modelo.md",
|
|
846
|
-
"comandos/swl/metricas.md",
|
|
847
852
|
"comandos/swl/plugins.md",
|
|
848
853
|
"comandos/swl/brainstorm.md",
|
|
849
854
|
"comandos/swl/revisar.md",
|
|
850
855
|
"comandos/swl/gateway.md",
|
|
851
856
|
"comandos/swl/cron.md",
|
|
852
|
-
"comandos/swl/dashboard.md",
|
|
853
857
|
"comandos/swl/skill-search.md",
|
|
854
858
|
"comandos/swl/evaluar-skill.md",
|
|
855
859
|
"comandos/swl/wiki.md",
|
|
@@ -907,7 +911,6 @@
|
|
|
907
911
|
"reglas/auditorias-documentales-estructurales.md",
|
|
908
912
|
"reglas/intent-engineering.md",
|
|
909
913
|
"reglas/tests-cleanup.md",
|
|
910
|
-
"reglas/verificar-citas-temporales.md",
|
|
911
914
|
"reglas/sin-duplicacion-reglas-globales.md"
|
|
912
915
|
],
|
|
913
916
|
"targets": [
|
|
@@ -934,8 +937,7 @@
|
|
|
934
937
|
"reglas/gobernanza.md",
|
|
935
938
|
"reglas/hooks.md",
|
|
936
939
|
"reglas/patrones.md",
|
|
937
|
-
"reglas/testing.md"
|
|
938
|
-
"reglas/harness-claude-code.md"
|
|
940
|
+
"reglas/testing.md"
|
|
939
941
|
],
|
|
940
942
|
"targets": [
|
|
941
943
|
"claude",
|
|
@@ -1019,9 +1021,8 @@
|
|
|
1019
1021
|
"hooks/graph-update.js",
|
|
1020
1022
|
"hooks/preservar-estado-pre-compact.js",
|
|
1021
1023
|
"hooks/check-update.js",
|
|
1022
|
-
"hooks/
|
|
1023
|
-
"hooks/
|
|
1024
|
-
"hooks/metricas-evolucion.js",
|
|
1024
|
+
"hooks/ciclo-evolucion.js",
|
|
1025
|
+
"hooks/ciclo-evolucion-subagente.js",
|
|
1025
1026
|
"hooks/notificacion-sesion-stop.js",
|
|
1026
1027
|
"hooks/captura-feedback-usuario.js",
|
|
1027
1028
|
"hooks/inbox-aviso.js",
|
|
@@ -1029,13 +1030,20 @@
|
|
|
1029
1030
|
"hooks/claudemd-bloat-detector.js",
|
|
1030
1031
|
"hooks/claudemd-duplicacion-detector.js",
|
|
1031
1032
|
"hooks/validar-intent-spec.js",
|
|
1033
|
+
"hooks/spec-gate.js",
|
|
1034
|
+
"hooks/tdd-gate.js",
|
|
1032
1035
|
"hooks/sugerir-regenerar-inventario.js",
|
|
1033
1036
|
"hooks/sugerir-contribuir.js",
|
|
1037
|
+
"hooks/contexto-iteracion.js",
|
|
1034
1038
|
"hooks/_run-hook.sh",
|
|
1035
1039
|
"hooks/lib/fingerprint-id.js",
|
|
1036
1040
|
"hooks/lib/token-budget.js",
|
|
1037
1041
|
"hooks/lib/nudge-tracker.js",
|
|
1038
1042
|
"hooks/lib/gateway-notify.js",
|
|
1043
|
+
"hooks/lib/ciclo-evolucion.js",
|
|
1044
|
+
"hooks/lib/etapa-metricas.js",
|
|
1045
|
+
"hooks/lib/etapa-perfil-usuario.js",
|
|
1046
|
+
"hooks/lib/etapa-auto-evolucion.js",
|
|
1039
1047
|
"hooks/validar-planning-paths.js"
|
|
1040
1048
|
],
|
|
1041
1049
|
"targets": [
|
|
@@ -1078,6 +1086,7 @@
|
|
|
1078
1086
|
"hooks/lib/taint-tracker.js",
|
|
1079
1087
|
"hooks/lib/resource-quota.js",
|
|
1080
1088
|
"hooks/lib/merkle-audit.js",
|
|
1089
|
+
"hooks/lib/loop-telemetry.js",
|
|
1081
1090
|
"scripts/lib/scoring-instintos.js",
|
|
1082
1091
|
"scripts/lib/budget-enforcer.js",
|
|
1083
1092
|
"scripts/lib/semantic-search.js",
|