@saulwade/swl-ses 1.9.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/CLAUDE.md +196 -196
  2. package/README.md +579 -579
  3. package/agentes/_propose-step.md +90 -0
  4. package/agentes/accesibilidad-wcag-swl.md +3 -3
  5. package/agentes/auto-evolucion-swl.md +908 -908
  6. package/agentes/disenador-ui-swl.md +6 -5
  7. package/agentes/frontend-angular-swl.md +2 -2
  8. package/agentes/frontend-css-swl.md +2 -2
  9. package/agentes/frontend-react-swl.md +4 -4
  10. package/agentes/frontend-swl.md +6 -6
  11. package/agentes/implementador-swl.md +2 -0
  12. package/agentes/investigador-ux-swl.md +5 -5
  13. package/agentes/orquestador-swl.md +9 -7
  14. package/agentes/perfilador-usuario-swl.md +321 -308
  15. package/agentes/producto-prd-swl.md +1 -1
  16. package/agentes/red-team-swl.md +218 -218
  17. package/agentes/tdd-qa-swl.md +17 -1
  18. package/bin/swl-ses.js +1 -1
  19. package/comandos/swl/actualizar.md +1 -1
  20. package/comandos/swl/aprender.md +2 -2
  21. package/comandos/swl/aprobar-plan.md +153 -0
  22. package/comandos/swl/ayuda.md +3 -3
  23. package/comandos/swl/briefing.md +122 -0
  24. package/comandos/swl/compactar.md +29 -2
  25. package/comandos/swl/discutir-fase.md +23 -2
  26. package/comandos/swl/ejecutar-fase.md +59 -6
  27. package/comandos/swl/evolucionar.md +1 -1
  28. package/comandos/swl/inbox.md +1 -1
  29. package/comandos/swl/instalar.md +1 -1
  30. package/comandos/swl/nemesis.md +1 -1
  31. package/comandos/swl/planear-fase.md +19 -1
  32. package/comandos/swl/plugins.md +1 -1
  33. package/comandos/swl/release.md +47 -1
  34. package/comandos/swl/status.md +348 -0
  35. package/comandos/swl/verificar.md +27 -1
  36. package/habilidades/ai-runtime-security/SKILL.md +1 -1
  37. package/habilidades/auto-evolucion-protocolo/SKILL.md +276 -276
  38. package/habilidades/benchmark-memoria/SKILL.md +1 -1
  39. package/habilidades/calidad-contract-testing/SKILL.md +165 -0
  40. package/habilidades/changelog-generator/SKILL.md +9 -2
  41. package/habilidades/changelog-generator/scripts/parse-commits.js +13 -1
  42. package/habilidades/diagrama-arquitectura/SKILL.md +1 -1
  43. package/habilidades/drift-detection/SKILL.md +179 -179
  44. package/habilidades/ejecutar-fase/SKILL.md +541 -468
  45. package/habilidades/estructura-proyecto-claude/SKILL.md +17 -14
  46. package/habilidades/estructura-proyecto-claude/recursos/configuracion-y-extensiones.md +34 -23
  47. package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +70 -53
  48. package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +57 -77
  49. package/habilidades/extractor-de-aprendizajes/SKILL.md +9 -5
  50. package/habilidades/harness-claude-code/SKILL.md +10 -7
  51. package/{reglas/harness-claude-code.md → habilidades/harness-claude-code/recursos/disciplina-harness-regla.md} +2 -2
  52. package/habilidades/instalar-sistema/SKILL.md +3 -3
  53. package/habilidades/meta-skills-estandar/recursos/frameworks-seguridad.md +1 -1
  54. package/habilidades/perfil-usuario/SKILL.md +200 -200
  55. package/habilidades/planear-fase/SKILL.md +26 -4
  56. package/habilidades/proceso-ddia-fundamentos/SKILL.md +1 -1
  57. package/habilidades/proceso-ddia-streaming/SKILL.md +4 -4
  58. package/habilidades/proceso-debate-adversarial/SKILL.md +2 -2
  59. package/habilidades/protocolo-revision-swl/SKILL.md +1 -1
  60. package/habilidades/seguridad-skills-ia/SKILL.md +1 -1
  61. package/habilidades/swl-claudemd/SKILL.md +50 -210
  62. package/habilidades/swl-claudemd/recursos/contrato-aprender.md +83 -0
  63. package/habilidades/swl-claudemd/recursos/duplicacion-reglas-globales.md +85 -0
  64. package/habilidades/swl-claudemd/recursos/plantillas-init.md +94 -0
  65. package/habilidades/swl-dashboard/SKILL.md +9 -9
  66. package/habilidades/swl-revisar-impacto/SKILL.md +1 -1
  67. package/habilidades/tdd-workflow/SKILL.md +715 -673
  68. package/habilidades/validacion-ci-sistema/SKILL.md +20 -4
  69. package/hooks/calidad-pre-commit.js +344 -3
  70. package/hooks/check-update.js +39 -1
  71. package/hooks/ciclo-evolucion-subagente.js +26 -0
  72. package/hooks/ciclo-evolucion.js +26 -0
  73. package/hooks/extraccion-aprendizajes.js +13 -0
  74. package/hooks/lib/autonomia.js +208 -0
  75. package/hooks/lib/briefing.js +474 -0
  76. package/hooks/lib/ciclo-evolucion.js +47 -0
  77. package/hooks/{auto-evolucion.js → lib/etapa-auto-evolucion.js} +701 -700
  78. package/hooks/{metricas-evolucion.js → lib/etapa-metricas.js} +388 -376
  79. package/hooks/{actualizar-perfil-usuario.js → lib/etapa-perfil-usuario.js} +376 -364
  80. package/hooks/lib/evolution-tracker.js +24 -3
  81. package/hooks/lib/propose-step.js +357 -0
  82. package/hooks/session-briefing.js +98 -0
  83. package/hooks/spec-gate.js +211 -0
  84. package/hooks/tdd-gate.js +241 -0
  85. package/hooks/telemetria-skill-routing.js +100 -0
  86. package/hooks/validar-intent-spec.js +30 -10
  87. package/instintos/autonomia.yaml +27 -0
  88. package/llms.txt +6 -6
  89. package/manifiestos/hooks-config.json +44 -17
  90. package/manifiestos/modulos.json +40 -15
  91. package/manifiestos/skills-lock.json +64 -57
  92. package/package.json +93 -93
  93. package/plugin.json +371 -375
  94. package/reglas/accesibilidad.md +10 -0
  95. package/reglas/analizar-directorios-antes-de-escribir.md +228 -0
  96. package/reglas/api-diseno.md +9 -0
  97. package/reglas/auditorias-documentales-estructurales.md +7 -0
  98. package/reglas/cloud-infra.md +8 -0
  99. package/reglas/consultar-vault-primero.md +195 -0
  100. package/reglas/debatir-antes-de-aceptar.md +158 -0
  101. package/reglas/fragmentos-compartidos.md +5 -0
  102. package/reglas/git-coauthor.md +100 -0
  103. package/reglas/gobernanza.md +4 -4
  104. package/reglas/hooks.md +6 -0
  105. package/reglas/intent-engineering.md +4 -0
  106. package/reglas/markitdown.md +8 -0
  107. package/reglas/memoria-consolidada.md +1 -1
  108. package/reglas/monitor-ci.md +309 -0
  109. package/reglas/patrones.md +6 -0
  110. package/reglas/registro-componentes-nuevos.md +39 -2
  111. package/reglas/seguridad-agentes.md +1 -1
  112. package/reglas/sesiones-paralelas.md +180 -0
  113. package/reglas/skills-estandar.md +6 -0
  114. package/reglas/testing.md +7 -0
  115. package/reglas/tests-cleanup.md +4 -0
  116. package/reglas/usar-code-review-graph.md +155 -0
  117. package/reglas/usar-sistema-swl.md +1 -1
  118. package/reglas/verificar-citas-normativas.md +548 -0
  119. package/scripts/instalador.js +52 -6
  120. package/scripts/lib/ci-reader.js +193 -0
  121. package/scripts/lib/detectar-host-swl.js +175 -0
  122. package/scripts/lib/evidencia-release.js +322 -0
  123. package/scripts/lib/gate-hooks-requires.js +249 -0
  124. package/scripts/lib/gate-licencias.js +212 -0
  125. package/scripts/lib/git-metricas.js +257 -0
  126. package/scripts/lib/gitignore-manifest.js +29 -1
  127. package/scripts/lib/metricas-dora.js +204 -0
  128. package/scripts/lib/plan-lock.js +275 -0
  129. package/scripts/migrar-fase-dominio.js +0 -1
  130. package/scripts/tui/ejecutores.js +1 -1
  131. package/scripts/validar-manifest.js +92 -1
  132. package/scripts/verificar-evolucion.js +54 -4
  133. package/scripts/verificar-release.js +102 -0
  134. package/scripts/verificar-trazabilidad.js +298 -0
  135. package/agentes/ux-disenador-swl.md +0 -503
  136. package/comandos/swl/dashboard.md +0 -146
  137. package/comandos/swl/evolucion-estado.md +0 -191
  138. package/comandos/swl/metricas.md +0 -376
  139. package/comandos/swl/salud.md +0 -481
  140. package/reglas/arquitectura.evolved.json +0 -7
  141. package/reglas/seguridad.evolved.json +0 -7
  142. package/reglas/verificar-citas-temporales.md +0 -139
@@ -0,0 +1,298 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * verificar-trazabilidad.js — Valida la cadena REQ→T→commit→test de una fase (G4).
6
+ *
7
+ * Uso:
8
+ * node scripts/verificar-trazabilidad.js --fase=10 [--solo-plan] [--json]
9
+ *
10
+ * Fuentes:
11
+ * - REQ-NN: `.planning/fases/NN-CONTEXTO.md` § Criterios de aceptación
12
+ * (definiciones `**REQ-NN**:` o `REQ-NN:`; los marcados RETIRADO
13
+ * se excluyen del universo exigible)
14
+ * - T-NN: `.planning/fases/NN-PLAN.md` — campo `**Verifica REQ**: ...`
15
+ * por tarea `### T-NN:`
16
+ * - Commits: `git log` — footer `Refs: REQ-NN[, REQ-MM]`
17
+ * - Tests: archivos de test versionados (git ls-files + clasificador de
18
+ * calidad-pre-commit) con marker `verifica: REQ-NN`
19
+ *
20
+ * Exit codes:
21
+ * 0 — cadena completa, o CONTEXTO legacy sin REQ-IDs (gracia, con nota)
22
+ * 1 — huérfanos detectados (REQ sin tarea / sin commit / sin test)
23
+ * 2 — error de invocación o parseo (fase inexistente, args inválidos)
24
+ *
25
+ * `--solo-plan`: valida únicamente la matriz REQ×T (lo usa /swl:aprobar-plan,
26
+ * donde commits y tests aún no existen).
27
+ *
28
+ * Zero-deps. Espejo estructural de verificar-release.js (gates + exit codes).
29
+ */
30
+
31
+ const fs = require('fs');
32
+ const path = require('path');
33
+ const { execFileSync } = require('child_process');
34
+
35
+ const LIMITE_COMMITS = 300;
36
+
37
+ // ─── Parseo de fuentes ──────────────────────────────────────────────────────
38
+
39
+ /**
40
+ * Extrae definiciones REQ-NN del CONTEXTO.
41
+ * Método de verificación por REQ (patrón requirements engineering):
42
+ * - default `test` — exige test con marker `verifica: REQ-NN`
43
+ * - `(verificación: inspección)` en el criterio — satisfecho por prosa/docs/grep;
44
+ * exige tarea y commit, pero NO test automatizado.
45
+ * @returns {{activos: string[], retirados: string[], metodo: Object<string,string>}}
46
+ */
47
+ function extraerReqs(contextoTexto) {
48
+ const activos = new Set();
49
+ const retirados = new Set();
50
+ const metodo = {};
51
+ // Definición: línea con `**REQ-NN**:` o `REQ-NN:` (con bullet opcional).
52
+ // El criterio puede continuar en líneas siguientes indentadas — se capturan
53
+ // hasta la próxima definición para detectar la anotación de método.
54
+ // REQ-NN (legacy) o REQ-NN-MM (namespaceado por fase, DT-IDS-NAMESPACE).
55
+ // El grupo `(?:-\d{1,3})?` es greedy: en `REQ-12-01` captura el ID completo,
56
+ // nunca el prefijo `REQ-12` truncado.
57
+ const re = /^\s*(?:[-*]\s*)?\*{0,2}(REQ-\d{1,3}(?:-\d{1,3})?)\*{0,2}\s*:([\s\S]*?)(?=^\s*(?:[-*]\s*)?\*{0,2}REQ-\d|^#|\n\n|$(?![\s\S]))/gm;
58
+ let m;
59
+ while ((m = re.exec(contextoTexto)) !== null) {
60
+ const cuerpo = m[2];
61
+ if (/RETIRADO/i.test(cuerpo)) {
62
+ retirados.add(m[1]);
63
+ continue;
64
+ }
65
+ activos.add(m[1]);
66
+ metodo[m[1]] = /verificaci[oó]n:\s*inspecci[oó]n/i.test(cuerpo) ? 'inspeccion' : 'test';
67
+ }
68
+ return { activos: [...activos], retirados: [...retirados], metodo };
69
+ }
70
+
71
+ /** Extrae mapa tarea→REQs del PLAN. @returns {Map<string, string[]>} */
72
+ function extraerMatrizPlan(planTexto) {
73
+ const tareas = new Map();
74
+ let tareaActual = null;
75
+ for (const linea of planTexto.split('\n')) {
76
+ const t = linea.match(/^#{2,4}\s*(T-\d{1,3})\s*:/);
77
+ if (t) {
78
+ tareaActual = t[1];
79
+ if (!tareas.has(tareaActual)) tareas.set(tareaActual, []);
80
+ continue;
81
+ }
82
+ // Solo la línea-campo cuenta (`- **Verifica REQ**: ...` al inicio, bullet
83
+ // opcional). Una descripción que cite `**Verifica REQ**:` en prosa NO debe
84
+ // contaminar la matriz ni ocultar huérfanos (ancla `^` obligatoria).
85
+ if (tareaActual && /^\s*(?:[-*]\s*)?\*\*Verifica REQ\*\*\s*:/i.test(linea)) {
86
+ const reqs = linea.match(/REQ-\d{1,3}(?:-\d{1,3})?/g) || [];
87
+ tareas.get(tareaActual).push(...reqs);
88
+ }
89
+ }
90
+ return tareas;
91
+ }
92
+
93
+ /** Commits con footer `Refs: REQ-NN`. @returns {Map<string, string[]>} REQ → hashes cortos */
94
+ function extraerCommitsConRefs(cwd) {
95
+ const porReq = new Map();
96
+ let salida;
97
+ try {
98
+ salida = execFileSync(
99
+ 'git',
100
+ ['log', `-${LIMITE_COMMITS}`, '--format=%h%x00%B%x01'],
101
+ { cwd, encoding: 'utf8', timeout: 10000 }
102
+ );
103
+ } catch (_) {
104
+ return porReq; // sin repo git o sin commits — el reporte lo refleja como gap
105
+ }
106
+ for (const bloque of salida.split('\x01')) {
107
+ const [hash, cuerpo] = bloque.split('\x00');
108
+ if (!hash || !cuerpo) continue;
109
+ const refs = cuerpo.match(/^Refs:\s*(.+)$/m);
110
+ if (!refs) continue;
111
+ for (const req of refs[1].match(/REQ-\d{1,3}(?:-\d{1,3})?/g) || []) {
112
+ if (!porReq.has(req)) porReq.set(req, []);
113
+ porReq.get(req).push(hash.trim());
114
+ }
115
+ }
116
+ return porReq;
117
+ }
118
+
119
+ /** Tests con marker `verifica: REQ-NN`. @returns {Map<string, string[]>} REQ → archivos */
120
+ function extraerTestsConMarker(cwd) {
121
+ const porReq = new Map();
122
+ let esArchivoTest;
123
+ try {
124
+ ({ esArchivoTest } = require(path.join(__dirname, '..', 'hooks', 'calidad-pre-commit.js')));
125
+ } catch (_) {
126
+ esArchivoTest = (r) => /\.(test|spec)\.[jt]sx?$/.test(r) || /test_.*\.py$/.test(r);
127
+ }
128
+
129
+ let archivos = [];
130
+ try {
131
+ archivos = execFileSync('git', ['ls-files'], { cwd, encoding: 'utf8', timeout: 10000 })
132
+ .split('\n')
133
+ .map((l) => l.trim())
134
+ .filter(Boolean)
135
+ .filter(esArchivoTest);
136
+ } catch (_) {
137
+ return porReq;
138
+ }
139
+
140
+ for (const archivo of archivos) {
141
+ let contenido;
142
+ try {
143
+ contenido = fs.readFileSync(path.join(cwd, archivo), 'utf-8');
144
+ } catch (_) {
145
+ continue;
146
+ }
147
+ for (const m of contenido.matchAll(/verifica:\s*(REQ-\d{1,3}(?:-\d{1,3})?)/g)) {
148
+ const req = m[1];
149
+ if (!porReq.has(req)) porReq.set(req, []);
150
+ if (!porReq.get(req).includes(archivo)) porReq.get(req).push(archivo);
151
+ }
152
+ }
153
+ return porReq;
154
+ }
155
+
156
+ // ─── Validación ─────────────────────────────────────────────────────────────
157
+
158
+ function validarFase({ cwd, fase, soloPlan }) {
159
+ const nn = String(Number(fase)).padStart(2, '0');
160
+ const contextoPath = path.join(cwd, '.planning', 'fases', `${nn}-CONTEXTO.md`);
161
+ if (!fs.existsSync(contextoPath)) {
162
+ return { error: `No existe ${path.relative(cwd, contextoPath)}`, exit: 2 };
163
+ }
164
+
165
+ const { activos, retirados, metodo } = extraerReqs(fs.readFileSync(contextoPath, 'utf-8'));
166
+ if (activos.length === 0) {
167
+ return {
168
+ fase: nn,
169
+ legacy: true,
170
+ nota: 'CONTEXTO sin REQ-IDs — trazabilidad no exigible (gracia legacy, fases pre-10)',
171
+ exit: 0,
172
+ };
173
+ }
174
+
175
+ const planPath = path.join(cwd, '.planning', 'fases', `${nn}-PLAN.md`);
176
+ const matrizTareas = fs.existsSync(planPath)
177
+ ? extraerMatrizPlan(fs.readFileSync(planPath, 'utf-8'))
178
+ : new Map();
179
+
180
+ const reqATareas = new Map(activos.map((r) => [r, []]));
181
+ const tareasSinReq = [];
182
+ for (const [tarea, reqs] of matrizTareas) {
183
+ if (reqs.length === 0) tareasSinReq.push(tarea);
184
+ for (const req of reqs) {
185
+ if (reqATareas.has(req)) reqATareas.get(req).push(tarea);
186
+ }
187
+ }
188
+
189
+ const commits = soloPlan ? new Map() : extraerCommitsConRefs(cwd);
190
+ const tests = soloPlan ? new Map() : extraerTestsConMarker(cwd);
191
+
192
+ const validaciones = {
193
+ req_sin_tarea: activos.filter((r) => (reqATareas.get(r) || []).length === 0),
194
+ req_sin_commit: soloPlan ? [] : activos.filter((r) => !(commits.get(r) || []).length),
195
+ req_sin_test: soloPlan
196
+ ? []
197
+ : activos.filter((r) => metodo[r] === 'test' && !(tests.get(r) || []).length),
198
+ tarea_sin_req: tareasSinReq, // informativo, no rompe
199
+ };
200
+
201
+ const trazabilidad = {};
202
+ for (const req of activos) {
203
+ trazabilidad[req] = {
204
+ metodo: metodo[req],
205
+ tareas: reqATareas.get(req) || [],
206
+ commits: commits.get(req) || [],
207
+ tests: tests.get(req) || [],
208
+ };
209
+ }
210
+
211
+ const huerfanos =
212
+ validaciones.req_sin_tarea.length +
213
+ validaciones.req_sin_commit.length +
214
+ validaciones.req_sin_test.length;
215
+
216
+ return {
217
+ fase: nn,
218
+ legacy: false,
219
+ soloPlan: Boolean(soloPlan),
220
+ reqs: activos,
221
+ retirados,
222
+ trazabilidad,
223
+ validaciones,
224
+ exit: huerfanos > 0 ? 1 : 0,
225
+ };
226
+ }
227
+
228
+ // ─── Reporte ────────────────────────────────────────────────────────────────
229
+
230
+ function imprimirReporte(r) {
231
+ if (r.error) {
232
+ console.error(`ERROR: ${r.error}`);
233
+ return;
234
+ }
235
+ if (r.legacy) {
236
+ console.log(`Fase ${r.fase}: ${r.nota}. Exit 0.`);
237
+ return;
238
+ }
239
+ console.log(`Trazabilidad REQ→T→commit→test — Fase ${r.fase}${r.soloPlan ? ' (--solo-plan: matriz REQ×T)' : ''}`);
240
+ console.log('');
241
+ for (const req of r.reqs) {
242
+ const t = r.trazabilidad[req];
243
+ const partes = [`tareas: ${t.tareas.join(', ') || '—'}`];
244
+ if (!r.soloPlan) {
245
+ partes.push(`commits: ${t.commits.join(', ') || '—'}`);
246
+ partes.push(t.metodo === 'inspeccion' ? 'verificación: inspección' : `tests: ${t.tests.join(', ') || '—'}`);
247
+ }
248
+ console.log(` ${req} → ${partes.join(' | ')}`);
249
+ }
250
+ if (r.retirados.length) console.log(` Retirados (no exigibles): ${r.retirados.join(', ')}`);
251
+ console.log('');
252
+
253
+ const v = r.validaciones;
254
+ const gaps = [];
255
+ if (v.req_sin_tarea.length) gaps.push(`REQ sin tarea: ${v.req_sin_tarea.join(', ')}`);
256
+ if (v.req_sin_commit.length) gaps.push(`REQ sin commit (footer Refs:): ${v.req_sin_commit.join(', ')}`);
257
+ if (v.req_sin_test.length) gaps.push(`REQ sin test (marker verifica:): ${v.req_sin_test.join(', ')}`);
258
+
259
+ if (gaps.length) {
260
+ console.log('HUÉRFANOS DETECTADOS:');
261
+ for (const g of gaps) console.log(` ✗ ${g}`);
262
+ } else {
263
+ console.log('✓ Cadena de trazabilidad completa: 0 huérfanos.');
264
+ }
265
+ if (v.tarea_sin_req.length) {
266
+ console.log(` (info) Tareas sin REQ declarado: ${v.tarea_sin_req.join(', ')} — válido para infraestructura/refactor`);
267
+ }
268
+ }
269
+
270
+ // ─── CLI ────────────────────────────────────────────────────────────────────
271
+
272
+ function main() {
273
+ const args = process.argv.slice(2);
274
+ const faseArg = args.find((a) => a.startsWith('--fase='));
275
+ if (!faseArg || !/^\d+$/.test(faseArg.split('=')[1] || '')) {
276
+ console.error('Uso: node scripts/verificar-trazabilidad.js --fase=N [--solo-plan] [--json]');
277
+ process.exit(2);
278
+ }
279
+
280
+ const resultado = validarFase({
281
+ cwd: process.cwd(),
282
+ fase: faseArg.split('=')[1],
283
+ soloPlan: args.includes('--solo-plan'),
284
+ });
285
+
286
+ if (args.includes('--json')) {
287
+ console.log(JSON.stringify(resultado, null, 2));
288
+ } else {
289
+ imprimirReporte(resultado);
290
+ }
291
+ process.exit(resultado.exit);
292
+ }
293
+
294
+ if (require.main === module) {
295
+ main();
296
+ }
297
+
298
+ module.exports = { extraerReqs, extraerMatrizPlan, extraerCommitsConRefs, extraerTestsConMarker, validarFase };