From 098bba69f91f1686c081b3fcb5a0cb670ac0bf7f Mon Sep 17 00:00:00 2001 From: aarroyo Date: Sat, 19 Sep 2026 09:05:30 -0500 Subject: [PATCH] docs(readme): tabla comparativa con ArchUnit, dependency-cruiser y Conftest (EN/ES) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La portada decía «no sustituye a ArchUnit, Conftest ni dependency-cruiser; los complementa» sin decir en qué se diferencian. Es lo primero que busca quien evalúa la herramienta, y sin tabla lo rellena con lo que supone. Nueva sección «How it compares» / «Cómo se compara» entre «What is inside» y «What it is not», enlazada en la navegación: nueve filas (qué lee, lenguaje de reglas, dónde viven, qué pasa con una regla que no se evaluó, código de salida, superficies, reglas desde ADRs, alcance de lenguaje, licencia). Cada celda ajena está verificada contra la documentación de la herramienta el 2026-09-19, no recordada: - ArchUnit: `archRule.failOnEmptyShould` activo por defecto — falla una regla cuyo `should` recibe un conjunto vacío (userguide §Configuration). Se le reconoce, porque es el pariente más cercano de nuestro `skipped`. - dependency-cruiser: `severity: ignore` no comprueba la regla; el reporter `err` sale con el número de violaciones `error` (doc/rules-reference.md, doc/cli.md). - Conftest: exit 1 solo con fallos; `--fail-on-warn` → 0/1/2; políticas compartibles con `conftest pull` git/OCI (docs/options.md, docs/sharing.md). La columna de Evolith repite lo que la portada ya afirma (skipped de primera clase, taxonomía 0/1/2/3, cuatro superficies, sin AST, Node/TS para las reglas de dependencias), sin añadir ninguna afirmación nueva. Co-Authored-By: Claude Opus 5 --- README.es.md | 22 +++++++++++++++++++++- README.md | 22 +++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/README.es.md b/README.es.md index 78f296c73..755e6c10b 100644 --- a/README.es.md +++ b/README.es.md @@ -25,7 +25,7 @@ Y no es solo un linter: **las reglas van atadas a la fase SDLC del producto.** E Es para equipos que quieren sus decisiones de arquitectura aplicadas en CI y no revisadas a mano, para plataformas que bloquean artefactos no conformes antes de producción, y para agentes de IA que necesitan validar su propia salida contra las mismas reglas. -[Pruébalo](#pruébalo-en-dos-minutos) · [Cuatro términos](#cuatro-términos-que-necesitas) · [En CI](#en-ci) · [Qué hay dentro](#qué-hay-dentro) · [Qué no es](#qué-no-es) · [Documentación](#documentación) · [Atlas interactivo](https://beyondnetcode.github.io/evolith_arch32/) +[Pruébalo](#pruébalo-en-dos-minutos) · [Cuatro términos](#cuatro-términos-que-necesitas) · [En CI](#en-ci) · [Qué hay dentro](#qué-hay-dentro) · [Cómo se compara](#cómo-se-compara) · [Qué no es](#qué-no-es) · [Documentación](#documentación) · [Atlas interactivo](https://beyondnetcode.github.io/evolith_arch32/) --- @@ -95,6 +95,26 @@ Cuántas reglas, packs y ADRs carga tu instalación lo imprime `evolith rulesets --- +## Cómo se compara + +Las herramientas a las que uno acude primero comprueban cosas distintas, y las diferencias están en las filas, no en los adjetivos. Verificado contra la documentación de cada herramienta el 2026-09-19; las correcciones son bienvenidas como PR. + +| | ArchUnit | dependency-cruiser | Conftest | Evolith | +|---|---|---|---|---| +| **Qué lee** | Bytecode de la JVM: clases, paquetes, capas | El grafo de imports de módulos JS/TS | Ficheros de configuración estructurados (YAML, JSON, HCL, Dockerfile…) | El repositorio alrededor del código: layout, workflows, manifiestos, ADRs — **no** el AST | +| **Lenguaje de reglas** | DSL fluido en Java, ejecutado como tests unitarios | Configuración JSON/JS (`forbidden` / `allowed`) | Rego | Rego, compilado a Wasm, en packs JSON | +| **Dónde viven las reglas** | En el código, por repositorio | En el repositorio (`.dependency-cruiser.js`) | Un directorio de políticas; compartible con `conftest pull` (git, OCI) | Una biblioteca fuera de los repositorios, adoptada por repositorio con `--select` | +| **Una regla que no se evaluó** | Falla la regla cuyo `should` recibió un conjunto vacío (`failOnEmptyShould`, activo por defecto) | `severity: ignore` la omite en silencio; no existe otro resultado | Sin resultado: un `deny` indefinido es un aprobado | `skipped` es un veredicto de primera clase, contado junto a `passed` y `failed`; un `skipped` **bloqueante** hace fallar la ejecución | +| **Código de salida** | Un test unitario que falla | El número de violaciones `error` | `1` si falla (`0`/`1`/`2` con `--fail-on-warn`) | `0` pasa · `1` falló la herramienta · `2` el gate bloqueó · `3` invocación inválida | +| **Superficies** | Tests Java | CLI (+ grafos de dependencias) | CLI | CLI · GitHub Action · servidor MCP · API REST | +| **Reglas derivadas de ADRs** | — | — | — | Sí: `evolith adr create`, y muchos packs se derivan de decisiones | +| **Alcance de lenguaje** | JVM | JavaScript / TypeScript | Cualquier fichero estructurado | Cualquier repositorio para reglas estructurales, de CI/CD y de ADR; Node/TypeScript para las de dependencias y linters | +| **Licencia** | Apache-2.0 | MIT | Apache-2.0 | MIT | + +Son complementos, no sustitutos: ArchUnit y dependency-cruiser ven *dentro* del código, Conftest ve un fichero cada vez, Evolith ve el repositorio como unidad gobernada y cuenta lo que no pudo decidir. Ejecutar Evolith junto a una de ellas es la configuración prevista. + +--- + ## Qué no es - **No sustituye a ArchUnit, Conftest ni dependency-cruiser; los complementa.** Las reglas viven fuera del código, como datos que gobiernan muchos repositorios y que un agente puede leer. Evolith *es* OPA por debajo y añade la biblioteca de reglas, la derivación de ADR a regla y la contabilidad de cobertura. diff --git a/README.md b/README.md index d46710c74..7f61b648a 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ And it is not only a linter: **the rules are tied to the product's SDLC phase.** It is for engineering teams that want their architecture decisions enforced in CI rather than reviewed by hand, for platform teams blocking non-conformant artifacts before production, and for AI agents that need to validate their own output against the same rules. -[Try it](#try-it-in-two-minutes) · [Four terms](#four-terms-you-need) · [In CI](#in-ci) · [What is inside](#what-is-inside) · [What it is not](#what-it-is-not) · [Documentation](#documentation) · [Interactive atlas](https://beyondnetcode.github.io/evolith_arch32/) +[Try it](#try-it-in-two-minutes) · [Four terms](#four-terms-you-need) · [In CI](#in-ci) · [What is inside](#what-is-inside) · [How it compares](#how-it-compares) · [What it is not](#what-it-is-not) · [Documentation](#documentation) · [Interactive atlas](https://beyondnetcode.github.io/evolith_arch32/) --- @@ -95,6 +95,26 @@ How many rules, packs and ADRs your installation loads is printed by `evolith ru --- +## How it compares + +The tools people reach for first check different things, and the differences are in the rows, not in the adjectives. Verified against each tool's own documentation on 2026-09-19; corrections welcome as a PR. + +| | ArchUnit | dependency-cruiser | Conftest | Evolith | +|---|---|---|---|---| +| **What it reads** | JVM bytecode: classes, packages, layers | The JS/TS module import graph | Structured config files (YAML, JSON, HCL, Dockerfile…) | The repository around the code: layout, workflows, manifests, ADRs — **not** the AST | +| **Rule language** | Java fluent DSL, run as unit tests | JSON/JS config (`forbidden` / `allowed`) | Rego | Rego, compiled to Wasm, in JSON packs | +| **Where rules live** | In the code base, per repository | In the repository (`.dependency-cruiser.js`) | A policy directory; shareable with `conftest pull` (git, OCI) | A library outside the repositories, adopted per repository with `--select` | +| **A rule that did not evaluate** | Fails a rule whose `should` got an empty set (`failOnEmptyShould`, on by default) | `severity: ignore` skips it silently; no other outcome exists | No outcome: an undefined `deny` is a pass | `skipped` is a first-class verdict, counted next to `passed` and `failed`; a **blocking** `skipped` fails the run | +| **Exit code** | A failing unit test | The number of `error` violations | `1` on failure (`0`/`1`/`2` with `--fail-on-warn`) | `0` pass · `1` the tool failed · `2` the gate blocked · `3` invalid invocation | +| **Surfaces** | Java tests | CLI (+ dependency graphs) | CLI | CLI · GitHub Action · MCP server · REST API | +| **Rules derived from ADRs** | — | — | — | Yes: `evolith adr create`, and many packs are derived from decisions | +| **Language scope** | JVM | JavaScript / TypeScript | Any structured file | Any repository for structural, CI/CD and ADR rules; Node/TypeScript for the dependency and linter rules | +| **License** | Apache-2.0 | MIT | Apache-2.0 | MIT | + +They are complements, not substitutes: ArchUnit and dependency-cruiser see *inside* the code, Conftest sees one file at a time, Evolith sees the repository as a governed unit and counts what it could not decide. Running Evolith next to one of them is the intended setup. + +--- + ## What it is not - **Not a replacement for ArchUnit, Conftest or dependency-cruiser; it complements them.** Rules live outside the codebase, as data that governs many repositories and that an agent can read. Evolith *is* OPA underneath, and adds the rule library, the ADR-to-rule derivation and the coverage accounting.