Distribución de ensamblados y paquetes transversales de la suite Evolith.
Un artefacto es transversal cuando más de un producto lo consume. Ese es el único criterio de admisión: no es un cajón de "librerías útiles", es el sitio donde vive lo que cruza fronteras de producto y por tanto necesita versionado, contrato y política de publicación propios.
La suite ya distribuía artefactos, pero sin política: cada producto publicaba donde le convenía, o no publicaba. El resultado, medido el 2026-07-18:
| Artefacto | Dónde estaba | Estado |
|---|---|---|
BeyondNetCode.Shell.* |
nuget.org | Público |
@beyondnet/evolith-* |
npm | Público |
Ums.Sdk.* |
GitHub Packages | Privado — la única pieza inconsistente |
Evolith.Messaging.Contracts |
— | Sin publicar, pese a que Tracker debe consumirlo (DS-12) |
Dos consecuencias concretas y no hipotéticas:
- Un satélite quedó bloqueado por distribución, no por diseño. El contrato de identidad de UMS existía, compilaba y era consumible, pero nadie lo publicaba: existía como fuente con metadatos de paquete, no como artefacto. Evolith Tracker no pudo adoptarlo (ADR T-040).
- Un consumidor mantiene una copia local de un contrato compartido porque el paquete compartido
no existe en ningún feed (
DS-12, copia local deTenantEvent).
Este repositorio es la respuesta: un sitio, una política, un pipeline.
Sí:
- Kernel y plataforma compartidos entre productos (DDD, AOP, bootstrapper, factory).
- Contratos consumidos por más de un producto — mensajería, identidad, evaluación.
- SDKs de cliente que un producto publica para que otros lo consuman.
No:
- Código de un solo producto, por muy reutilizable que parezca. Un artefacto con un consumidor no es transversal: es una librería interna, y sacarla aquí sólo añade una frontera de versionado que nadie necesita todavía.
- Aplicaciones, servicios desplegables, infraestructura.
- Forks o copias de dependencias de terceros.
Regla de promoción: un artefacto entra cuando aparece su segundo consumidor, no cuando alguien anticipa que podría tenerlo. La especulación es lo que produce catálogos llenos de paquetes que nadie usa y que igualmente hay que versionar.
| Decisión | Regla |
|---|---|
| Registro | Un artefacto transversal se publica una vez, en un solo sitio. Nada de publicar el mismo paquete en dos registros. |
| Versionado | SemVer. Un cambio incompatible es major, sin excepciones y sin "es que sólo lo usa Tracker". |
| Inmutabilidad | Una versión publicada no se reescribe. Si sale mal, se publica la siguiente. |
| Trazabilidad | Todo paquete declara RepositoryUrl para quedar vinculado a su origen. Sin eso, el registro no puede heredar permisos ni nadie puede volver al código. |
| Quién publica | El pipeline, no una persona. Una publicación manual es una excepción y se documenta. |
nuget.org, público. BeyondNet Code es una organización open source: sus artefactos están
pensados para consumirse, y BeyondNetCode.Shell.* y @beyondnet/evolith-* ya viven en registros
públicos. Un artefacto transversal no gana nada escondiéndose y sí pierde: cada consumidor paga
credenciales en CI para leer algo que de todas formas es público.
Se evaluó GitHub Packages como alternativa por una razón legítima —una versión equivocada allí
se puede borrar, mientras que en nuget.org sólo se puede ocultar— y se descartó como opción por
defecto. El motivo: su registro NuGet exige autenticación para restaurar incluso en paquetes de
repositorios públicos, de modo que cada consumidor necesita nuget.config con credenciales en CI.
Esa fricción es diaria; la reversibilidad se necesita en el caso raro. Cambiar el caso común para
optimizar el raro fue un error concreto de esta suite: los Ums.Sdk.* se publicaron ahí el
2026-07-18 y se convirtieron en el único artefacto privado de un ecosistema público, bloqueando el
CI de un consumidor.
La respuesta a "publiqué una versión mala" no es poder borrarla: es publicar la siguiente. Eso ya está en la regla de inmutabilidad de la tabla anterior.
Excepción — GitHub Packages: un artefacto en incubación, todavía sin contrato estable ni segundo consumidor. En cuanto lo tiene, se promueve a nuget.org.
src/ ensamblados transversales, uno por directorio
docs/ decisiones de distribución y catálogo
.github/ pipeline de empaquetado y publicación
Repositorio recién creado. Todavía no aloja ningún ensamblado: la estructura y la política existen antes que el contenido, a propósito, para que la migración se decida artefacto por artefacto en lugar de volcarlo todo de golpe.
Candidatos identificados, por orden de urgencia:
Evolith.Messaging.Contracts— no existe en ningún feed y ya tiene consumidor esperando (DS-12). Es el caso más claro: contrato compartido sin publicar.Ums.Sdk.*— publicado el 2026-07-18 desde el repositorio de UMS. Decidir si su origen se queda allí (es un SDK de producto) o pasa aquí (es consumido por otros).BeyondNetCode.Shell.*— ya público y estable en nuget.org. Migrar el origen no es urgente y romperlo sí sería caro; evaluar sólo si aparece una razón concreta.
Organización: beyondnetcode · Suite Evolith