@saulwade/swl-ses 2.4.2 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/CLAUDE.md +194 -241
  2. package/README.md +600 -597
  3. package/agentes/_intent-spec.md +73 -73
  4. package/agentes/_propose-step.md +90 -90
  5. package/agentes/abogado-diablo-swl.md +145 -0
  6. package/agentes/accesibilidad-wcag-swl.md +690 -690
  7. package/agentes/arquitecto-swl.md +267 -267
  8. package/agentes/auto-evolucion-swl.md +908 -908
  9. package/agentes/backend-api-swl.md +1 -1
  10. package/agentes/backend-csharp-swl.md +420 -420
  11. package/agentes/backend-go-swl.md +390 -390
  12. package/agentes/backend-java-swl.md +281 -281
  13. package/agentes/backend-node-swl.md +1 -1
  14. package/agentes/backend-python-swl.md +1 -1
  15. package/agentes/backend-rust-swl.md +364 -364
  16. package/agentes/backend-workers-swl.md +482 -482
  17. package/agentes/cloud-infra-swl.md +509 -509
  18. package/agentes/consolidador-swl.md +541 -541
  19. package/agentes/datos-swl.md +1 -1
  20. package/agentes/depurador-swl.md +352 -352
  21. package/agentes/devops-ci-swl.md +400 -400
  22. package/agentes/disenador-ui-swl.md +569 -569
  23. package/agentes/documentador-swl.md +345 -345
  24. package/agentes/frontend-angular-swl.md +621 -621
  25. package/agentes/frontend-css-swl.md +716 -716
  26. package/agentes/frontend-react-swl.md +692 -692
  27. package/agentes/frontend-swl.md +496 -496
  28. package/agentes/frontend-tailwind-swl.md +826 -826
  29. package/agentes/gh-fix-ci-swl.md +6 -1
  30. package/agentes/implementador-swl.md +1 -1
  31. package/agentes/investigador-swl.md +432 -432
  32. package/agentes/investigador-ux-swl.md +505 -505
  33. package/agentes/llm-apps-swl.md +1 -1
  34. package/agentes/migrador-swl.md +442 -442
  35. package/agentes/mobile-android-swl.md +511 -511
  36. package/agentes/mobile-cross-swl.md +541 -541
  37. package/agentes/mobile-ios-swl.md +502 -502
  38. package/agentes/mobile-testing-swl.md +302 -302
  39. package/agentes/nemesis-auditor-swl.md +285 -285
  40. package/agentes/notificador-swl.md +1 -1
  41. package/agentes/observabilidad-swl.md +438 -438
  42. package/agentes/pagos-swl.md +310 -310
  43. package/agentes/perfilador-usuario-swl.md +321 -321
  44. package/agentes/planificador-swl.md +399 -399
  45. package/agentes/producto-prd-swl.md +589 -589
  46. package/agentes/red-team-swl.md +218 -218
  47. package/agentes/release-manager-swl.md +590 -590
  48. package/agentes/rendimiento-swl.md +713 -713
  49. package/agentes/resolutor-build-swl.md +10 -1
  50. package/agentes/revisor-angular-swl.md +278 -278
  51. package/agentes/revisor-codigo-swl.md +1 -1
  52. package/agentes/revisor-csharp-swl.md +264 -264
  53. package/agentes/revisor-go-swl.md +259 -259
  54. package/agentes/revisor-java-swl.md +257 -257
  55. package/agentes/revisor-kotlin-swl.md +273 -273
  56. package/agentes/revisor-nextjs-swl.md +281 -281
  57. package/agentes/revisor-php-swl.md +271 -271
  58. package/agentes/revisor-react-swl.md +278 -278
  59. package/agentes/revisor-rust-swl.md +346 -346
  60. package/agentes/revisor-seguridad-swl.md +399 -399
  61. package/agentes/revisor-swift-swl.md +268 -268
  62. package/agentes/revisor-typescript-swl.md +346 -346
  63. package/agentes/sre-swl.md +1 -1
  64. package/agentes/tdd-qa-swl.md +393 -393
  65. package/bin/lib/bot-comandos.js +1 -1
  66. package/bin/swl-ses.js +6 -0
  67. package/comandos/swl/adoptar-proyecto.md +14 -2
  68. package/comandos/swl/configurar-ci.md +8 -1
  69. package/comandos/swl/deuda-codigo.md +97 -97
  70. package/comandos/swl/discutir-fase.md +22 -118
  71. package/comandos/swl/fix.md +118 -0
  72. package/comandos/swl/nuevo-proyecto.md +54 -3
  73. package/comandos/swl/predecir.md +32 -2
  74. package/comandos/swl/seguridad.md +189 -0
  75. package/comandos/swl/status.md +5 -3
  76. package/habilidades/aprendizaje-continuo/SKILL.md +3 -1
  77. package/habilidades/discutir-fase/SKILL.md +84 -81
  78. package/habilidades/discutir-fase/recursos/plantilla-contexto.md +136 -0
  79. package/habilidades/doc-sync/SKILL.md +3 -1
  80. package/habilidades/doubt-driven-review/SKILL.md +15 -1
  81. package/habilidades/ejecutar-task-iterativo/SKILL.md +278 -278
  82. package/habilidades/estructura-proyecto-claude/SKILL.md +11 -2
  83. package/habilidades/harness-claude-code/SKILL.md +3 -1
  84. package/habilidades/instalar-sistema/SKILL.md +3 -1
  85. package/habilidades/meta-reglas-extendido/SKILL.md +92 -0
  86. package/habilidades/meta-reglas-extendido/recursos/analisis-previo-tareas-grandes.md +186 -0
  87. package/habilidades/meta-reglas-extendido/recursos/analizar-directorios-antes-de-escribir.md +235 -0
  88. package/habilidades/meta-reglas-extendido/recursos/api-diseno.md +413 -0
  89. package/habilidades/meta-reglas-extendido/recursos/arquitectura.md +491 -0
  90. package/habilidades/meta-reglas-extendido/recursos/arreglar-al-detectar.md +264 -0
  91. package/habilidades/meta-reglas-extendido/recursos/debatir-antes-de-aceptar.md +152 -0
  92. package/habilidades/meta-reglas-extendido/recursos/git-workflow.md +259 -0
  93. package/habilidades/meta-reglas-extendido/recursos/gobernanza.md +291 -0
  94. package/habilidades/meta-reglas-extendido/recursos/memoria-consolidada.md +263 -0
  95. package/habilidades/meta-reglas-extendido/recursos/seguridad-agentes.md +443 -0
  96. package/habilidades/meta-reglas-extendido/recursos/sesiones-paralelas.md +190 -0
  97. package/habilidades/meta-reglas-extendido/recursos/sin-duplicacion-reglas-globales.md +179 -0
  98. package/habilidades/meta-reglas-extendido/recursos/skills-estandar.md +394 -0
  99. package/habilidades/meta-reglas-extendido/recursos/usar-code-review-graph.md +156 -0
  100. package/habilidades/meta-reglas-extendido/recursos/usar-context7.md +236 -0
  101. package/habilidades/meta-reglas-extendido/recursos/usar-sistema-swl.md +253 -0
  102. package/habilidades/meta-reglas-extendido/recursos/verificar-citas-normativas.md +527 -0
  103. package/habilidades/meta-skills-estandar/SKILL.md +3 -1
  104. package/habilidades/nuevo-proyecto/SKILL.md +20 -3
  105. package/habilidades/php-experto/SKILL.md +10 -3
  106. package/habilidades/{filament-admin/SKILL.md → php-experto/recursos/filament-admin.md} +23 -39
  107. package/habilidades/prevencion-sobreingenieria/recursos/soluciones-nativas.md +166 -166
  108. package/habilidades/prevencion-sobreingenieria/recursos/variables-residuales-post-refactor.md +85 -85
  109. package/habilidades/proceso-debate-adversarial/recursos/personas.md +5 -4
  110. package/habilidades/proceso-ingenieria-requerimientos/SKILL.md +147 -0
  111. package/hooks/check-update.js +19 -10
  112. package/hooks/contexto-subagente.js +68 -68
  113. package/hooks/degradacion-instintos.js +1 -1
  114. package/hooks/extraccion-aprendizajes.js +2 -2
  115. package/hooks/lib/briefing.js +3 -3
  116. package/hooks/lib/nudge-tracker.js +1 -1
  117. package/hooks/lib/otlp-exporter.js +1 -1
  118. package/hooks/lib/webhook-dedup.js +1 -1
  119. package/hooks/session-briefing.js +1 -1
  120. package/llms.txt +6 -6
  121. package/manifiestos/canonical-hashes.json +989 -0
  122. package/manifiestos/hooks-config.json +469 -469
  123. package/manifiestos/invariantes-criticos.json +30 -30
  124. package/manifiestos/modulos.json +168 -135
  125. package/manifiestos/perfiles.json +0 -2
  126. package/manifiestos/skills-lock.json +52 -59
  127. package/package.json +7 -5
  128. package/plantillas/github-workflows/README.md +15 -1
  129. package/plantillas/github-workflows/swl-devsecops.yml +70 -0
  130. package/plugin.json +5 -5
  131. package/reglas/analisis-previo-tareas-grandes.md +30 -156
  132. package/reglas/analizar-directorios-antes-de-escribir.md +30 -211
  133. package/reglas/api-diseno.md +28 -398
  134. package/reglas/arquitectura.md +35 -456
  135. package/reglas/arreglar-al-detectar.md +30 -230
  136. package/reglas/debatir-antes-de-aceptar.md +30 -143
  137. package/reglas/docs.md +7 -0
  138. package/reglas/estilo-codigo.md +9 -0
  139. package/reglas/fragmentos-compartidos.md +6 -0
  140. package/reglas/git-workflow.md +44 -240
  141. package/reglas/gobernanza.md +23 -262
  142. package/reglas/memoria-consolidada.md +34 -228
  143. package/reglas/performance.md +8 -0
  144. package/reglas/pruebas.md +12 -0
  145. package/reglas/seguridad-agentes.md +37 -418
  146. package/reglas/seguridad.md +12 -0
  147. package/reglas/sesiones-paralelas.md +29 -162
  148. package/reglas/sin-duplicacion-reglas-globales.md +25 -166
  149. package/reglas/skills-estandar.md +23 -373
  150. package/reglas/usar-code-review-graph.md +31 -140
  151. package/reglas/usar-context7.md +30 -208
  152. package/reglas/usar-sistema-swl.md +47 -242
  153. package/reglas/verificar-citas-normativas.md +47 -537
  154. package/scripts/actualizar.js +253 -253
  155. package/scripts/audit-tools/auditar-relleno-inventario.js +145 -0
  156. package/scripts/auditar-clases-conocidas.js +106 -0
  157. package/scripts/bootstrap-instintos.js +2 -2
  158. package/scripts/canario-hooks.js +166 -0
  159. package/scripts/cli/configurar-ci.js +2 -1
  160. package/scripts/evidencia-valor.js +93 -0
  161. package/scripts/field-report.js +1 -1
  162. package/scripts/generar-comandos.js +143 -0
  163. package/scripts/generar-inventario.js +236 -23
  164. package/scripts/generar-matriz-lenguajes.js +1 -1
  165. package/scripts/instalador.js +15 -1
  166. package/scripts/lib/configurar-ci.js +10 -3
  167. package/scripts/lib/detectar-runtime.js +12 -3
  168. package/scripts/lib/diary-entry.js +3 -1
  169. package/scripts/lib/drift-detector.js +1 -1
  170. package/scripts/lib/evidencia-valor.js +189 -0
  171. package/scripts/lib/expandir-targets.js +71 -71
  172. package/scripts/lib/frontmatter-md.js +63 -0
  173. package/scripts/lib/parsear-opciones.js +2 -0
  174. package/scripts/lib/prune-componentes.js +180 -0
  175. package/scripts/lib/reglas-globales-conocidas.json +16 -2
  176. package/scripts/lib/scoring-instintos.js +2 -2
  177. package/scripts/lib/toml-merge.js +204 -204
  178. package/scripts/lib/transformadores/claude.js +1 -1
  179. package/scripts/lib/transformadores/codex.js +1 -1
  180. package/scripts/lib/transformadores/copilot.js +1 -1
  181. package/scripts/lib/transformadores/cursor.js +1 -1
  182. package/scripts/lib/transformadores/gemini.js +22 -2
  183. package/scripts/lib/transformadores/opencode.js +1 -1
  184. package/scripts/mcp-server/auth.js +105 -105
  185. package/scripts/mcp-server/cache.js +106 -106
  186. package/scripts/prune.js +102 -0
  187. package/scripts/publicar.js +18 -2
  188. package/scripts/tui/pantallas/inspect.js +175 -175
  189. package/scripts/tui/pantallas/uninstall-wizard.js +210 -210
  190. package/scripts/tui/pantallas/update-wizard.js +234 -234
  191. package/scripts/tui/pantallas/welcome.js +189 -189
  192. package/habilidades/paid-media-tracking/SKILL.md +0 -269
  193. package/habilidades/paid-media-tracking/recursos/auditoria-tracking.md +0 -220
  194. package/habilidades/paid-media-tracking/recursos/google-ads-api.md +0 -215
  195. package/habilidades/tracking-measurement/SKILL.md +0 -239
  196. package/habilidades/tracking-measurement/recursos/consent-mode.md +0 -231
  197. package/habilidades/tracking-measurement/recursos/gtm-datalayer.md +0 -216
  198. package/habilidades/tracking-measurement/recursos/meta-capi.md +0 -262
@@ -0,0 +1,491 @@
1
+ # Arquitectura — extendido
2
+
3
+ > Extendido de `reglas/arquitectura.md` (Fase D, dieta de contexto). El núcleo
4
+ > instalado es la norma; aquí viven templates, ejemplos y casos completos.
5
+
6
+ ## Índice
7
+
8
+ - [ADRs — Architecture Decision Records](#adrs--architecture-decision-records)
9
+ - [Análisis de repositorios externos — filtro de dominio obligatorio](#análisis-de-repositorios-externos--filtro-de-dominio-obligatorio)
10
+ - [Módulos profundos — interfaz pequeña, implementación rica](#módulos-profundos--interfaz-pequeña-implementación-rica)
11
+ - [Dependency Injection (DI)](#dependency-injection-di)
12
+ - [Separación de concerns](#separación-de-concerns)
13
+ - [Sin dependencias circulares](#sin-dependencias-circulares)
14
+ - [SOLID](#solid)
15
+ - [Tres capas de reutilización: regla, skill, fragmento](#tres-capas-de-reutilización-regla-skill-fragmento)
16
+ - [DRY — Don't Repeat Yourself](#dry--dont-repeat-yourself)
17
+ - [Patrones de arquitectura reconocidos](#patrones-de-arquitectura-reconocidos)
18
+ - [Tablas append-only — excepción documentada a "audit columns nullable=False"](#tablas-append-only--excepción-documentada-a-audit-columns-nullablefalse)
19
+ - [Split modular con compositor por herencia múltiple](#split-modular-con-compositor-por-herencia-múltiple)
20
+ - [Reglas de desempate entre principios (conflict resolution)](#reglas-de-desempate-entre-principios-conflict-resolution)
21
+ - [Checklist arquitectural antes de implementar una feature](#checklist-arquitectural-antes-de-implementar-una-feature)
22
+
23
+ ---
24
+
25
+ ## ADRs — Architecture Decision Records
26
+
27
+ Toda decisión de arquitectura significativa debe documentarse como un ADR.
28
+
29
+ ¿Qué es significativa? Una decisión que:
30
+ - Afecta más de un módulo o equipo
31
+ - Es difícil o costosa de revertir
32
+ - Tiene alternativas viables que fueron consideradas
33
+ - El equipo debatió más de 15 minutos
34
+
35
+ Formato mínimo de un ADR (`docs/adr/NNN-titulo-corto.md`):
36
+ ```markdown
37
+ # ADR NNN: Título de la decisión
38
+
39
+ **Fecha**: YYYY-MM-DD
40
+ **Estado**: Propuesto | Aceptado | Deprecado | Reemplazado por ADR-NNN
41
+
42
+ ## Contexto
43
+ Qué situación o problema motivó esta decisión.
44
+
45
+ ## Decisión
46
+ Qué se decidió hacer.
47
+
48
+ ## Consecuencias
49
+ Qué implica esta decisión — positivo, negativo, neutral.
50
+
51
+ ## Alternativas consideradas
52
+ Qué más se evaluó y por qué se descartó.
53
+ ```
54
+
55
+ Reglas de ADRs:
56
+ - Numerados secuencialmente, nunca reutilizar un número.
57
+ - Inmutables: si una decisión cambia, crear un nuevo ADR que referencia al anterior.
58
+ - Versionar con el código — viven en el repositorio.
59
+ - Revisar ADRs existentes antes de proponer arquitectura nueva.
60
+
61
+ ### ADRs en estado Propuesto
62
+
63
+ Un ADR en estado `Propuesto` documenta una decisión evaluada pero **no implementada
64
+ todavía** — por ejemplo porque depende de factores externos (roadmap de un tercero,
65
+ evidencia futura que hoy no existe, señal de demanda que aún no aparece). Mantener
66
+ ADRs en Propuesto indefinidamente sin plan de cierre genera deuda silenciosa —
67
+ propuestas que "quedan ahí" y nadie revisa.
68
+
69
+ **Todo ADR en estado Propuesto DEBE incluir:**
70
+
71
+ 1. **Criterios de disparo** — lista concreta de condiciones que reabren la decisión
72
+ (al menos una por entrada). Ejemplos: "El usuario pide X", "Anthropic publica Y",
73
+ "Contador supera umbral Z".
74
+ 2. **Fecha límite de reevaluación automática** — entre 6 y 12 meses desde la fecha
75
+ de creación del ADR. Si ninguno de los criterios se cumple antes de la fecha,
76
+ el ADR se mueve a `Descartado` documentando la decisión final.
77
+
78
+ Un ADR Propuesto sin ambos elementos NO es aceptable — se rechaza en revisión.
79
+
80
+ **Índice obligatorio**: el archivo `docs/adr/README.md` (o `.planning/adrs/README.md`
81
+ en SWL) lista todos los ADRs con estado y fecha de reevaluación visible. Cualquier
82
+ persona debe poder ver en una lectura si hay ADRs vencidos sin abrir cada archivo.
83
+
84
+ ---
85
+
86
+ ## Análisis de repositorios externos — filtro de dominio obligatorio
87
+
88
+ Cuando se analiza un repositorio ajeno para enriquecer el sistema SWL (código en
89
+ `temp/`, dependencias, proyectos de referencia), **el primer paso antes de cualquier
90
+ análisis profundo** es aplicar el filtro de dominio:
91
+
92
+ > *¿Le sirve esto a un ingeniero de software en cualquier proyecto de software?*
93
+
94
+ Si la respuesta es **NO** porque el repositorio vive en un dominio vertical externo
95
+ (fintech/billing, ML Ops, data science, bio-informática, dominios regulados
96
+ específicos, etc.), descartar el 80-95% del contenido sin análisis profundo.
97
+
98
+ **Lo que siempre vale la pena extraer aunque el dominio sea externo:**
99
+
100
+ - Patrones de configuración de Claude Code: `.claude/settings.json`, hooks, comandos
101
+ - Patrones de arquitectura transversales: repository pattern, service layer, etc.
102
+ - Configuraciones de CI/CD, Docker, pre-commit
103
+ - Patrones de testing, observabilidad, auth
104
+
105
+ **Lo que se descarta sin análisis aunque esté bien escrito:**
106
+
107
+ - Lógica de negocio específica del dominio externo
108
+ - Integraciones con servicios verticales (Stripe fintech, servicios de ML Ops,
109
+ procesadores de señales médicas)
110
+ - Documentación de producto/handbook organizacional
111
+
112
+ **Patrón validado**: análisis de `temp/polar-main` (fintech, 86 módulos) en
113
+ sesión 2026-04-23 → 3% integrado (3 patrones transversales), 97% descartado sin
114
+ análisis profundo. Análisis de `temp/estilo-sin-ai-isms` (ecosistema auditor
115
+ OIC-INE) → 10% integrado. Aplicar el filtro primero ahorra horas de análisis
116
+ de código irrelevante.
117
+
118
+ ---
119
+
120
+ ## Módulos profundos — interfaz pequeña, implementación rica
121
+
122
+ El principio de módulos profundos (John Ousterhout — A Philosophy of Software Design):
123
+
124
+ - La interfaz pública de un módulo debe ser MÍNIMA en comparación con la
125
+ complejidad que encapsula.
126
+ - Un módulo profundo oculta decisiones de implementación detrás de una abstracción
127
+ simple. Quien lo usa no necesita conocer los detalles.
128
+ - Un módulo shallow tiene una interfaz casi tan compleja como su implementación
129
+ — ofrece poco valor de abstracción.
130
+
131
+ Señales de módulo shallow a corregir:
132
+ - Una clase con 15 métodos públicos donde 12 son getters/setters triviales.
133
+ - Un service que solo pasa llamadas a otro service sin agregar lógica.
134
+ - Una función que solo llama a otra función con los mismos parámetros.
135
+
136
+ Cómo diseñar módulos profundos:
137
+ - Definir la interfaz pública primero, antes de implementar.
138
+ - La interfaz solo expone lo que el llamador NECESITA, no lo que es conveniente.
139
+ - La implementación puede ser compleja — eso es el punto.
140
+ - Documentar la interfaz, no la implementación (la implementación se explica sola
141
+ con código limpio).
142
+
143
+ ---
144
+
145
+ ## Dependency Injection (DI)
146
+
147
+ - Nunca instanciar dependencias dentro de una clase o función.
148
+ Las dependencias se RECIBEN, no se crean.
149
+
150
+ Mal:
151
+ ```python
152
+ class FacturaService:
153
+ def __init__(self):
154
+ self.db = DatabaseConnection() # dependencia hardcodeada
155
+ self.mailer = SmtpMailer() # imposible de mockear en tests
156
+ ```
157
+
158
+ Bien:
159
+ ```python
160
+ class FacturaService:
161
+ def __init__(self, db: AsyncSession, mailer: MailerProtocol):
162
+ self.db = db
163
+ self.mailer = mailer
164
+ ```
165
+
166
+ - Usar el contenedor de DI del framework (FastAPI Depends, Angular DI).
167
+ - Inyectar interfaces/protocolos, no implementaciones concretas.
168
+ - El grafo de dependencias fluye en una dirección: alto nivel → bajo nivel.
169
+ Nunca al revés.
170
+
171
+ ---
172
+
173
+ ## Separación de concerns
174
+
175
+ Cada módulo tiene UNA responsabilidad principal. Las capas del sistema:
176
+
177
+ | Capa | Responsabilidad | Lo que NO hace |
178
+ |------|----------------|----------------|
179
+ | Endpoints / Controllers | Recibir HTTP, delegar al service, devolver respuesta | Lógica de negocio |
180
+ | Services | Lógica de negocio, orquestación | Queries SQL directas, formateo HTTP |
181
+ | Repositories / DAL | Acceso a datos, queries | Lógica de negocio |
182
+ | Schemas / DTOs | Validación y serialización | Lógica de negocio |
183
+ | Models / ORM | Estructura de datos en BD | Lógica de negocio |
184
+
185
+ Reglas estrictas:
186
+ - Los endpoints no contienen lógica de negocio — llaman al service.
187
+ - Los services no hacen `db.commit()` — el endpoint hace el commit.
188
+ - Los models ORM no contienen lógica de negocio compleja — solo helpers
189
+ de presentación simples.
190
+ - Los schemas Pydantic no acceden a la BD directamente.
191
+
192
+ ---
193
+
194
+ ## Sin dependencias circulares
195
+
196
+ - El grafo de dependencias entre módulos debe ser un DAG (grafo dirigido acíclico).
197
+ - Módulo A importa a Módulo B → Módulo B NO puede importar a Módulo A.
198
+ - Detectar con `import-linter` (Python) o `eslint-plugin-import` (TypeScript).
199
+ - Si se detecta una dependencia circular: extraer el tipo o la función compartida
200
+ a un módulo de bajo nivel del que ambos dependan.
201
+ - La solución NUNCA es `importlib.import_module()` para romper el ciclo en runtime.
202
+
203
+ Señales de dependencias circulares inminentes:
204
+ - Dos módulos que se referencian mutuamente "solo para un tipo".
205
+ - Un módulo `utils` o `helpers` que importa módulos de negocio.
206
+ - Un modelo ORM que importa un service.
207
+
208
+ ---
209
+
210
+ ## SOLID
211
+
212
+ **S — Single Responsibility**: Una clase/módulo, un eje de cambio.
213
+ Si una clase cambia por dos razones distintas, tiene dos responsabilidades.
214
+
215
+ **O — Open/Closed**: Abierto para extensión, cerrado para modificación.
216
+ Agregar funcionalidad nueva sin modificar código existente (usando herencia,
217
+ composición o strategy pattern, no if/else interminables).
218
+
219
+ **L — Liskov Substitution**: Un subtipo puede reemplazar a su supertipo.
220
+ Si se hereda de una clase, la subclase debe honrar el contrato de la base.
221
+ No lanzar excepciones que la base no lanza, no ignorar parámetros.
222
+
223
+ **I — Interface Segregation**: Interfaces pequeñas y específicas.
224
+ No forzar a una clase a implementar métodos que no usa. Preferir varias
225
+ interfaces pequeñas sobre una grande.
226
+
227
+ **D — Dependency Inversion**: Depender de abstracciones, no de implementaciones.
228
+ Los módulos de alto nivel no dependen de los de bajo nivel — ambos dependen
229
+ de abstracciones (protocolos, interfaces, clases abstractas).
230
+
231
+ ---
232
+
233
+ ## Tres capas de reutilización: regla, skill, fragmento
234
+
235
+ El sistema SWL distingue tres capas para evitar duplicación. La elección de la
236
+ capa correcta depende de cuándo y cómo se carga el contenido:
237
+
238
+ - **Regla** (`reglas/X.md`): política global cargada por matcher de archivos.
239
+ Aplicable a múltiples agentes y skills. Ejemplo: `reglas/seguridad.md`.
240
+ - **Skill** (`habilidades/X/SKILL.md`): conocimiento operacional invocado
241
+ dinámicamente con `Skill("X")`. Tiene frontmatter, descripción y carga
242
+ bajo demanda. Ejemplo: `habilidades/tdd-workflow/SKILL.md`.
243
+ - **Fragmento** (`agentes/_X.md`): bloque de prompt compartido por varios
244
+ agentes que se incrusta literalmente en su system prompt. Sin overhead
245
+ runtime, sin frontmatter operacional, no routable por el orquestador.
246
+ Ejemplo: `agentes/_hitl-alto-riesgo.md`.
247
+
248
+ Antes de crear texto compartido entre agentes, decidir cuál capa aplica. Ver
249
+ `reglas/fragmentos-compartidos.md` para la convención completa.
250
+
251
+ ---
252
+
253
+ ## DRY — Don't Repeat Yourself
254
+
255
+ Si una regla de negocio, una validación, un cálculo o una transformación cambia,
256
+ debe cambiar en un solo lugar. Si requiere cambiar en dos o más, hay duplicación
257
+ de conocimiento.
258
+
259
+ Estrategias para eliminar duplicación según el tipo:
260
+
261
+ - **Lógica de negocio duplicada entre services** → extraer a un service compartido
262
+ o un domain method.
263
+ - **Queries duplicadas** → extraer a un método del repositorio.
264
+ - **Validaciones repetidas** → centralizar en schemas (Pydantic, Zod, Bean Validation).
265
+ - **Configuración repetida** → extraer a variables de entorno o módulo de configuración.
266
+ - **Transformaciones de datos repetidas** → extraer a un mapper o utility function.
267
+
268
+ DRY aplica entre capas: si el frontend valida lo mismo que el backend, el backend
269
+ es la fuente de verdad. La validación del frontend es UX, no lógica de negocio.
270
+
271
+ DRY NO justifica abstracciones prematuras. Si la duplicación es casual (dos cosas
272
+ iguales hoy que cambiarán independientemente mañana), dejar duplicado es correcto.
273
+ DRY aplica cuando el conocimiento subyacente es el mismo.
274
+
275
+ ---
276
+
277
+ ## Patrones de arquitectura reconocidos
278
+
279
+ Antes de inventar una solución arquitectural nueva, verificar si alguno de
280
+ estos patrones resuelve el problema:
281
+
282
+ - **Repository Pattern**: Para abstraer el acceso a datos.
283
+ - **Command/Query Separation (CQS)**: Operaciones que cambian estado vs. las que leen.
284
+ - **Event-driven**: Para desacoplar productores de consumidores.
285
+ - **Strangler Fig**: Para migración incremental de sistemas legados.
286
+ - **Adapter**: Para integrar sistemas externos con interfaces incompatibles.
287
+ - **Saga**: Para transacciones distribuidas entre microservicios.
288
+
289
+ Documentar en un ADR qué patrón se usa y por qué.
290
+
291
+ ---
292
+
293
+ ## Tablas append-only — excepción documentada a "audit columns nullable=False"
294
+
295
+ Algunas tablas son **append-only por diseño**: solo se crean filas (INSERT) y
296
+ eventualmente se eliminan por purga (DELETE). Nunca se actualizan. Ejemplos
297
+ típicos: logs de errores (`bitacora_error`, `error_log`), audit trails inmutables,
298
+ telemetría, métricas históricas, event sourcing event store, outbox pattern.
299
+
300
+ Para estas tablas la regla general del proyecto "`created_by`/`updated_by`
301
+ `nullable=False` en tablas transaccionales" **NO aplica**. Documentar la
302
+ excepción explícitamente:
303
+
304
+ 1. En el **docstring de la clase modelo** (Python/Java/C#):
305
+
306
+ ```python
307
+ class BitacoraError(Base):
308
+ """
309
+ Registro inmutable de un error backend o frontend.
310
+
311
+ Tabla append-only: solo se crean filas (INSERT) y se purgan por antigüedad
312
+ (DELETE). Nunca se actualizan. Esta invariante es fundamental para que el
313
+ log de errores sea un audit trail confiable.
314
+
315
+ Excepción a regla "audit columns nullable=False":
316
+ La convención del proyecto exige `created_by` y `updated_by` NOT NULL
317
+ en tablas transaccionales. BitacoraError queda exenta porque:
318
+ (a) Es un log del sistema, no una entidad de negocio modificable.
319
+ (b) No tiene `updated_at` ni `updated_by` — no hay concepto de
320
+ "última modificación" en una tabla append-only.
321
+ (c) `usuario_id` es nullable de forma intencional: los errores de
322
+ sesiones no autenticadas (401 antes del login) no tienen usuario.
323
+ """
324
+ ```
325
+
326
+ 2. En el **comentario del DDL SQL**:
327
+
328
+ ```sql
329
+ COMMENT ON TABLE bitacora_error IS
330
+ 'Errores backend y frontend persistidos para diagnóstico. '
331
+ 'Append-only: solo INSERT y DELETE (purga). '
332
+ 'Sin updated_at/updated_by por diseño (excepción documentada en CONTEXTO).';
333
+ ```
334
+
335
+ 3. En el **GRANT** del rol de aplicación, omitir explícitamente `UPDATE`:
336
+
337
+ ```sql
338
+ -- INSERT: para que el sistema cree entradas.
339
+ -- SELECT: para que el admin las consulte.
340
+ -- DELETE: para que el job de purga elimine antiguas.
341
+ -- NO UPDATE: la tabla es append-only por diseño.
342
+ GRANT SELECT, INSERT, DELETE ON bitacora_error TO ine_user;
343
+ ```
344
+
345
+ **Criterios para considerar una tabla append-only legítima**:
346
+
347
+ - Toda fila representa un evento ocurrido en un momento específico (immutable in time).
348
+ - No hay caso de negocio que requiera modificar la fila después de creada.
349
+ - La única forma de "corregir" un dato erróneo es insertar una fila correctora
350
+ posterior (event sourcing) o purgar y re-insertar (telemetría).
351
+ - El borrado se hace por política de retención (antigüedad), no por revocación.
352
+
353
+ **Origen del patrón**: OIC v1.5 Slice 1 (2026-06-04). Patrón portable a cualquier
354
+ proyecto con logs estructurados, audit trails o event sourcing.
355
+
356
+ ---
357
+
358
+ ## Split modular con compositor por herencia múltiple
359
+
360
+ Cuando un módulo backend (router, service, repository) supera ~1500 LOC en un
361
+ solo archivo y contiene sub-dominios identificables, aplicar el playbook de
362
+ split documentado en `Skill("proceso-modular-split")`. El patrón clave:
363
+
364
+ - **Compositor por herencia múltiple, NO `__getattr__`**: el compositor (clase
365
+ monolítica que mantiene API pública previa) hereda de cada sub-service. MRO
366
+ inspeccionable, type checker feliz, IDE autocompleta. `__getattr__` para
367
+ delegación es opaco al tipado y al stack trace.
368
+
369
+ - **Helpers transversales en clase base, no duplicados entre sub-services**: si
370
+ un helper como `_validar_predio_existe` lo usan ≥80% de sub-services, vive
371
+ en `<modulo>/service_base.py` (`<Modulo>ServiceBase`). Cada sub-service
372
+ hereda de la base. Si solo lo usan 1-2 sub-services, vive en uno de ellos y
373
+ los demás importan por composición (no por herencia).
374
+
375
+ - **Helper transversal cross-sub-service NO se duplica**: validación que
376
+ aparece en ≥3 sub-services es candidata inmediata a la clase base. La
377
+ duplicación es señal de que el split fue prematuro o de que se perdió el
378
+ helper común durante la migración.
379
+
380
+ - **Validar a escala**: el patrón se validó a ~20,000 LOC totales en SIGM
381
+ (recaudación ADR-0016 + catastro ADR-0017). Aplicar al primer módulo es
382
+ prudente; antes de aplicar a un tercero, confirmar que el feedback de los
383
+ dos primeros no requiere ajuste al playbook.
384
+
385
+ Anti-patrones a evitar (las auditorías técnicas NO los detectan):
386
+
387
+ - Router que importa el compositor cuando existe sub-service específico.
388
+ - Router que accede a `servicio._repo` o métodos privados del sub-service.
389
+ - Default `None` pasado explícitamente bypasea el default del callee.
390
+ - CLAUDE.md y AGENTS.md desincronizados tras el refactor.
391
+
392
+ Estos los detecta revisión de arquitectura humana o senior, no `nemesis-auditor-swl`.
393
+
394
+ ---
395
+
396
+ ## Reglas de desempate entre principios (conflict resolution)
397
+
398
+ Los principios de ingeniería pueden entrar en tensión. Cuando dos reglas
399
+ correctas en abstracto sugieren caminos opuestos, aplicar las siguientes
400
+ heurísticas de desempate. Origen: síntesis adaptada de "Unified Software
401
+ Engineering" (M. Ciemborowicz, MIT) más experiencia operativa de SWL.
402
+
403
+ ### Simplicidad vs. modelado rico
404
+
405
+ - Empezar con el diseño **más simple** que represente honestamente el problema.
406
+ - CRUD administrativo y workflows lineales: usar transaction script o
407
+ service layer simple.
408
+ - Reglas de negocio complejas, invariantes, ciclos de vida y lenguaje
409
+ específico del dominio: justificar modelado más rico (DDD táctico).
410
+ - NO usar patrones de DDD como ceremonia en subdominios genéricos.
411
+ - NO aplanar complejidad real del dominio en records pasivos y servicios
412
+ procedurales — eso lo único que hace es desplazar la complejidad al caller.
413
+
414
+ ### Funciones pequeñas vs. módulos profundos
415
+
416
+ - Funciones pequeñas son una herramienta, no un objetivo en sí mismo.
417
+ - Preferir funciones pequeñas cuando clarifican intención, aíslan
418
+ responsabilidad o simplifican testing.
419
+ - Evitar cadenas de funciones triviales que solo pasan parámetros (pass-through)
420
+ y obligan al lector a saltar entre archivos para entender una operación.
421
+ - Un módulo puede tener implementación interna compleja siempre que su
422
+ interfaz pública sea pequeña, significativa y estable (módulo profundo).
423
+
424
+ ### DRY vs. abstracción prematura
425
+
426
+ - DRY aplica a duplicación de **conocimiento**, no de texto.
427
+ - Centralizar reglas de negocio, validaciones, mappings y cálculos.
428
+ - Mantener código similar separado cuando la similitud es **coincidente**
429
+ o cuando la abstracción compartida sería vaga ("regla de tres" antes
430
+ de extraer).
431
+ - Tres líneas de código duplicado son mejores que una abstracción
432
+ prematura que después haya que romper.
433
+
434
+ ### Boundaries vs. over-engineering
435
+
436
+ - Introducir boundaries explícitas alrededor de: volatilidad, sistemas
437
+ externos, persistencia, frameworks, tiempo, aleatoriedad y traducción
438
+ cross-context.
439
+ - NO agregar capas que solo reenvían llamadas (forwarding-only layers).
440
+ - Toda abstracción debe cumplir **al menos uno** de estos criterios:
441
+ reducir acoplamiento, ocultar complejidad, clarificar ownership, o
442
+ proteger un contrato. Si no cumple ninguno, eliminar la abstracción.
443
+
444
+ ### Consistencia fuerte vs. eventual
445
+
446
+ - Proteger invariantes que **deben** cumplirse de forma inmediata dentro
447
+ del menor boundary de consistencia útil.
448
+ - Default razonable: un aggregate o una transacción local como unidad
449
+ atómica.
450
+ - Usar consistencia eventual entre aggregates, servicios o contextos
451
+ cuando la consistencia inmediata no sea un requisito real de negocio.
452
+ - Hacer **siempre explícitas** las semánticas de consistencia, staleness,
453
+ conflicto y retry — nunca implícitas.
454
+
455
+ ### Comentarios vs. código auto-documentado
456
+
457
+ - Mejorar nombres y estructura **antes** de agregar comentarios.
458
+ - Comentarios válidos: contratos, invariantes, racional de decisiones
459
+ no-obvias, restricciones legales o regulatorias, asunciones sobre
460
+ protocolos externos.
461
+ - Eliminar comentarios que narran código obvio, repiten nombres o
462
+ describen comportamiento obsoleto.
463
+
464
+ ### Refactor vs. preservar comportamiento
465
+
466
+ - Refactoring debe preservar el comportamiento observable. Sin excepciones.
467
+ - Si el comportamiento debe cambiar, mantener el cambio funcional **separado
468
+ del refactor estructural** cuando sea práctico (commits independientes).
469
+ - Preferir transformaciones pequeñas y verificables sobre rewrites grandes.
470
+
471
+ ### Cómo aplicar este desempate
472
+
473
+ Cuando dos principios chocan en una decisión concreta, no inventar
474
+ síntesis nuevas — aplicar la heurística arriba según el caso. Si ninguna
475
+ aplica, escalar al `arquitecto-swl` con la disyuntiva concreta y dos
476
+ opciones evaluadas. Documentar la decisión en un ADR si tiene impacto
477
+ estructural.
478
+
479
+ ---
480
+
481
+ ## Checklist arquitectural antes de implementar una feature
482
+
483
+ - [ ] ¿La decisión requiere un ADR? Si sí, está redactado.
484
+ - [ ] ¿El módulo nuevo tiene una interfaz más pequeña que su implementación?
485
+ - [ ] ¿Las dependencias fluyen en una sola dirección?
486
+ - [ ] ¿Hay separación clara de concerns entre capas?
487
+ - [ ] ¿El módulo puede testearse de forma aislada?
488
+ - [ ] ¿Se revisaron ADRs existentes para no contradecirlos?
489
+ - [ ] ¿No hay duplicación de lógica de negocio entre módulos o capas?
490
+ - [ ] Si dos principios entran en tensión, ¿se aplicó la regla de
491
+ desempate correspondiente y la decisión está justificada?