From 0101a5ac206db0a776f1ae0f42d7c5bed3b6e83b Mon Sep 17 00:00:00 2001 From: Alberto Arroyo Raygada Date: Fri, 21 Aug 2026 11:35:35 -0500 Subject: [PATCH 1/3] docs(readme): say what the tool is before showing what it found (#629) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(ci): the inventory tally ran on the one condition that could never change it `07-generate-inventories.mjs` counts ADRs, rulesets and schemas. In the local hook it hung off `infraChanged` — docker-compose, helm, `.github/workflows` — so a ruleset or an ADR could be added without ever triggering it. And it ran in no workflow at all: its only other appearance in the repository is its own unit test in ci-cd.yml. The published summary had been stale since 2026-08-16 (141/181 against a measured 142/182) and the front page quoted it onward. - regenerate both halves of the summary, so the numbers match the corpus - run the generator with `--check` in the required `Validate documentation` job, plus its self-test, which also ran nowhere - move the local trigger to `governanceChanged || adrChanged`, the two things that can actually move the count Verified: `--check` exits 0 against the tree; self-test 7/7. Co-Authored-By: Claude Opus 5 Signed-off-by: aarroyo * docs(mcp): the tool catalog and the product vision both undercounted the surface Closes #566, closes #567. The server registers 52 `evolith-*` tools. The hand-maintained catalog listed 51 -- `evolith-ruleset-list` was never added when the tool landed -- and the product vision master still said 47 tools and 11 resources, a figure corrected in the README months ago and missed here. - add the missing `evolith-ruleset-list` row, in the shape of its neighbours - correct the catalog's two declared totals (51 and "current 47-tool surface") and the Spanish twin's, which asserted 51 as well - product vision EN/ES: 47 tools / 11 resources -> 52 / 12, matching the generated `product-inventory.md` Verified: the server's registered names and the catalog rows are now the same 52-element set (`comm` on both sorted lists returns nothing either way); bilingual suite green, 17/17 entry-surface documents. Co-Authored-By: Claude Opus 5 Signed-off-by: aarroyo * docs(evidence): publish the front page's first-run capture, in full and in both languages The README quotes counters from one run of the published CLI against a fresh satellite. Until now the run itself lived nowhere, so the numbers had to be taken on faith and the elided rows could not be inspected. Captured today against `@beyondnet/evolith-cli@1.3.2` resolved from the public registry: 133 checked / 26 skipped / 0 errored of 159 selected, 72 issue rows, 37 blocking, nine of those blocking rows being rules the engine could not decide, exit 2. `stderr` was empty. Three things the capture makes checkable rather than asserted: - the two denominators reconcile in the output itself -- the `GOV-RULE-NOT-APPLICABLE` row states 253 inapplicable rules, and 253 + 159 = 412 - the same repository on the default native engine checks 41 rules and skips 118. CI holds the two engines to agreement over fixtures, not to equal coverage over a real repository, and today they do not have it - the three `[Nest] WARN Skipping non-standard ruleset` lines the README still quotes are gone in 1.3.2 -- on both streams. `INFRA-001` and `INFRA-OPA-001` are still in no denominator, so #575 is now silent rather than fixed Both halves written together, as the entry-surface rule requires. Co-Authored-By: Claude Opus 5 Signed-off-by: aarroyo * docs(readme): say what the tool is before showing what it found The front page opened with a 490-word forensic account of a run that ends in `exit 2` with 37 blocking findings, and in 498 lines it never said what category of tool this is. A reader with a minute left believing it was broken, having never learned what it does. Worse, the hero taught `validate --engine opa` and Quick Start taught bare `validate` — two commands that produce different denominators (133 rules evaluated against 41) with nothing explaining the flag. That is the exact defect this project exists to catch, on its own front page. Restructured, 498 -> 201 lines and 19 -> 10 sections, in both languages: - category sentence first, then the command, then the real output - the capture stays but is trimmed to the counters, one `did not run` row, the `GOV-RULE-NOT-APPLICABLE` row that reconciles both denominators, and `echo $?`; it now carries its date and resolved version, and links the full capture - `--engine opa` used consistently, and the divergence between the two engines disclosed rather than hidden behind the inconsistency - Quick Start moves to the top fifth and gains Node requirements, a sample `evolith.yaml`, what the tool actually inspects, and the `--select` mitigation for the first-run findings - Network Egress goes from 50 lines to 6, pointing at SECURITY.{md,es.md}, which already carried the full disclosure bilingually and with two limitations the README never had - the hand-written 15-entry Menu, the inline Q&A and the ASCII diagram go; the documentation table is rebuilt around intent, 21 rows to 9 - Contributing now names the open good-first-issues and Discussions instead of linking four process documents at the 96% mark Every figure was measured today rather than carried over. The old "412 rules / 181 files" is replaced by counts CI verifies (142 ADRs, 182 ruleset files, 50 schemas) alongside what the published CLI reports loading (177 packs, 412 rules). A tree-side rule count is deliberately absent: the published CLI evaluates its bundled corpus regardless of `coreRef.path`, so that number could not be measured with the real counting rule, and an unverifiable figure has no business on this page. Verified: 201 lines and ten `##` on both sides, every relative link resolves, both anchors exist, guards 01 and 04 green (17/17 entry-surface documents). Co-Authored-By: Claude Opus 5 Signed-off-by: aarroyo * docs(nav): one canonical master index, and the other one stops competing Closes #564. Two files called MASTER_INDEX.md, and a reader who found either had no way to know the other existed. The root pair was six links deep and sat on the entry surface; the taxonomy pair was already a redirect, but its two halves pointed at DIFFERENT documents -- English at the control-center hub, Spanish at the Core hub -- so the bilingual pair disagreed about where it was sending you. - the root pair becomes canonical, and is filled out to earn the link the README now gives it: architecture, governance, product, project state and knowledge, twenty entries a side - the taxonomy pair becomes a pure redirect to the root, with both halves naming the same destination, and says in words why it holds no content of its own The redirect stays rather than being deleted: 60-odd ADRs and both reference hubs link to it. Verified: guards 01 and 04 green, five `##` a side at the root and two a side in the redirect, every relative link resolves from its own directory. Co-Authored-By: Claude Opus 5 Signed-off-by: aarroyo * docs(core): rehome the three blocks the front page shed, and fix what they carried The README rewrite dropped three blocks. Two had a home to go to and one had a defect that only showed once it was moved. - **Core concepts** land in the Core hub as section 8, both languages, with the ten terms the rest of the corpus assumes and links to where each is defined. `Related Navigation` renumbers 8 -> 9; nothing links to those anchors. - **The directory tree** lands in the repository taxonomy, replacing one that had gone stale at the `src/` refactor: it still showed `sdk/`, `rulesets/`, `apps/` and `packages/` at the repository root, four paths that have not existed for months, and omitted `docs/`, `product/` and `.claude-plugin/` entirely. Both halves rewritten from the tracked tree. - **The Q&A** gains the two entries the Spanish half never had. This was not two missing translations: Spanish was missing EN's `T04-P04` (topology composition) and `T07-P03` (Strangler Fig), and had silently renumbered everything after them, so `T04-P04` named different questions in the two languages. The ids now agree as a set, 43 a side. - One Spanish line read `no六个月 después` -- a CJK fragment where "seis meses" belonged, sitting in the file since it was written. The README's Spanish half is corrected from 41 questions to 43 to match. Verified: `T##-P##` id sets identical across both halves (`diff` empty), guards 01 and 04 green, every relative link in the touched files resolves. Co-Authored-By: Claude Opus 5 Signed-off-by: aarroyo * docs(nav): two bilingual pairs sent their readers to different documents Measured across the seventeen entry-surface pairs: seventeen link entries differ between halves, and thirteen of them are correct -- a Spanish half pointing at the Spanish anchor of a bilingual document is what it should do. Two were defects. - `gap-tracking` and `gap-reference-catalog` both ended with a "Back to Vision Index" footer whose halves resolved to DIFFERENT files: `../README.md` (Control Center) in English, `../../README.es.md` (the Core hub) in Spanish. Both resolve, so guard 01 was green over the contradiction. Unified on the Control Center, which is the hub these two documents actually live under, and the label now names it -- neither file is a vision index. - `reference/core/interfaces/README.md` had no bilingual navigation line at all while its Spanish half linked back to it, so the Spanish version was reachable in one direction only. Two further divergences are real but out of scope here, and are being left visible rather than papered over: `AGENTS.es.md` has no script-taxonomy section to hang the EN pointer on, and `gap-tracking.es.md` has no 2026-06-27 wave paragraph. Both are abridged translations -- content gaps, not path bugs. A link-parity guard is deliberately NOT added in this change. Of the seventeen divergences it would see today, thirteen are correct translations; a guard that needs a hand-maintained exemption list for its own true negatives is the pattern this repository emptied out of guard 66. It needs a rule that can tell a translated anchor from a wrong destination, and that is its own piece of work. Verified: guards 01, 04 and 08 green (706 gaps, 682/682 catalog sections). Co-Authored-By: Claude Opus 5 Signed-off-by: aarroyo * docs: cite #628 where the engine coverage gap is disclosed Opening the issue corrected the framing the disclosure carried. Guard 68 (`68-validate-engine-verdict-parity.mjs`) states in its own header that the two engines ARE allowed to disagree about coverage and are held only to agreement about facts -- so the 133-versus-41 gap is an accepted design position, not an undiscovered defect, and calling it one would have contradicted the repository's own stance. What is not accepted, and is what #628 asks for: `evolith validate` with no flag is the lower-coverage command, and nothing in its output says which engine ran or what that engine could decide. The reader sees 118 skips and has no way to tell they belong to the engine rather than to their repository. Both READMEs and both halves of the first-run capture now say that distinction in those terms and link the issue. Co-Authored-By: Claude Opus 5 Signed-off-by: aarroyo --------- Signed-off-by: aarroyo Co-authored-by: Claude Opus 5 --- .github/workflows/docs.yml | 18 + .harness/scripts/ci-runner.mjs | 9 +- MASTER_INDEX.es.md | 31 +- MASTER_INDEX.md | 31 +- README.es.md | 485 ++++-------------- README.md | 482 ++++------------- docs/evidence/first-run-capture.es.md | 296 +++++++++++ docs/evidence/first-run-capture.md | 295 +++++++++++ .../evolith-product-vision-master.es.md | 4 +- .../vision/evolith-product-vision-master.md | 4 +- reference/core/README.es.md | 23 +- reference/core/README.md | 23 +- .../gaps/gap-reference-catalog.es.md | 2 +- .../gaps/gap-reference-catalog.md | 2 +- .../control-center/gaps/gap-tracking.es.md | 2 +- .../core/control-center/gaps/gap-tracking.md | 2 +- .../maturity-reports/inventory-summary.es.md | 6 +- .../maturity-reports/inventory-summary.md | 6 +- .../taxonomy/MASTER_INDEX.es.md | 15 +- .../control-center/taxonomy/MASTER_INDEX.md | 13 +- .../taxonomy/repository-taxonomy.es.md | 76 +-- .../taxonomy/repository-taxonomy.md | 54 +- .../03-tools-catalog/evolith-mcp-tools.es.md | 2 +- .../03-tools-catalog/evolith-mcp-tools.md | 5 +- reference/core/interfaces/README.es.md | 2 +- reference/core/interfaces/README.md | 2 + reference/core/sdlc/q-and-a.es.md | 20 +- 27 files changed, 1046 insertions(+), 864 deletions(-) create mode 100644 docs/evidence/first-run-capture.es.md create mode 100644 docs/evidence/first-run-capture.md diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0ae5a765c..c656b50c7 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -126,6 +126,24 @@ jobs: - name: Reconcile maturity evidence run: node .harness/scripts/ci/09-reconcile-maturity.mjs --check + # The inventory summaries are the source every doc quotes when it says how many + # ADRs, rulesets and schemas the corpus carries -- and until now nothing checked + # them. `07-generate-inventories.mjs` appears in exactly one other place in the + # repository: its own unit test in ci-cd.yml. The generator ran in no workflow, + # and in the local hook it hung off `infraChanged` (compose files, helm, the + # workflow directory) -- never off `src/rulesets/` or the ADR directory, which + # are the only two things that can change the numbers. + # + # The result was a published tally that had been stale since 2026-08-16: 141/181 + # against a measured 142/182, quoted onward by the README as "412 rules". This + # step runs the generator in --check mode, so a ruleset or ADR added without + # regenerating the summaries fails here instead of aging into the front page. + - name: Check inventory summaries match the corpus + run: node .harness/scripts/ci/07-generate-inventories.mjs --check + + - name: Self-test for the inventory generator + run: node --test .harness/scripts/ci/07-generate-inventories.test.mjs + # 21 cases over `09-reconcile-maturity.mjs`, including the GT-576 rule that a # capability may not be marked Validated on an ADR citation alone and the GT-596 # ISO/IEC 33020 threshold rule. Both were closed with "ships with a negative diff --git a/.harness/scripts/ci-runner.mjs b/.harness/scripts/ci-runner.mjs index c1898afb3..c6a44416a 100644 --- a/.harness/scripts/ci-runner.mjs +++ b/.harness/scripts/ci-runner.mjs @@ -100,6 +100,7 @@ function getAutoScripts() { const trackingChanged = changed.some(f => f.includes("gap-tracking") || f.includes("gap-reference") || f.includes("gap-closure")); const topologyChanged = changed.some(f => f.includes("topologies/")); const governanceChanged = changed.some(f => f.includes("src/rulesets/") || f.includes("reference/core/sdlc/")); + const adrChanged = changed.some(f => f.includes("reference/core/architecture/adrs/")); const knowledgeChanged = changed.some(f => f.includes("reference/knowledge/")); const codeChanged = changed.some(f => f.endsWith(".ts") || f.endsWith(".js") || f.endsWith(".mjs")); const infraChanged = changed.some(f => f.includes("docker-compose") || f.includes("helm/") || f.includes(".github/workflows")); @@ -129,9 +130,15 @@ function getAutoScripts() { scripts.push("agentic/13-agentic-code-review.mjs"); } if (infraChanged) { - scripts.push("07-generate-inventories.mjs"); scripts.push("29-validate-opa-sidecar-bundles.mjs"); } + // The inventory tally counts ADRs, rulesets and schemas, so `infraChanged` + // (compose, helm, workflows) could never trigger it on a change that moves the + // numbers. It sat on the wrong condition long enough for the published summary + // to fall a full week behind the corpus it claims to measure. + if (governanceChanged || adrChanged) { + scripts.push("07-generate-inventories.mjs"); + } if (codeChanged || infraChanged) { // GT-578: workflows, harness scripts and compose files are exactly where a // path *string* survives a move that the compiler would have caught. diff --git a/MASTER_INDEX.es.md b/MASTER_INDEX.es.md index 321b43e66..e2fd48237 100644 --- a/MASTER_INDEX.es.md +++ b/MASTER_INDEX.es.md @@ -2,13 +2,42 @@ > **Navegación Bilingüe:** [English](./MASTER_INDEX.md) +El punto de entrada canónico a cada área de este repositorio. Si lo que buscas es un punto de +partida orientado a tareas, el [README](./README.es.md) organiza el mismo material por +intención. + ## Arquitectura + - [Visión General de Arquitectura](./reference/core/architecture/README.es.md) - [Registro de ADRs](./reference/core/architecture/adrs/README.es.md) +- [Topologías](./reference/core/architecture/topologies/README.es.md) +- [Arquitectura Maestra C4](./reference/core/architecture/demos/C4-MASTER-ARCHITECTURE.es.md) ## Gobernanza + +- [Hub de Evolith Core](./reference/core/README.es.md) - [Estándares](./reference/core/foundations/README.es.md) -- [Rulesets](./src/rulesets/README.md) +- [Centro de Gobernanza SDLC](./reference/core/sdlc/README.es.md) +- [Rulesets](./src/rulesets/README.es.md) · [Políticas OPA](./src/rulesets/opa/README.es.md) · [Schemas](./src/rulesets/schema/README.es.md) + +## Producto + +- [Hub de Producto](./product/README.es.md) +- [Evolith CLI](./product/products/smart-cli/README.es.md) +- [Core API](./product/products/core-api/README.es.md) +- [MCP Services](./product/products/mcp-services/README.es.md) +- [Operaciones y SRE](./product/operations/README.es.md) + +## Estado del proyecto + +- [Centro de Control](./reference/core/control-center/README.es.md) +- [Tablero de Gaps](./reference/core/control-center/gaps/gap-tracking.es.md) +- [Oportunidades](./reference/core/control-center/opportunities/README.es.md) +- [Taxonomía del Repositorio](./reference/core/control-center/taxonomy/repository-taxonomy.es.md) ## Conocimiento + +- [Q&A](./reference/core/sdlc/q-and-a.es.md) +- [Glosario del Ecosistema](./reference/core/sdlc/glossary/glossary-ecosystem.es.md) - [Referencias de Demo](./product/research/demo/README.md) +- [Captura de la primera ejecución](./docs/evidence/first-run-capture.es.md) diff --git a/MASTER_INDEX.md b/MASTER_INDEX.md index 5f76b8f69..6c8937630 100644 --- a/MASTER_INDEX.md +++ b/MASTER_INDEX.md @@ -2,13 +2,42 @@ > **Bilingual Navigation:** [Versión en Español](./MASTER_INDEX.es.md) +The canonical entry point to every area of this repository. If you are looking for a +task-oriented starting point instead, the [README](./README.md) organises the same material by +intent. + ## Architecture + - [Architecture Overview](./reference/core/architecture/README.md) - [ADR Registry](./reference/core/architecture/adrs/README.md) +- [Topologies](./reference/core/architecture/topologies/README.md) +- [C4 Master Architecture](./reference/core/architecture/demos/C4-MASTER-ARCHITECTURE.md) ## Governance + +- [Evolith Core hub](./reference/core/README.md) - [Standards](./reference/core/foundations/README.md) -- [Rulesets](./src/rulesets/README.md) +- [SDLC Governance Center](./reference/core/sdlc/README.md) +- [Rulesets](./src/rulesets/README.md) · [OPA policies](./src/rulesets/opa/README.md) · [Schemas](./src/rulesets/schema/README.md) + +## Product + +- [Product hub](./product/README.md) +- [Evolith CLI](./product/products/smart-cli/README.md) +- [Core API](./product/products/core-api/README.md) +- [MCP Services](./product/products/mcp-services/README.md) +- [Operations and SRE](./product/operations/README.md) + +## Project state + +- [Control Center](./reference/core/control-center/README.md) +- [Gap board](./reference/core/control-center/gaps/gap-tracking.md) +- [Opportunities](./reference/core/control-center/opportunities/README.md) +- [Repository Taxonomy](./reference/core/control-center/taxonomy/repository-taxonomy.md) ## Knowledge + +- [Q&A](./reference/core/sdlc/q-and-a.md) +- [Ecosystem Glossary](./reference/core/sdlc/glossary/glossary-ecosystem.md) - [Demo References](./product/research/demo/README.md) +- [First-run capture](./docs/evidence/first-run-capture.md) diff --git a/README.es.md b/README.es.md index 79ed7aded..130d6b199 100644 --- a/README.es.md +++ b/README.es.md @@ -5,28 +5,22 @@ > **Navegación Bilingüe:** [English](./README.md) [![npm](https://img.shields.io/npm/v/@beyondnet/evolith-cli?label=%40beyondnet%2Fevolith-cli)](https://www.npmjs.com/package/@beyondnet/evolith-cli) +[![node](https://img.shields.io/node/v/@beyondnet/evolith-cli)](https://www.npmjs.com/package/@beyondnet/evolith-cli) [![CI](https://img.shields.io/github/actions/workflow/status/beyondnetcode/evolith_arch32/ci-cd.yml?branch=main&label=CI)](https://github.com/beyondnetcode/evolith_arch32/actions/workflows/ci-cd.yml) [![License](https://img.shields.io/badge/license-MIT-informational)](./LICENSE) -**Gobernanza de arquitectura ejecutable. Una regla que no se evaluó no es una regla que pasó.** +**Tus reglas de arquitectura, ejecutándose en cada PR. Una regla que no se evaluó no es una regla que pasó.** +Evolith corre reglas de arquitectura —capas, dependencias, seguridad, CI/CD, ADRs— contra tu repositorio desde CI y falla el PR. A diferencia del resto, te dice cuántas reglas **no pudo evaluar**, y si alguna era bloqueante, falla igual. + ```bash -npm install -g @beyondnet/evolith-cli -evolith init --name my-sat --yes -evolith validate --engine opa +npx -y @beyondnet/evolith-cli init --name my-sat --yes # escribe evolith.yaml aquí mismo +npx -y @beyondnet/evolith-cli validate --engine opa # espera hallazgos: esto es una línea base ``` -[Inicio Rápido](#inicio-rápido) · [Atlas interactivo de arquitectura](https://beyondnetcode.github.io/evolith_arch32/) · [Cómo auditamos nuestras propias afirmaciones](./reference/core/control-center/adoption/pending-2026-08-16.md) - ---- - -## Qué acaba de pasar - -Ese tercer comando evaluó el corpus de reglas de este propio repositorio contra un satélite -recién inicializado, usando el bundle Rego compilado. Esto es lo que imprimió -`@beyondnet/evolith-cli@1.3.0` en un contenedor con nada más que Node instalado: +Esto es lo que imprime, sin recortes en las cifras: ``` **Status:** failed @@ -34,222 +28,104 @@ recién inicializado, usando el bundle Rego compilado. Esto es lo que imprimió **Rules Skipped:** 26 **Rules Errored:** 0 **Rules Total:** 159 - -### Issues -| Rule Id | Severity | Category | Title | Blocking | -| --- | --- | --- | --- | --- | -| ACL-01 | MUST | anti-corruption | Schema Validation Before Ingestion | YES | ... | SEC-INJ-01 | MUST | security | Blocking rule did not run: No shell exec with user input | YES | -| SEC-INJ-02 | MUST | security | Blocking rule did not run: Parameter allowlists for scaffold tools | YES | -| SEC-PATH-01 | MUST | security | Blocking rule did not run: Path input sanitization | YES | ... -└ ❌ Validation failed. See the errors above. - +| GOV-RULE-NOT-APPLICABLE | COULD | governance | 253 corpus rules do not apply to this repository | no | +**Selection:** {"source":"core-default","rulesSelected":412,"corpusTotal":412} $ echo $? 2 ``` -Cada línea de arriba es la de la herramienta, carácter por carácter. Los `...` marcan filas de -issues recortadas por longitud y nada más -- hay 72 en total, 37 de ellas bloqueantes. La -ejecución además abre con tres líneas `[Nest] WARN Skipping non-standard ruleset`: tres ficheros -de ruleset viajan en el tarball y el propio esquema del validador publicado los rechaza. Eso es -un defecto real, y un README que sostiene que *no evaluado* no es lo mismo que *pasó* no tiene -derecho a borrarlo de la captura. - -El Core carga **412 reglas**; el 159 de arriba es lo que la ejecución de este satélite -seleccionó de ellas. Dos denominadores distintos, y un informe que los mezclara sería el -defecto exacto que este proyecto existe para evitar. - -**Nueve de esos 37 issues bloqueantes son reglas que se saltaron.** No reglas que fallaron: -reglas que el motor no pudo decidir, reportadas como fallo porque una regla bloqueante sin -decidir no es una regla que pasa. Entre ellas están `SEC-INJ-01`, `SEC-INJ-02` y `SEC-PATH-01`. - -Esta es la idea entera. Todo linter de arquitectura y de políticas pasa en silencio las reglas -que nunca evaluó, con lo que *cobertura* y *cumplimiento* producen el mismo verde. Evolith -publica el denominador y se niega a redondearlo hacia arriba: - -- El bundle compilado declara qué ids de regla puede decidir, y `skipped` es un resultado de - primera clase, no la ausencia de una violación. -- Una regla bloqueante que termina `skipped` hace fallar la ejecución. Ese invariante tiene su - propio test, escrito contra el código que no lo tenía: - [`blocking-skipped-invariant.spec.ts`](./src/packages/core-domain/src/application/validators/blocking-skipped-invariant.spec.ts). -- Dos motores -- un evaluador nativo en TypeScript y Rego/WASM -- deben coincidir sobre - fixtures, o el CI falla. - -Los códigos de salida son una taxonomía, no un booleano: `0` pasa, `1` la herramienta falló, -`2` la puerta bloqueó, `3` la invocaste mal. Una ejecución que no pudo producir un veredicto -nunca reporta uno. - ---- - -## Úsalo como puerta de PR - -```yaml -- uses: beyondnetcode/evolith_arch32@v1 - with: - fail-on-violation: true -``` - -Expone `compliance-status`, `violations-count`, `issues-count`, `exit-code` y `report-path`. -`error` e `invalid-input` significan que el repositorio **no fue evaluado** -- no son formas -más débiles de no-conforme, y el resumen del job lo dice con palabras. - -Como contexto vivo para un agente de IA, sobre stdio: +72 filas de issues, 37 bloqueantes, **9 de ellas reglas que el motor no pudo decidir** — reportadas como fallo porque una bloqueante sin decidir no es una regla que pasa. Medido el 2026-08-21 con `@beyondnet/evolith-cli@1.3.2`; tarda ~2 s. [Captura íntegra, 72 filas y los dos denominadores](./docs/evidence/first-run-capture.es.md). -```json -{ "mcpServers": { "evolith": { "command": "npx", "args": ["-y", "@beyondnet/evolith-mcp"] } } } -``` +[Inicio Rápido](#inicio-rápido) · [Puerta de PR](#úsalo-como-puerta-de-pr) · [Qué gobierna](#qué-gobierna) · [Documentación](#documentación) · [Contribuir](#contribución) · [Atlas interactivo](https://beyondnetcode.github.io/evolith_arch32/) --- -## Por qué no ArchUnit, Conftest o dependency-cruiser - -Úsalos. Son buenos, y Evolith no sustituye a ninguno. - -| Herramienta | Qué hace bien | En qué difiere Evolith | -|---|---|---| -| **ArchUnit / ts-arch** | Reglas de capas y dependencias como tests unitarios, en tu lenguaje | Las reglas viven fuera del código como datos, así que un mismo corpus gobierna muchos repositorios y un agente puede leerlo | -| **Conftest / OPA** | Rego contra cualquier entrada estructurada | Evolith *es* OPA por debajo. Lo que añade es el corpus, la derivación de ADR a regla, y la contabilidad de cobertura | -| **dependency-cruiser** | Reglas sobre el grafo de dependencias, rápido y enfocado | Corpus más amplio (gates SDLC, topologías, estándares de seguridad) y un rastro de evidencia por veredicto | -| **Backstage Scorecards** | Chequeos de salud sobre todo el catálogo, con UI | Corre offline en CI sin catálogo que mantener, y bloquea un PR en vez de colorear un panel | +## La idea, en una línea -**En qué es genuinamente distinto:** reporta lo que no pudo evaluar. Ninguna de las -herramientas de arriba distingue "esta regla pasó" de "esta regla nunca corrió" en su código -de salida. +Todo linter de arquitectura pinta de verde las reglas que nunca llegó a ejecutar: *cobertura* y *cumplimiento* acaban del mismo color. Evolith publica el denominador y se niega a redondearlo. `skipped` es un resultado de primera clase; una regla bloqueante que acaba `skipped` **hace fallar la ejecución** ([invariante con test propio](./src/packages/core-domain/src/application/validators/blocking-skipped-invariant.spec.ts)); y los códigos de salida son una taxonomía: `0` pasa · `1` falló la herramienta · `2` bloqueó la puerta · `3` mala invocación. -**Qué NO está construido todavía, para que no lo descubras tú:** la mitad de "el LLM propone, -un verificador determinista dispone" es una dirección documentada, no comportamiento -publicado. Ningún comando del CLI instalado alcanza un LLM. Ver -[Egreso de Red y Manejo de Datos](#egreso-de-red-y-manejo-de-datos). +Y lo aplicamos a nosotros. Tres cosas que esta portada podría callar y no calla: ---- +- **Los dos motores no cubren lo mismo hoy.** `--engine opa` evalúa 133 de 159 reglas; el evaluador nativo por defecto evalúa 41 y salta 118, sobre el mismo repo. CI exige que coincidan sobre hechos, no sobre cobertura — eso es por diseño; que el comando por defecto no lo diga, no ([#628](https://github.com/beyondnetcode/evolith_arch32/issues/628)). Esta portada usa `--engine opa` en todas partes. +- **Dos reglas de infraestructura no están en ningún denominador.** El cargador rechaza tres ficheros del propio corpus, y desde 1.3.2 ya ni lo avisa por stderr ([#575](https://github.com/beyondnetcode/evolith_arch32/issues/575)). +- **Lo que se instala no es todo lo que hay en este árbol.** El árbol lleva 182 ficheros de reglas; el CLI publicado carga 177 packs con 412 reglas — el rechazo del cargador de arriba es una de las causas. `evolith rulesets` imprime lo que carga *tu* instalación, pack por pack. -## Menú - -- [¿Qué es Evolith?](#qué-es-evolith) -- [¿Por qué Evolith?](#por-qué-evolith) -- [Conceptos Clave](#conceptos-clave) -- [Ecosistema de Productos](#ecosistema-de-productos) -- [Cómo Funciona](#cómo-funciona) -- [Visión de Arquitectura](#visión-de-arquitectura) -- [Componentes Principales](#componentes-principales) -- [Inicio Rápido](#inicio-rápido) -- [Preguntas y Respuestas](#preguntas-y-respuestas) -- [Egreso de Red y Manejo de Datos](#egreso-de-red-y-manejo-de-datos) -- [Documentación](#documentación) -- [Casos de Uso](#casos-de-uso) -- [Roadmap](#roadmap) -- [Contribución](#contribución) -- [Licencia](#licencia) +Auditoría completa de nuestras propias afirmaciones: [pendientes 2026-08-16](./reference/core/control-center/adoption/pending-2026-08-16.md). --- -## ¿Qué es Evolith? - -Evolith es un **framework de gobernanza arquitectónica ejecutable**. Codifica cómo se construye el software — a través de múltiples estilos de arquitectura — como reglas verificables, ADRs y compuertas de fase que equipos, plataformas y agentes de IA pueden ejecutar de verdad. +## Inicio Rápido -La gobernanza en Evolith no es un documento. Es una capacidad operativa expuesta a través de una CLI, un servidor MCP y una API REST. +**Requisitos:** Node ≥ 18 para la CLI, ≥ 20 para el servidor MCP · sin base de datos, sin servidor, sin Docker. La instalación se verifica en CI sobre Linux; macOS y Windows no están cubiertos por esa puerta. ---- +```bash +npm install -g @beyondnet/evolith-cli # o usa `npx -y @beyondnet/evolith-cli` sin instalar nada -## ¿Por qué Evolith? +evolith init --name my-sat --yes # configura el directorio ACTUAL; --name solo nombra el proyecto +evolith validate --engine opa # mismo directorio, sin `cd` -La mayoría de proyectos acumulan ADRs y documentos de arquitectura que nadie lee y nadie aplica. Los sistemas se desvían. Las decisiones se olvidan. La consistencia se rompe en silencio. +evolith rulesets # qué reglas carga TU instalación, pack por pack +evolith validate --engine opa --select rulesets/acl/anti-corruption-layer.rules.json +evolith validate --engine opa --phase qa +evolith adr create # gestiona Architecture Decision Records +``` -Evolith hace que la gobernanza sea **ejecutable**: +`--engine opa` evalúa con el bundle Rego compilado; sin la bandera corre el evaluador nativo, que hoy cubre menos. Para crear un directorio nuevo, pásalo como argumento: `evolith init my-sat --yes`. Con `--format json` nunca pregunta e imprime un único objeto JSON en stdout; `--dry-run` no escribe nada. -- Las reglas se validan automáticamente, no se revisan manualmente. -- Las compuertas de fase bloquean el avance hasta que se cumplen los criterios de calidad. -- Los agentes de IA y los pipelines de CI consumen los mismos artefactos de gobernanza que los humanos. -- Las decisiones de arquitectura son trazables desde el ADR hasta el código en producción. +> **Espera hallazgos en la primera ejecución.** Un repo recién configurado es una línea base, no un aprobado: muchas reglas asumen un layout más completo. Para empezar por lo que sí has adoptado, usa `--select` con los refs que imprime `evolith rulesets`; llevar el default a cero se sigue como GT-571 en el [Tablero de Gaps](./reference/core/control-center/gaps/gap-tracking.es.md). ---- +Configuración en **`evolith.yaml`**, que `init` escribe por ti: -## Conceptos Clave +```yaml +coreRef: { version: "1.0.0", path: "../evolith" } +product: { name: my-sat, type: enterprise-application, phase: phase-0 } +tools: { runtime: nodejs, architecture: clean, ci: github-actions } +``` -| Concepto | Qué es | -|---|---| -| **Fases SDLC** | Las cinco etapas de la idea a producción: Discovery → Design → Construction → QA → Delivery | -| **Compuertas** | Puntos de control automatizados que cierran cada fase antes de pasar a la siguiente | -| **Topologías** | Estilos de arquitectura (ej. monolito modular, microservicios, event-driven, agentic-AI) | -| **ADRs** | Architecture Decision Records — el registro autoritativo de decisiones arquitectónicas | -| **Blueprints** | Plantillas de diseño canónicas para cada topología | -| **Rulesets** | Reglas legibles por máquina aplicadas por la CLI y la Core API | -| **Políticas OPA** | Políticas de Open Policy Agent para controles de gobernanza granulares | -| **Artefactos** | Salidas estructuradas en cada fase: specs, schemas, manifests, contratos | -| **Agentes de IA** | Agentes especializados (Winston y otros) que participan en el SDLC como colaboradores de primer nivel | - -Detalles completos: [Conceptos Core](./reference/core/README.es.md) · [Topologías](./reference/core/architecture/topologies/README.es.md) +**Qué inspecciona:** estructura del repositorio, workflows de CI, manifiestos y artefactos de gobernanza — no el AST de tu código. Eso lo hace en su mayoría agnóstico al lenguaje; el subconjunto que mira dependencias y linters asume un repo Node/TypeScript. Referencia: [Hub de Evolith CLI](./product/products/smart-cli/README.es.md) · [Guía rápida](./docs/guides/evolith-quickstart.es.md) --- -## Ecosistema de Productos - -Evolith se distribuye como una suite de productos coordinados sobre una base común. +## Úsalo como puerta de PR -| Producto | Rol | -| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| **[Evolith Core](reference/README.es.md)** | Constitución neutral al proveedor: principios, ADRs, rulesets, topologías y contratos | -| **[Evolith CLI](product/products/smart-cli/README.es.md)** | Aplicación local — valida código, ejecuta compuertas, gestiona ADRs, sirve MCP | -| **[Core API](product/products/core-api/README.es.md)** | Servicio REST para consultas y evaluación de gobernanza de forma remota | -| **[MCP Services](product/products/mcp-services/README.es.md)** | Gobernanza como contexto en vivo para LLMs y agentes de IA (52 tools, 12 resources, 8 prompts) | -| **[Agent Runtime](reference/core/architecture/foundations/README.es.md)** | Capa de mediación agéntica — orquesta el Core mediante Puertos y Adaptadores; Hermes es uno de los adaptadores reemplazables | -| **[Evolith Tracker](product/products/evolith-tracker/README.es.md)** | Gobernanza del ciclo de vida del negocio — fases, propietarios, financiación y ROI | -| **[Narrativa Comercial](product/suite/vision/evolith-commercial-brochure.es.md)** | Estrategia de producto y monetización empresarial (Despliegue Hub & Spoke) | -| **[Rulesets](src/rulesets/README.es.md)** | Reglas de aplicación legibles por máquina por topología | -| **[Políticas OPA](src/rulesets/opa/README.es.md)** | Controles de política granulares integrados en el pipeline | -| **[Schemas y Manifests](src/rulesets/schema/README.es.md)** | Contratos estructurados para artefactos y definiciones de topología | +```yaml +- uses: beyondnetcode/evolith_arch32@v1 + with: + fail-on-violation: true +``` ---- +Expone `compliance-status`, `violations-count`, `issues-count`, `exit-code` y `report-path`. `error` e `invalid-input` significan que el repositorio **no fue evaluado** — no son formas más débiles de no-conforme, y el resumen del job lo dice con palabras. -## Cómo Funciona +Como contexto vivo para un agente de IA, sobre stdio: -``` -Desarrollador / Agente de IA / Disparador Externo - │ - ▼ - Evolith CLI ──────────────────────────────► Servidor MCP - (aplicación local) (contexto para agentes de IA) - │ - ▼ - Core API ────────────────────────────► Evolith Tracker - (gobernanza remota) (ciclo de vida del negocio) - │ - ▼ - Agent Runtime ───────────────────────────► Hermes (adaptador) - (mediación agéntica, Puertos y Adaptadores) (.harness · OPA · Tracker · Memoria) - │ - ▼ - Rulesets · Políticas OPA · ADRs · Blueprints - (los artefactos de gobernanza compartidos) +```json +{ "mcpServers": { "evolith": { "command": "npx", "args": ["-y", "@beyondnet/evolith-mcp"] } } } ``` -1. **Evolith CLI** valida el código localmente contra los rulesets y ejecuta las compuertas de fase. -2. **Core API** expone la misma gobernanza de forma remota para pipelines de CI y orquestadores. -3. **Servidor MCP** entrega contexto de gobernanza a LLMs y agentes de IA en tiempo real. -4. **Agent Runtime** orquesta las capacidades del Core mediante Puertos y Adaptadores — Hermes es uno de los adaptadores reemplazables. -5. **Evolith Tracker** coordina el lado del negocio — quién es responsable, qué está financiado, qué se entrega cuándo. +--- -Todos los productos comparten los mismos artefactos definidos en **Evolith Core**. +## Por qué no ArchUnit, Conftest o dependency-cruiser ---- +Úsalos. Son buenos, y Evolith no sustituye a ninguno. -
+| Herramienta | Qué hace bien | En qué difiere Evolith | +|---|---|---| +| **ArchUnit / ts-arch** | Reglas de capas y dependencias como tests unitarios, en tu lenguaje | Las reglas viven fuera del código como datos: una misma biblioteca gobierna muchos repos y un agente puede leerla | +| **Conftest / OPA** | Rego contra cualquier entrada estructurada | Evolith *es* OPA por debajo. Añade la biblioteca de reglas, la derivación de ADR a regla y la contabilidad de cobertura | +| **Backstage Scorecards** | Chequeos de salud sobre todo el catálogo, con UI | Corre offline en CI sin catálogo que mantener, y bloquea un PR en vez de colorear un panel | - - Visión General del Producto Evolith E2E - Composición Gobernada, Core de evaluación stateless, SDLC federado de cinco fases - +Frente a **dependency-cruiser**, el alcance es más amplio (controles de fase, estilos de arquitectura, estándares de seguridad) y guarda por qué falló cada regla. -Visión General del Producto Evolith E2E - Abrir visor interactivo - arrastra para desplazar, rueda para zoom, pantalla completa +**Qué NO está construido todavía, para que no lo descubras tú:** la mitad de «el LLM propone, un verificador determinista dispone» es una dirección documentada, no comportamiento publicado. Ningún comando de la CLI instalada alcanza un LLM. -
+--- -## Visión de Arquitectura +## Qué gobierna -Evolith gobierna **8 topologías** en cuatro ejes: +Ocho **estilos de arquitectura** (aquí los llamamos *topologías*) repartidos en cinco ejes. Las mismas reglas te siguen cuando el monolito se parte en servicios. | Eje | Topologías | |---|---| @@ -259,240 +135,67 @@ Evolith gobierna **8 topologías** en cuatro ejes: | Datos | `data-mesh` | | IA | `agentic-ai` | -Cada topología tiene sus propios ADRs, políticas OPA, rulesets de IA y contratos UMS. Los sistemas migran entre topologías a medida que el negocio escala — esto es **Arquitectura Progresiva**. +Encima corre una biblioteca **gratis y MIT**: en este árbol, 142 ADRs, 182 ficheros de reglas y 50 schemas de fase, más las cinco fases del SDLC (Discovery → Design → Construction → QA → Delivery) y los controles que bloquean el paso de una a la siguiente. Esos tres conteos los mide y los verifica CI en cada PR. Lo que evalúa tu instalación lo imprime `evolith rulesets`: hoy, 177 packs con 412 reglas, 188 de ellas capaces de hacer fallar una ejecución. El único producto de pago será **Evolith Tracker**, aún no lanzado. -Referencia completa: [Hub de Arquitectura](./reference/core/architecture/README.es.md) · [Arquitectura Maestra C4](./reference/core/architecture/demos/C4-MASTER-ARCHITECTURE.es.md) +
Cómo encajan CLI, Core y las cinco fases del SDLC
Abrir visor interactivo — arrastra para desplazar, rueda para zoom
--- -## Componentes Principales +## Ecosistema de productos -``` -evolith/ -├── packages/agent-runtime/ # @beyondnet/evolith-agent-runtime — capa agéntica Puertos y Adaptadores -├── apps/agent-runtime-api/ # Servicio HTTP NestJS que envuelve el runtime (POST /v1/agent/handle) -├── reference/core/ # Constitución de ingeniería y principios -├── reference/core/architecture/ # Topologías, blueprints, ADRs y docs del agent-runtime -├── reference/core/sdlc/ # Fases SDLC, compuertas, estándares y glosario -├── product/products/ # Evolith CLI, Core API, MCP, Tracker, UMS -└── product/operations/ # SRE, infra, compuertas de calidad -``` - -Punto de entrada para cada área: [Índice Maestro Global](./reference/core/control-center/taxonomy/MASTER_INDEX.es.md) - ---- - -## Inicio Rápido - -El paquete npm es `@beyondnet/evolith-cli`; instala dos bins equivalentes, **`evolith`** (el nombre documentado) y `evolith-cli` (compatibilidad). Ambos se identifican como `evolith` en `--help`. - -```bash -# 1. Instala la CLI -npm install -g @beyondnet/evolith-cli - -# 2. Inicializa el directorio ACTUAL como satélite de Evolith. -# --name fija el nombre del proyecto que se escribe en evolith.yaml. -# --yes corre sin preguntas (también implícito con stdin sin TTY o --format json). -evolith init --name my-sat --yes - -# 3. Valida el satélite que acabas de crear — mismo directorio, sin `cd` -evolith validate - -# Valida una fase específica del SDLC -evolith validate --phase qa - -# Gestiona Architecture Decision Records -evolith adr create -evolith adr list - -# Sirve la gobernanza como contexto en vivo para agentes de IA — el servidor MCP -# es un paquete aparte (@beyondnet/evolith-mcp) con su propio bin: -evolith-mcp serve -``` - -Para generar el satélite en un directorio **nuevo** en lugar del actual, pásalo como argumento posicional (o con `--dir`); `--name` solo nombra el proyecto, nunca crea un directorio: - -```bash -evolith init my-sat --yes && cd my-sat && evolith validate -``` - -Las corridas legibles por máquina (`--format json`) nunca preguntan e imprimen exactamente un envelope en stdout; un `init` fallido sale con código distinto de cero. `evolith init --dry-run` no escribe nada. - -> **Espera hallazgos en el primer `validate`.** Un satélite recién inicializado es una línea base, no un aprobado: algunas reglas siguen asumiendo un layout de repositorio más completo y reportan hallazgos bloqueantes en un proyecto en fase 0. Llevar eso a cero se sigue en el [Tablero de Gaps](./reference/core/control-center/gaps/gap-tracking.md) (GT-571). - -Evolith CLI se configura mediante **`evolith.yaml`**; ejecuta `evolith --help` para la lista vigente de comandos. Referencia completa: [Hub de Evolith CLI](./product/products/smart-cli/README.es.md) - ---- - -## Preguntas y Respuestas - -
-¿Qué es Evolith en una frase? -
-Evolith es un framework ejecutable de gobernanza arquitectónica — se asegura de que las decisiones de arquitectura realmente se cumplan, automáticamente, ya sea que el código lo escriba un humano o un agente AI. -
- -
-¿Para qué lo usaría? -
-
    -
  1. Feedback instantáneo en decisiones arquitectónicas — ejecuta evolith validate y sabe en segundos si tu código cumple.
  2. -
  3. Sin refactors sorpresa — el drift arquitectónico se detecta en el gate, no seis meses después.
  4. -
  5. Gobernanza a prueba de AI — cuando un agente AI escribe código, Evolith asegura que siga las mismas reglas que un arquitecto senior.
  6. -
-
- -
-¿Cuánto cuesta? -
-La plataforma core es completamente gratis (licencia MIT): CLI, servidor MCP, Core API, Agent Runtime, 142 ADRs, 181 ficheros de ruleset con 412 reglas, 50 schemas de phase-gate. El único producto de pago es Evolith Tracker (gobernanza enterprise multi-tenant — aún no lanzado). -
- -
-¿Cómo empiezo? -
- -```bash -npm install -g @beyondnet/evolith-cli -evolith init --name my-sat --yes # inicializa el directorio ACTUAL -evolith validate # mismo directorio, sin `cd` -``` - -Sin base de datos, sin servidor, sin Docker. -
- -
-¿Qué topologías cubre? -
-Evolith gobierna 8 topologías en 5 dimensiones: Modular Monolith, Distributed Modules, Microservices (progressive-axis), Serverless, Edge Computing (execution), Event-Driven (integration), Data Mesh (data) y Agentic AI. Todas componibles. -
- -
-¿Cómo funciona con herramientas AI como Cursor o Claude? -
-Evolith envía un servidor MCP dentro del CLI. Agrégalo a la configuración de tu herramienta AI y tu agente puede consultar reglas, validar código y evaluar gates — todo gobernado. -
- -**[Q&A completo: 64 preguntas en 12 categorías →](./reference/core/sdlc/q-and-a.es.md)** - ---- - -## Egreso de Red y Manejo de Datos - -Evolith es local-first: la CLI, los rulesets, las políticas OPA y el Core de evaluación stateless corren en tu máquina, y tu código fuente nunca se sube — la evaluación ocurre donde está el código. Existe exactamente **una** integración de salida en todo el corpus, está **desactivada por defecto**, y esta es su divulgación completa. - -| Ítem | Divulgación | +| Producto | Rol | |---|---| -| **Componente** | `GeminiProvider`, export público de `@beyondnet/evolith-agent-runtime` | -| **Endpoint** | un `POST` HTTPS a `https://generativelanguage.googleapis.com/v1beta/models/:generateContent`, modelo por defecto `gemini-2.5-flash`. El paquete no contacta ningún otro host. | -| **Sub-procesador** | **Google LLC (Gemini API)**. El contenido enviado por esta vía lo procesa Google bajo sus términos para esa API. No interviene ningún otro sub-procesador. | -| **Estado por defecto** | **DESACTIVADO.** Sin configuración el provider no abre ningún socket: registra el intento rechazado y lanza `LlmEgressDisabledError`. De fábrica el paquete no hace ninguna llamada de red. | -| **Opt-in** | `EVOLITH_LLM_EGRESS=true` (o `1`), o un explícito `new GeminiProvider({ enabled: true })`. No hay forma implícita de activarlo. | -| **Credencial** | `EVOLITH_LLM_API_KEY`, con respaldo en `GEMINI_API_KEY`. Viaja en el header `x-goog-api-key` de la petición y nunca en la URL. Sin clave la llamada se rechaza antes de abrir un socket. | -| **Límites** | timeout de 30.000 ms con `AbortController`; 60.000 bytes / ~15.000 tokens estimados. Por encima del presupuesto la petición **falla cerrado** — nada se trunca para enviarse igual. | - -**Qué sale de la máquina** - -- Por la costura gobernada `IAssistantTransport`: el intent de la petición, el id opcional de la herramienta, los parámetros, el flag `dryRun` y el catálogo gobernado de skills (solo id y descripción). -- Por la costura deprecada `ILLMProvider` (`generateStructuredJson`): el system prompt y el user prompt del llamador, textuales. -- Ambos se redactan antes de serializarse, sobre 8 clases de patrones: claves privadas PEM, JWTs, access key ids de AWS, API keys de Google, PATs de GitHub, tokens de Slack, tokens `Bearer` y asignaciones genéricas de `KEY`/`SECRET`/`TOKEN`/`PASSWORD`. +| **Evolith Core** | Las reglas en sí: ficheros que puedes leer, editar y versionar | +| **Evolith CLI** | Aplicación local — valida el repo, ejecuta controles de fase, gestiona ADRs | +| **Core API** | Servicio REST para consultar y evaluar gobernanza en remoto | +| **MCP Services** | Gobernanza como contexto en vivo para agentes (52 tools, 12 resources, 8 prompts) | +| **Agent Runtime** | Ejecuta el Core desde un agente, por Puertos y Adaptadores. Experimental | +| **Evolith Tracker** | Producto comercial de gobernanza del ciclo de vida. Aún no lanzado | -**Qué no sale de la máquina** +**Para quién es:** -El id de tenant, de producto, de iniciativa, la referencia al workspace y la identidad del solicitante quedan excluidos del payload por construcción (minimización de datos), igual que el contenido del repositorio. +- Equipos de ingeniería que quieren sus ADRs aplicados en CI, no revisados a mano. +- Equipos de plataforma que bloquean artefactos no conformes antes de producción. +- Desarrollo asistido por IA que necesita que el agente valide su salida contra las mismas reglas. -**Observabilidad** +**Adopción, sin adornos:** 1.109 descargas en npm el último mes (21-07 → 19-08), ninguna adopción externa confirmada. El repositorio se gobierna a sí mismo y esa es toda la evidencia que hay. -Cada intento — incluidos los rechazos — emite una línea JSON sin contenido, prefijada `[evolith:llm-egress]`, con provider, endpoint, propósito, resultado, conteo de bytes y tokens, número de redacciones, status HTTP, duración y correlation id. El contenido de prompts y respuestas nunca se registra. - -**Human-in-the-loop** - -El cableado previsto inyecta `GeminiProvider` como `IAssistantTransport` de `SupervisedAssistantClient`, que a su vez está desactivado por defecto y exige una aprobación humana explícita antes de llegar al transporte. - -**Otro tráfico de salida** - -- La **exportación OpenTelemetry** de la CLI está apagada salvo que `OTEL_ENABLED=true`, y entonces va solo al colector que configures. -- La **Core API** y el **transporte HTTP del MCP** son servidores que tú alojas; la CLI contacta un Core remoto solo si lo configuras. -- Ninguna superficie envía telemetría, analítica ni verificación de licencia a casa. +--- -**Estado real, sin adornos** +## Egreso de red -- La redacción es por patrones, no un control DLP: reduce materialmente el egreso accidental de credenciales, no garantiza su ausencia. -- Los controles de header, timeout, presupuesto, redacción y validación de schema están cubiertos por tests unitarios con un `fetch` inyectado; **no** se han ejercitado contra el endpoint real de Google. -- Los valores de timeout y presupuesto se heredan del revisor de CI del propio repositorio y no están afinados para prompts interactivos grandes, que fallan cerrado en lugar de degradar. -- Hoy ningún comando registrado en la CLI publicada alcanza este provider, así que una instalación por defecto de la CLI no hace egreso a LLM alguno. -- Los tarballs npm publicados actualmente son anteriores a este endurecimiento; los controles descritos están en `develop` y llegan al registry con la próxima release, seguido como GT-570 en el [Tablero de Gaps](./reference/core/control-center/gaps/gap-tracking.md). +Local-first: la CLI, las reglas, las políticas OPA y el Core de evaluación corren en tu máquina, y tu código nunca se sube. Existe exactamente **una** integración de salida (`GeminiProvider`, Google Gemini API), está **desactivada por defecto**, y hoy ningún comando de la CLI publicada la alcanza. Los tarballs que hay en el registro son anteriores a ese endurecimiento: **trata el `GeminiProvider` publicado como no gobernado y no lo armes.** -Reporta cualquier defecto de egreso o de divulgación por la [Política de Seguridad](./SECURITY.md), nunca en un issue público. +Divulgación completa —sub-encargados, credencial, límites, redacción, qué sale y qué no, y las limitaciones conocidas de estos controles—: [Salida de Red y Tratamiento de Datos](./SECURITY.es.md#salida-de-red-y-tratamiento-de-datos). Reporta un defecto de egreso por ahí, nunca en un issue público. --- ## Documentación -| Área | Enlace | +| Para… | Ve a | |---|---| -| Constitución Core | [Hub de Evolith Core](./reference/core/README.es.md) | -| Corpus de producto | [Hub de Producto](./product/README.es.md) | -| Arquitectura Maestra | [Arquitectura Maestra C4](./reference/core/architecture/demos/C4-MASTER-ARCHITECTURE.es.md) | -| Gobernanza SDLC | [Centro de Gobernanza SDLC](./reference/core/sdlc/README.es.md) | -| Topologías | [Hub de Topologías](./reference/core/architecture/topologies/README.es.md) | -| Evolith CLI | [Hub de Evolith CLI](./product/products/smart-cli/README.es.md) | -| Core API | [Hub de Core API](./product/products/core-api/README.es.md) | -| MCP Services | [Hub de MCP Services](./product/products/mcp-services/README.es.md) | -| Agent Runtime | [Hub de Agent Runtime](./reference/core/architecture/foundations/README.es.md) | -| Evolith Tracker | [Hub de Tracker](./product/products/evolith-tracker/README.es.md) | -| Operaciones y SRE | [Hub de Operaciones](./product/operations/README.es.md) | -| Onboarding por rol | Inicio por Rol | -| Glosario del ecosistema | [Glosario](./reference/core/sdlc/glossary/glossary-ecosystem.es.md) | -| Seguimiento de gaps | [Tablero de Gaps](./reference/core/control-center/gaps/gap-tracking.md) | -| Oportunidades | [Tablero de Oportunidades](./reference/core/control-center/opportunities/README.es.md) | -| Todos los artefactos | [Índice Maestro Global](./reference/core/control-center/taxonomy/MASTER_INDEX.es.md) | - ---- - -## Casos de Uso - -**Para equipos de ingeniería** -Aplica decisiones de arquitectura automáticamente. Ejecuta compuertas de fase en CI. Mantén los ADRs vivos y trazables. - -**Para equipos de plataforma** -Consulta la gobernanza de forma remota vía Core API. Integra rulesets en pipelines de despliegue. Bloquea artefactos no conformes antes de que lleguen a producción. - -**Para desarrollo asistido por IA** -Entrega contexto de gobernanza a LLMs a través de MCP. Permite que los agentes de IA validen sus propias salidas contra los rulesets de arquitectura antes de hacer commit. - -**Para productos en crecimiento** -Empieza con un monolito modular. Migra a módulos distribuidos o microservicios cuando el negocio lo exija — Evolith rastrea la transición y aplica consistencia en cada paso. - ---- - -## Roadmap - -Consulta el tablero de seguimiento de gaps para prioridades actuales y elementos abiertos: - -- [Tablero de Gaps](./reference/core/control-center/gaps/gap-tracking.md) -- [Tablero de Oportunidades](./reference/core/control-center/opportunities/README.es.md) -- [Hub de Madurez y Gaps](./reference/core/control-center/README.md) +| Empezar según tu rol | [Inicio por Rol](./reference/core/foundations/inheritance-model/product-quick-start.es.md) | +| Entender las reglas y ADRs | [Hub de Evolith Core](./reference/core/README.es.md) | +| Ver el corpus ejecutable | [Rulesets](./src/rulesets/README.es.md) · [Políticas OPA](./src/rulesets/opa/README.es.md) · [Schemas](./src/rulesets/schema/README.es.md) | +| Elegir o migrar de topología | [Hub de Topologías](./reference/core/architecture/topologies/README.es.md) | +| Usar CLI, MCP o REST | [Hub de Interfaces](./reference/core/interfaces/README.es.md) | +| Ver el estado real del proyecto | [Tablero de Gaps](./reference/core/control-center/gaps/gap-tracking.es.md) · [Madurez](./reference/core/control-center/README.es.md) | +| Resolver una duda concreta | [Q&A — 43 preguntas en 12 categorías](./reference/core/sdlc/q-and-a.es.md) · [Glosario](./reference/core/sdlc/glossary/glossary-ecosystem.es.md) | +| Saber qué va dónde | [Taxonomía del Repositorio](./reference/core/control-center/taxonomy/repository-taxonomy.es.md) | +| Recorrer todo el corpus | [Índice Maestro](./MASTER_INDEX.es.md) · [Hub de Producto](./product/README.es.md) · [Operaciones](./product/operations/README.es.md) | --- ## Contribución -Lee esto antes de abrir un PR: +**Empieza por aquí:** [issues buenos para una primera contribución](https://github.com/beyondnetcode/evolith_arch32/issues?q=is%3Aopen+label%3A%22good+first+issue%22) — la mayoría toca un solo fichero. ¿Dudas antes de abrir un PR? [Discussions](https://github.com/beyondnetcode/evolith_arch32/discussions). + +**Tres formas de aportar sin escribir TypeScript:** corregir una divergencia de conteo entre docs y código · traducir un hub al español · añadir una regla a `src/rulesets/`. -- [Guía de Contribución](./CONTRIBUTING.es.md) -- [Política de Seguridad](./SECURITY.md) -- [AGENTS.es.md](./AGENTS.es.md) — convenciones para contribuidores agentes de IA -- [Taxonomía del Repositorio](./reference/core/control-center/taxonomy/repository-taxonomy.md) — qué va dónde +Antes del PR: [Guía de Contribución](./CONTRIBUTING.es.md) · [Política de Seguridad](./SECURITY.es.md) · [AGENTS.es.md](./AGENTS.es.md) · [CHANGELOG](./CHANGELOG.md) (EN) --- ## Licencia Publicado bajo la [Licencia MIT](./LICENSE). - ---- - -
- Evolith — Framework de Gobernanza Arquitectónica Ejecutable | Corpus de Referencia Multi-Topología | Spec-driven AI-DD -
diff --git a/README.md b/README.md index bf78f4f40..53cdcf28d 100644 --- a/README.md +++ b/README.md @@ -5,28 +5,22 @@ > **Bilingual Navigation:** [Versión en Español](./README.es.md) [![npm](https://img.shields.io/npm/v/@beyondnet/evolith-cli?label=%40beyondnet%2Fevolith-cli)](https://www.npmjs.com/package/@beyondnet/evolith-cli) +[![node](https://img.shields.io/node/v/@beyondnet/evolith-cli)](https://www.npmjs.com/package/@beyondnet/evolith-cli) [![CI](https://img.shields.io/github/actions/workflow/status/beyondnetcode/evolith_arch32/ci-cd.yml?branch=main&label=CI)](https://github.com/beyondnetcode/evolith_arch32/actions/workflows/ci-cd.yml) [![License](https://img.shields.io/badge/license-MIT-informational)](./LICENSE) -**Executable architecture governance. A rule that was not evaluated is not a rule that passed.** +**Your architecture rules, running on every PR. A rule that was not evaluated is not a rule that passed.** +Evolith runs architecture rules — layering, dependencies, security, CI/CD, ADRs — against your repository from CI, and fails the PR. Unlike the rest, it tells you how many rules it **could not evaluate**, and if any of them was blocking, it fails anyway. + ```bash -npm install -g @beyondnet/evolith-cli -evolith init --name my-sat --yes -evolith validate --engine opa +npx -y @beyondnet/evolith-cli init --name my-sat --yes # writes evolith.yaml right here +npx -y @beyondnet/evolith-cli validate --engine opa # expect findings: this is a baseline ``` -[Quick Start](#quick-start) · [Interactive architecture atlas](https://beyondnetcode.github.io/evolith_arch32/) · [How we audit our own claims](./reference/core/control-center/adoption/pending-2026-08-16.md) - ---- - -## What just happened - -That third command evaluated this repository's own rule corpus against a freshly initialized -satellite, using the compiled Rego bundle. This is what `@beyondnet/evolith-cli@1.3.0` printed -in a container with nothing but Node installed: +This is what it prints, with nothing rounded up: ``` **Status:** failed @@ -34,217 +28,104 @@ in a container with nothing but Node installed: **Rules Skipped:** 26 **Rules Errored:** 0 **Rules Total:** 159 - -### Issues -| Rule Id | Severity | Category | Title | Blocking | -| --- | --- | --- | --- | --- | -| ACL-01 | MUST | anti-corruption | Schema Validation Before Ingestion | YES | ... | SEC-INJ-01 | MUST | security | Blocking rule did not run: No shell exec with user input | YES | -| SEC-INJ-02 | MUST | security | Blocking rule did not run: Parameter allowlists for scaffold tools | YES | -| SEC-PATH-01 | MUST | security | Blocking rule did not run: Path input sanitization | YES | ... -└ ❌ Validation failed. See the errors above. - +| GOV-RULE-NOT-APPLICABLE | COULD | governance | 253 corpus rules do not apply to this repository | no | +**Selection:** {"source":"core-default","rulesSelected":412,"corpusTotal":412} $ echo $? 2 ``` -Every line above is the tool's own, character for character. The `...` marks issue rows cut for -length and nothing else -- there are 72 in all, 37 of them blocking. The run also opens with -three `[Nest] WARN Skipping non-standard ruleset` lines: three ruleset files ship in the tarball -that the shipped validator's own schema rejects. That is a real defect, and a README arguing -that unevaluated is not the same as passing does not get to quietly drop it from the capture. - -The Core carries **412 rules**; the 159 above is what this one satellite's run selected from -them. Two different denominators, and a report that blurred them would be the exact defect -this project exists to stop. +72 issue rows, 37 blocking, **nine of them rules the engine could not decide** — reported as failures because an undecided blocking rule is not a rule that passed. Measured on 2026-08-21 with `@beyondnet/evolith-cli@1.3.2`; it takes ~2 s. [Full capture, all 72 rows and both denominators](./docs/evidence/first-run-capture.md). -**Nine of those 37 blocking issues are rules that were skipped.** Not rules that failed -- -rules the engine could not decide, reported as failures because an undecided blocking rule -is not a passing one. Among them are `SEC-INJ-01`, `SEC-INJ-02` and `SEC-PATH-01`. - -This is the whole idea. Every architecture and policy linter silently passes the rules it -never evaluated, so *coverage* and *compliance* produce the same green. Evolith publishes the -denominator and refuses to round it up: - -- The compiled bundle declares which rule ids it can decide, and `skipped` is a first-class - outcome rather than the absence of a violation. -- A blocking rule that ends `skipped` fails the run. That invariant has its own test, written - against the code that did not have it: [`blocking-skipped-invariant.spec.ts`](./src/packages/core-domain/src/application/validators/blocking-skipped-invariant.spec.ts). -- Two engines -- a native TypeScript evaluator and Rego/WASM -- must agree on fixtures, or CI - fails. - -Exit codes are a taxonomy, not a boolean: `0` pass, `1` the tool failed, `2` the gate blocked, -`3` you invoked it wrong. A run that could not produce a verdict never reports one. +[Quick Start](#quick-start) · [PR gate](#use-it-as-a-pr-gate) · [What it governs](#what-it-governs) · [Documentation](#documentation) · [Contribute](#contributing) · [Interactive atlas](https://beyondnetcode.github.io/evolith_arch32/) --- -## Use it as a PR gate +## The idea, in one line -```yaml -- uses: beyondnetcode/evolith_arch32@v1 - with: - fail-on-violation: true -``` +Every architecture linter paints the rules it never ran green: *coverage* and *compliance* end up the same colour. Evolith publishes the denominator and refuses to round it up. `skipped` is a first-class outcome; a blocking rule that ends `skipped` **fails the run** ([invariant with its own test](./src/packages/core-domain/src/application/validators/blocking-skipped-invariant.spec.ts)); and exit codes are a taxonomy: `0` pass · `1` the tool failed · `2` the gate blocked · `3` you invoked it wrong. -Outputs `compliance-status`, `violations-count`, `issues-count`, `exit-code` and -`report-path`. `error` and `invalid-input` mean the repository was **not evaluated** -- they -are not weaker forms of non-compliant, and the job summary says so in words. +And we apply it to ourselves. Three things this front page could keep quiet and does not: -As live context for an AI agent, over stdio: +- **The two engines do not cover the same ground today.** `--engine opa` evaluates 133 of 159 rules; the default native evaluator evaluates 41 and skips 118, on the same repository. They are held to agreement over facts in CI, not over coverage — that part is by design; that the default command never says so is not ([#628](https://github.com/beyondnetcode/evolith_arch32/issues/628)). This page uses `--engine opa` everywhere. +- **Two infrastructure rules are in no denominator.** The loader rejects three ruleset files from its own corpus, and as of 1.3.2 it no longer even says so on stderr ([#575](https://github.com/beyondnetcode/evolith_arch32/issues/575)). +- **What installs is not everything this tree holds.** The tree carries 182 ruleset files; the published CLI loads 177 packs with 412 rules — the loader rejection above is one of the causes. `evolith rulesets` prints what *your* installation loads, pack by pack. -```json -{ "mcpServers": { "evolith": { "command": "npx", "args": ["-y", "@beyondnet/evolith-mcp"] } } } -``` +Full audit of our own claims: [pending items, 2026-08-16](./reference/core/control-center/adoption/pending-2026-08-16.md). --- -## Why not ArchUnit, Conftest or dependency-cruiser? - -Use them. They are good, and Evolith is not a replacement for any of them. +## Quick Start -| Tool | What it does well | Where Evolith differs | -|---|---|---| -| **ArchUnit / ts-arch** | Layer and dependency rules as unit tests, in your language | Rules live outside the codebase as data, so the same corpus governs many repositories and an agent can read it | -| **Conftest / OPA** | Rego against any structured input | Evolith *is* OPA underneath. What it adds is the corpus, the ADR-to-rule derivation, and the coverage accounting | -| **dependency-cruiser** | Dependency graph rules, fast and focused | Broader corpus (SDLC gates, topologies, security standards), and an evidence trail per verdict | -| **Backstage Scorecards** | Catalog-wide health checks with a UI | Runs offline in CI with no catalog to maintain, and blocks a PR rather than colouring a dashboard | +**Requirements:** Node ≥ 18 for the CLI, ≥ 20 for the MCP server · no database, no server, no Docker. Installation is verified in CI on Linux; macOS and Windows are not covered by that gate. -**Where it is genuinely different:** it reports what it could not evaluate. None of the tools -above distinguishes "this rule passed" from "this rule never ran" in their exit status. +```bash +npm install -g @beyondnet/evolith-cli # or use `npx -y @beyondnet/evolith-cli` and install nothing -**What is not built yet, so you do not have to discover it:** the "LLM proposes, a -deterministic verifier disposes" half is a documented direction, not shipped behaviour. No -command in the installed CLI reaches an LLM. See [Network Egress and Data Handling](#network-egress-and-data-handling). +evolith init --name my-sat --yes # configures the CURRENT directory; --name only names the project +evolith validate --engine opa # same directory, no `cd` needed ---- +evolith rulesets # what YOUR installation loads, pack by pack +evolith validate --engine opa --select rulesets/acl/anti-corruption-layer.rules.json +evolith validate --engine opa --phase qa +evolith adr create # manage Architecture Decision Records +``` -## Menu - -- [What is Evolith?](#what-is-evolith) -- [Why Evolith?](#why-evolith) -- [Core Concepts](#core-concepts) -- [Product Ecosystem](#product-ecosystem) -- [How It Works](#how-it-works) -- [Architecture Overview](#architecture-overview) -- [Main Components](#main-components) -- [Quick Start](#quick-start) -- [Questions & Answers](#questions--answers) -- [Network Egress and Data Handling](#network-egress-and-data-handling) -- [Documentation](#documentation) -- [Use Cases](#use-cases) -- [Roadmap](#roadmap) -- [Contributing](#contributing) -- [License](#license) +`--engine opa` evaluates with the compiled Rego bundle; without the flag it runs the native evaluator, which covers less today. To create a new directory instead, pass it positionally: `evolith init my-sat --yes`. With `--format json` it never prompts and prints exactly one JSON object on stdout; `--dry-run` writes nothing. ---- +> **Expect findings on the first run.** A freshly configured repository is a baseline, not a pass: many rules assume a fuller layout. To start from what you have actually adopted, use `--select` with the refs `evolith rulesets` prints; bringing the default to zero is tracked as GT-571 on the [gap board](./reference/core/control-center/gaps/gap-tracking.md). -## What is Evolith? +Configuration lives in **`evolith.yaml`**, which `init` writes for you: -Evolith is an **executable architectural governance framework**. It encodes how software is built — across multiple architecture styles — as verifiable rules, ADRs, and phase gates that teams, platforms, and AI agents can actually run. +```yaml +coreRef: { version: "1.0.0", path: "../evolith" } +product: { name: my-sat, type: enterprise-application, phase: phase-0 } +tools: { runtime: nodejs, architecture: clean, ci: github-actions } +``` -Governance in Evolith is not a document. It is an operational capability exposed through a CLI, an MCP server, and a REST API. +**What it inspects:** repository structure, CI workflows, manifests and governance artifacts — not your code's AST. That makes it largely language-agnostic; the subset that looks at dependencies and linters assumes a Node/TypeScript repository. Reference: [Evolith CLI hub](./product/products/smart-cli/README.md) · [Quickstart guide](./docs/guides/evolith-quickstart.md) --- -## Why Evolith? - -Most projects accumulate ADRs and architecture docs that nobody reads and nobody enforces. Systems drift. Decisions are forgotten. Consistency breaks silently. - -Evolith makes governance **executable**: +## Use it as a PR gate -- Rules are validated automatically, not reviewed manually. -- Phase gates block progression until quality criteria are met. -- AI agents and CI pipelines consume the same governance artifacts as humans. -- Architecture decisions are traceable from ADR to production code. +```yaml +- uses: beyondnetcode/evolith_arch32@v1 + with: + fail-on-violation: true +``` ---- +Outputs `compliance-status`, `violations-count`, `issues-count`, `exit-code` and `report-path`. `error` and `invalid-input` mean the repository was **not evaluated** — they are not weaker forms of non-compliant, and the job summary says so in words. -## Core Concepts +As live context for an AI agent, over stdio: -| Concept | What it is | -|---|---| -| **SDLC Phases** | The five stages from idea to production: Discovery → Design → Construction → QA → Delivery | -| **Gates** | Automated checkpoints that close each phase before the next begins | -| **Topologies** | Architecture styles (e.g., modular monolith, microservices, event-driven, agentic-AI) | -| **ADRs** | Architecture Decision Records — the authoritative log of architectural choices | -| **Blueprints** | Canonical design templates for each topology | -| **Rulesets** | Machine-readable rules enforced by the CLI and Core API | -| **OPA Policies** | Open Policy Agent policies for fine-grained governance checks | -| **Artifacts** | Structured outputs at each phase: specs, schemas, manifests, contracts | -| **AI Agents** | Specialized agents (Winston and others) that participate in the SDLC as first-class contributors | - -Full details: [Core Concepts](./reference/core/README.md) · [Topologies](./reference/core/architecture/topologies/README.md) +```json +{ "mcpServers": { "evolith": { "command": "npx", "args": ["-y", "@beyondnet/evolith-mcp"] } } } +``` --- -## Product Ecosystem - -Evolith ships as a suite of coordinated products built on a common foundation. - -| Product | Role | -|---|---| -| **[Evolith Core](reference/README.md)** | Provider-neutral constitution: principles, ADRs, rulesets, topologies, and contracts | -| **[Evolith CLI](product/products/smart-cli/README.md)** | Local enforcement — validate code, run gates, manage ADRs, serve MCP | -| **[Core API](product/products/core-api/README.md)** | REST service for remote governance queries and evaluation | -| **[MCP Services](product/products/mcp-services/README.md)** | Governance as live context for LLMs and AI agents (52 tools, 12 resources, 8 prompts) | -| **[Agent Runtime](reference/core/architecture/foundations/README.md)** | Agentic mediation layer — orchestrates Core through Ports & Adapters; Hermes is one replaceable adapter | -| **[Evolith Tracker](product/products/evolith-tracker/README.md)** | Business lifecycle governance — phases, owners, funding, and ROI | -| **[Commercial Vision](product/suite/vision/evolith-commercial-brochure.md)** | Product strategy and enterprise monetization narrative (Hub & Spoke deployment) | -| **[Rulesets](src/rulesets/README.md)** | Machine-readable enforcement rules per topology | -| **[OPA Policies](src/rulesets/opa/README.md)** | Fine-grained policy checks integrated into the pipeline | -| **[Schemas & Manifests](src/rulesets/schema/README.md)** | Structured contracts for artifacts and topology definitions | - ---- +## Why not ArchUnit, Conftest or dependency-cruiser -## How It Works +Use them. They are good, and Evolith replaces none of them. -``` -Developer / AI Agent / External Trigger - │ - ▼ - Evolith CLI ──────────────────────────────► MCP Server - (local enforcement) (AI agent context) - │ - ▼ - Core API ────────────────────────────► Evolith Tracker - (remote governance) (business lifecycle) - │ - ▼ - Agent Runtime ───────────────────────────► Hermes (adapter) - (agentic mediation, Ports & Adapters) (.harness · OPA · Tracker · Memory) - │ - ▼ - Rulesets · OPA Policies · ADRs · Blueprints - (the shared governance artifacts) -``` +| Tool | What it does well | Where Evolith differs | +|---|---|---| +| **ArchUnit / ts-arch** | Layer and dependency rules as unit tests, in your language | Rules live outside the codebase as data: one library governs many repositories and an agent can read it | +| **Conftest / OPA** | Rego against any structured input | Evolith *is* OPA underneath. It adds the rule library, the ADR-to-rule derivation and the coverage accounting | +| **Backstage Scorecards** | Catalog-wide health checks with a UI | Runs offline in CI with no catalog to maintain, and blocks a PR rather than colouring a dashboard | -1. **Evolith CLI** validates code locally against rulesets and runs phase gates. -2. **Core API** exposes the same governance remotely for CI pipelines and orchestrators. -3. **MCP Server** feeds governance context to LLMs and AI agents in real time. -4. **Agent Runtime** orchestrates Core capabilities through a Ports & Adapters model — Hermes is one replaceable adapter. -5. **Evolith Tracker** coordinates the business side — who owns what, what's funded, what ships when. +Against **dependency-cruiser**, the scope is broader (phase gates, architecture styles, security standards) and it keeps why each rule failed. -All products share the same artifacts defined in **Evolith Core**. +**What is NOT built yet, so you do not have to find out:** the "LLM proposes, a deterministic verifier disposes" half is a documented direction, not shipped behaviour. No command in the installed CLI reaches an LLM. --- -
- - - Evolith E2E Product Vision - Governed Composition, stateless evaluation Core, federated five-phase SDLC - - -Evolith E2E Product Vision - Open interactive viewer - drag to pan, scroll to zoom, fullscreen +## What it governs -
- -## Architecture Overview - -Evolith governs **8 topologies** across four axes: +Eight **architecture styles** (we call them *topologies*) across five axes. The same rules follow you when the monolith splits into services. | Axis | Topologies | |---|---| @@ -254,242 +135,67 @@ Evolith governs **8 topologies** across four axes: | Data | `data-mesh` | | AI | `agentic-ai` | -Each topology has its own ADRs, OPA policies, AI rulesets, and UMS contracts. Systems migrate between topologies as the business scales — this is **Progressive Architecture**. +On top runs a **free, MIT** library: in this tree, 142 ADRs, 182 ruleset files and 50 phase schemas, plus the five SDLC phases (Discovery → Design → Construction → QA → Delivery) and the gates that block the move from one to the next. Those three counts are measured and verified by CI on every PR. What your installation actually evaluates is printed by `evolith rulesets`: today, 177 packs with 412 rules, 188 of them able to fail a run. The only paid product will be **Evolith Tracker**, not yet launched. -Full reference: [Architecture hub](./reference/core/architecture/README.md) · [C4 Master Architecture](./reference/core/architecture/demos/C4-MASTER-ARCHITECTURE.md) +
How the CLI, the Core and the five SDLC phases fit together
Open the interactive viewer — drag to pan, scroll to zoom
--- -## Main Components +## Product ecosystem -``` -evolith/ -├── src/packages/agent-runtime/ # @beyondnet/evolith-agent-runtime — Ports & Adapters agentic layer -├── src/apps/agent-runtime-api/ # NestJS HTTP service wrapping the runtime (POST /v1/agent/handle) -├── reference/core/ # Engineering constitution and principles -├── reference/core/architecture/ # Topologies, blueprints, ADRs, and agent-runtime docs -├── reference/core/sdlc/ # SDLC phases, gates, standards, and glossary -├── product/products/ # Evolith CLI, Core API, MCP, Tracker, UMS -└── product/operations/ # SRE, infra, quality gates -``` - -Entry point for each area: [Global Master Index](./reference/core/control-center/taxonomy/MASTER_INDEX.md) - ---- - -## Quick Start - -The npm package is `@beyondnet/evolith-cli`; it installs two equivalent bins, **`evolith`** (the documented name) and `evolith-cli` (compatibility). Both self-identify as `evolith` in `--help`. - -```bash -# 1. Install the CLI -npm install -g @beyondnet/evolith-cli - -# 2. Initialize the CURRENT directory as an Evolith satellite. -# --name sets the project name written into evolith.yaml. -# --yes runs without prompts (also implied by a non-TTY stdin or --format json). -evolith init --name my-sat --yes - -# 3. Validate the satellite you just created — same directory, no `cd` needed -evolith validate - -# Validate a specific SDLC phase -evolith validate --phase qa - -# Manage Architecture Decision Records -evolith adr create -evolith adr list - -# Serve governance as live context for AI agents — the MCP server ships as a -# separate package (@beyondnet/evolith-mcp) with its own bin: -evolith-mcp serve -``` - -To scaffold into a **new** directory instead of the current one, pass it as the positional argument (or via `--dir`); `--name` only ever names the project, it never creates a directory: - -```bash -evolith init my-sat --yes && cd my-sat && evolith validate -``` - -Machine-readable runs (`--format json`) never prompt and print exactly one envelope on stdout; a failed `init` exits non-zero. `evolith init --dry-run` writes nothing. - -> **Expect findings on the first `validate`.** A freshly initialized satellite is a baseline, not a pass: some rules still assume a fuller repository layout and report blocking findings on a phase-0 project. Reducing that to zero is tracked on the [Gap Tracking Board](./reference/core/control-center/gaps/gap-tracking.md) (GT-571). - -Evolith CLI is configured via **`evolith.yaml`**; run `evolith --help` for the current command list. Full reference: [Evolith CLI hub](./product/products/smart-cli/README.md) - ---- - -## Questions & Answers - -
-What is Evolith in one sentence? -
-Evolith is an executable architectural governance framework — it makes sure architecture decisions actually get followed, automatically, whether the code is written by a human or an AI agent. -
- -
-What would I use it for? -
-
    -
  1. Instant feedback on architecture decisions — run evolith validate and know in seconds if your code follows your team's rules.
  2. -
  3. No more surprise refactors — architecture drift is caught at the gate, not six months later.
  4. -
  5. AI-proof governance — when an AI agent writes code, Evolith ensures it follows the same rules a senior architect would enforce.
  6. -
-
- -
-How much does it cost? -
-The core platform is completely free (MIT license): CLI, MCP server, Core API, Agent Runtime, 142 ADRs, 181 ruleset files carrying 412 rules, 50 phase-gate schemas. The only paid product is Evolith Tracker (enterprise multi-tenant governance — not yet released). -
- -
-How do I get started? -
- -```bash -npm install -g @beyondnet/evolith-cli -evolith init --name my-sat --yes # initializes the CURRENT directory -evolith validate # same directory, no `cd` -``` - -No database, no server, no Docker required. -
- -
-What topologies does it cover? -
-Evolith governs 8 topologies across 5 dimensions: Modular Monolith, Distributed Modules, Microservices (progressive-axis), Serverless, Edge Computing (execution), Event-Driven (integration), Data Mesh (data), and Agentic AI. All are composable. -
- -
-How does it work with AI tools like Cursor or Claude? -
-Evolith ships an MCP server inside the CLI. Add it to your AI tool's config and your agent can query architecture rules, validate code, and evaluate gate readiness — all without bypassing governance. -
- -**[Full Q&A: 64 questions across 12 categories →](./reference/core/sdlc/q-and-a.md)** - ---- - -## Network Egress and Data Handling - -Evolith is local-first: the CLI, the rulesets, the OPA policies and the stateless evaluation Core all run on your machine, and your source files are never uploaded — evaluation happens where the code is. There is exactly **one** outbound integration in the corpus, it is **off by default**, and this is its complete disclosure. - -| Item | Disclosure | +| Product | Role | |---|---| -| **Component** | `GeminiProvider`, a public export of `@beyondnet/evolith-agent-runtime` | -| **Endpoint** | one HTTPS `POST` to `https://generativelanguage.googleapis.com/v1beta/models/:generateContent`, default model `gemini-2.5-flash`. No other host is contacted by the package. | -| **Sub-processor** | **Google LLC (Gemini API)**. Prompt content sent through this path is processed by Google under its terms for that API. No other sub-processor is involved. | -| **Default state** | **DISABLED.** With no configuration the provider opens no socket: it records the refused attempt and throws `LlmEgressDisabledError`. Out of the box the package makes zero network calls. | -| **Opt-in** | `EVOLITH_LLM_EGRESS=true` (or `1`), or an explicit `new GeminiProvider({ enabled: true })`. There is no implicit way to arm it. | -| **Credential** | `EVOLITH_LLM_API_KEY`, falling back to `GEMINI_API_KEY`. It travels in the `x-goog-api-key` request header and never in the URL. Without a key the call is refused before a socket opens. | -| **Limits** | 30,000 ms `AbortController` timeout; 60,000 bytes / ~15,000 estimated tokens. Over budget the request **fails closed** — nothing is truncated and sent anyway. | - -**What leaves the machine** - -- Through the governed `IAssistantTransport` seam: the request intent, the optional tool id, the request parameters, the `dryRun` flag, and the governed skill catalog (id and description only). -- Through the deprecated `ILLMProvider` seam (`generateStructuredJson`): the caller's system prompt and user prompt, verbatim. -- Both are secret-redacted before serialization, over 8 pattern classes: PEM private keys, JWTs, AWS access key ids, Google API keys, GitHub PATs, Slack tokens, `Bearer` tokens, and generic `KEY`/`SECRET`/`TOKEN`/`PASSWORD` assignments. +| **Evolith Core** | The rules themselves: files you can read, edit and version | +| **Evolith CLI** | Local application — validates the repo, runs phase gates, manages ADRs | +| **Core API** | REST service to query and evaluate governance remotely | +| **MCP Services** | Governance as live context for agents (52 tools, 12 resources, 8 prompts) | +| **Agent Runtime** | Drives the Core from an agent, through Ports and Adapters. Experimental | +| **Evolith Tracker** | Commercial lifecycle-governance product. Not yet launched | -**What does not leave the machine** +**Who it is for:** -Tenant id, product id, initiative id, workspace reference and requester identity are excluded from the transport payload by construction (data minimization), as are repository contents. +- Engineering teams that want their ADRs enforced in CI, not reviewed by hand. +- Platform teams blocking non-conformant artifacts before production. +- AI-assisted development that needs the agent to validate its output against the same rules. -**Observability** +**Adoption, unvarnished:** 1,109 npm downloads last month (2026-07-21 → 2026-08-19), no confirmed external adoption. The repository governs itself, and that is all the evidence there is. -Every attempt — including refusals — emits one content-free JSON line prefixed `[evolith:llm-egress]` with provider, endpoint, purpose, outcome, byte and token counts, redaction count, HTTP status, duration and correlation id. Prompt and response content are never logged. - -**Human-in-the-loop** - -The intended wiring injects `GeminiProvider` as the `IAssistantTransport` of `SupervisedAssistantClient`, which is itself off by default and requires an explicit human approval before the transport is reached. - -**Other outbound traffic** - -- **OpenTelemetry export** from the CLI is off unless `OTEL_ENABLED=true`, and then it goes only to the collector you configure. -- **Core API / MCP HTTP transport** are servers you host; the CLI contacts a remote Core only when you configure one. -- No telemetry, analytics or licence check is phoned home by any surface. +--- -**Honest current state** +## Network egress -- Redaction is pattern-based, not a DLP control: it materially reduces accidental credential egress, it does not guarantee absence. -- The header, timeout, budget, redaction and schema-validation controls are covered by unit tests with an injected `fetch`; they have **not** been exercised against the live Google endpoint. -- The timeout and budget values are inherited from the repository's own CI reviewer and are not tuned for large interactive prompts, which fail closed rather than degrade. -- No command registered in the shipped CLI reaches this provider today, so a default CLI install performs no LLM egress at all. -- The npm tarballs currently published predate this hardening; the controls above are on `develop` and reach the registry with the next release, tracked as GT-570 on the [Gap Tracking Board](./reference/core/control-center/gaps/gap-tracking.md). +Local-first: the CLI, the rules, the OPA policies and the evaluation Core run on your machine, and your code is never uploaded. There is exactly **one** outbound integration (`GeminiProvider`, Google Gemini API), it is **off by default**, and no command in the published CLI reaches it today. The tarballs on the registry predate that hardening: **treat the published `GeminiProvider` as ungoverned and do not wire it up.** -Report a suspected egress or disclosure defect through the [Security Policy](./SECURITY.md), never in a public issue. +Full disclosure — sub-processors, credential, limits, redaction, what leaves and what does not, and the known limitations of these controls: [Network Egress and Data Handling](./SECURITY.md#network-egress-and-data-handling). Report an egress defect there, never in a public issue. --- ## Documentation -| Area | Link | +| To… | Go to | |---|---| -| Core constitution | [Evolith Core hub](./reference/core/README.md) | -| Product corpus | [Product hub](./product/README.md) | -| Interface how-to (CLI / MCP / REST) | [Interface guides](./reference/core/interfaces/README.md) | -| Master Architecture | [C4 Master Architecture](./reference/core/architecture/demos/C4-MASTER-ARCHITECTURE.md) | -| SDLC governance | [SDLC Governance Center](./reference/core/sdlc/README.md) | -| Topologies | [Topologies hub](./reference/core/architecture/topologies/README.md) | -| Evolith CLI | [Evolith CLI hub](./product/products/smart-cli/README.md) | -| Core API | [Core API hub](./product/products/core-api/README.md) | -| MCP Services | [MCP Services hub](./product/products/mcp-services/README.md) | -| Agent Runtime | [Agent Runtime hub](./reference/core/architecture/foundations/README.md) | -| Evolith Tracker | [Tracker hub](./product/products/evolith-tracker/README.md) | -| Operations & SRE | [Operations hub](./product/operations/README.md) | -| Onboarding by role | [Getting Started by Role](./reference/core/foundations/inheritance-model/product-quick-start.md) | -| Ecosystem glossary | [Glossary](./reference/core/sdlc/glossary/glossary-ecosystem.md) | -| Questions & Answers | [Q&A](./reference/core/sdlc/q-and-a.md) | -| Gap tracking | [Gap Tracking Board](./reference/core/control-center/gaps/gap-tracking.md) | -| Opportunities | [Opportunities Board](./reference/core/control-center/opportunities/README.md) | -| All artifacts | [Global Master Index](./reference/core/control-center/taxonomy/MASTER_INDEX.md) | - ---- - -## Use Cases - -**For engineering teams** -Enforce architecture decisions automatically. Run phase gates in CI. Keep ADRs alive and traceable. - -**For platform teams** -Query governance remotely via Core API. Integrate rulesets into deployment pipelines. Block non-compliant artifacts before they reach production. - -**For AI-assisted development** -Feed governance context to LLMs through MCP. Let AI agents validate their own outputs against architecture rulesets before committing. - -**For growing products** -Start with a modular monolith. Migrate to distributed modules or microservices when the business demands it — Evolith tracks the transition and enforces consistency at every step. - ---- - -## Roadmap - -See the active gap tracking board for current priorities and open items: - -- [Gap Tracking Board](./reference/core/control-center/gaps/gap-tracking.md) -- [Opportunities Board](./reference/core/control-center/opportunities/README.md) -- [Maturity & Gaps hub](./reference/core/control-center/README.md) +| Start from your role | [Start by Role](./reference/core/foundations/inheritance-model/product-quick-start.md) | +| Understand the rules and ADRs | [Evolith Core hub](./reference/core/README.md) | +| See the executable corpus | [Rulesets](./src/rulesets/README.md) · [OPA policies](./src/rulesets/opa/README.md) · [Schemas](./src/rulesets/schema/README.md) | +| Choose or migrate a topology | [Topologies hub](./reference/core/architecture/topologies/README.md) | +| Use the CLI, MCP or REST | [Interfaces hub](./reference/core/interfaces/README.md) | +| See the project's real state | [Gap board](./reference/core/control-center/gaps/gap-tracking.md) · [Maturity](./reference/core/control-center/README.md) | +| Answer a specific question | [Q&A — 43 questions in 12 categories](./reference/core/sdlc/q-and-a.md) · [Glossary](./reference/core/sdlc/glossary/glossary-ecosystem.md) | +| Know what goes where | [Repository Taxonomy](./reference/core/control-center/taxonomy/repository-taxonomy.md) | +| Walk the whole corpus | [Master Index](./MASTER_INDEX.md) · [Product hub](./product/README.md) · [Operations](./product/operations/README.md) | --- ## Contributing -Read these before opening a PR: +**Start here:** [issues that are good for a first contribution](https://github.com/beyondnetcode/evolith_arch32/issues?q=is%3Aopen+label%3A%22good+first+issue%22) — most touch a single file. Unsure before opening a PR? [Discussions](https://github.com/beyondnetcode/evolith_arch32/discussions). + +**Three ways to contribute without writing TypeScript:** correct a count that disagrees between docs and code · translate a hub into Spanish · add a rule to `src/rulesets/`. -- [Contributing Guide](./CONTRIBUTING.md) -- [Security Policy](./SECURITY.md) -- [AGENTS.md](./AGENTS.md) — conventions for AI agent contributors -- [Repository Taxonomy](./reference/core/control-center/taxonomy/repository-taxonomy.md) — what goes where +Before the PR: [Contribution Guide](./CONTRIBUTING.md) · [Security Policy](./SECURITY.md) · [AGENTS.md](./AGENTS.md) · [CHANGELOG](./CHANGELOG.md) --- ## License -Published under the [MIT License](./LICENSE). - ---- - -
- Evolith — Executable Architectural Governance Framework | Multi-Topology Reference Corpus | Spec-driven AI-DD -
+Released under the [MIT License](./LICENSE). diff --git a/docs/evidence/first-run-capture.es.md b/docs/evidence/first-run-capture.es.md new file mode 100644 index 000000000..942e47c03 --- /dev/null +++ b/docs/evidence/first-run-capture.es.md @@ -0,0 +1,296 @@ +# Captura de la primera ejecución + +La portada cita unas cuantas cifras de una ejecución del CLI publicado contra un +satélite recién inicializado. Este fichero es esa ejecución, entera, para que los +contadores de la portada se puedan comprobar en vez de creer. + +## Condiciones + +| | | +|---|---| +| **Fecha** | 2026-08-21 | +| **Paquete** | `@beyondnet/evolith-cli@1.3.2`, resuelto con `npx -y` desde el registro público | +| **Corpus del tarball** | 177 packs · 412 reglas · 188 que pueden hacer fallar una ejecución (`evolith rulesets`) | +| **Corpus de este árbol** | 182 ficheros de reglas · 415 reglas — el árbol va por delante del paquete publicado | +| **Repositorio evaluado** | un directorio vacío, luego `evolith init --name my-sat --yes` y nada más | +| **Código de salida** | `2` — la puerta bloqueó | + +Para reproducirlo: + +```bash +mkdir my-sat && cd my-sat +npx -y @beyondnet/evolith-cli@1.3.2 init --name my-sat --yes +npx -y @beyondnet/evolith-cli@1.3.2 validate --engine opa +echo $? +``` + +## Los dos denominadores + +En la salida aparecen dos totales distintos y miden cosas distintas. Un informe +que los mezclara sería el defecto exacto que este proyecto existe para evitar. + +- **412** es el corpus que carga el CLI instalado. +- **159** es lo que la ejecución de este satélite seleccionó de él. La fila + `GOV-RULE-NOT-APPLICABLE` dice el resto con palabras: 253 reglas del corpus no + aplican a este repositorio, y `253 + 159 = 412`. +- De esas 159, **133 se evaluaron** y **26 se saltaron** — el motor no pudo + decidirlas. +- La ejecución reporta **72 issues, 37 de ellos bloqueantes**. **Nueve de los 37 + son reglas saltadas**, no reglas que fallaron: llevan el prefijo + `Blocking rule did not run:`. Una regla bloqueante que acaba sin decidir hace + fallar la ejecución, porque una regla sin decidir no es una regla que pasa. + +## La ejecución, sin editar + +Se han quitado las secuencias de control del terminal y el spinner de progreso; +nada más se elimina, reordena ni reescribe. `stderr` salió vacío. + +``` +**Status:** failed +**Rules Checked:** 133 +**Rules Skipped:** 26 +**Rules Errored:** 0 +**Rules Total:** 159 + +### Issues +| Rule Id | Severity | Category | Title | Blocking | +| --- | --- | --- | --- | --- | +| ACL-01 | MUST | anti-corruption | Schema Validation Before Ingestion | YES | +| ACL-02 | MUST | anti-corruption | Transformation Traceability | YES | +| ACL-04 | MUST | anti-corruption | ACL Version Synchronization with Core | YES | +| HXA-03 | MUST | layer-structure | Infrastructure (Adapters) implements Core ports | YES | +| CICD-01 | MUST | security-scan | CodeQL Static Analysis runs on every PR | YES | +| CICD-02 | MUST | dependency-scan | Dependency vulnerability scan blocks merge | YES | +| CICD-03 | MUST | secret-detection | Secret detection enabled on repository | YES | +| CICD-04 | MUST | pipeline-structure | All quality gates execute before merge | YES | +| MTN-01 | MUST | filtering-layer | Application-layer tenant filtering is primary | YES | +| MTN-02 | MUST | filtering-layer | Database-native tenant enforcement is secondary | YES | +| MTN-03 | MUST | context-propagation | Tenant context propagated through all layers | YES | +| MTN-06 | MUST | audit-trail | Tenant-scoped audit trail maintained | no | +| MTN-07 | MUST | data-migration | Tenant migration path defined for schema changes | YES | +| MTN-08 | MUST | external-api | External APIs validate tenant context on every request | YES | +| TPY-03 | MUST | integration-testing | Integration tests use ephemeral containers | no | +| TPY-04 | MUST | e2e-testing | E2E tests cover full HTTP routes | no | +| PROT-05 | MUST | protobuf-centralization | Proto files centralized in Contracts library | YES | +| RUNT-01 | MUST | runtime-selection | Runtime selected by workload profile only | YES | +| RUNT-08 | MUST | contract-registry | Contracts centrally stored and versioned | YES | +| GIT-03 | MUST | code-review | PR requires minimum 1 approved review | YES | +| GIT-10 | MUST | code-review | Higher environments require stronger approval | YES | +| DORA-01 | MUST | metrics | Deployment Frequency | no | +| DORA-02 | MUST | metrics | Lead Time for Changes | no | +| DORA-03 | MUST | metrics | Change Failure Rate | no | +| DORA-04 | MUST | metrics | Time to Restore | no | +| SPACE-01 | MUST | metrics | Reliability (Observability) | YES | +| SPACE-02 | SHOULD | metrics | Culture (Team Health) | no | +| SPACE-03 | SHOULD | metrics | Execution (Throughput) | no | +| SPACE-04 | SHOULD | metrics | Communication (Visibility) | no | +| SPACE-05 | MUST | metrics | Sponsorship (Leadership Alignment) | no | +| INH-02 | MUST | inheritance | Version Pinning | no | +| INH-04 | MUST | inheritance | Satellite Extension via Local ADRs | no | +| INH-06 | MUST | inheritance | Mandatory Architecture Tracker | no | +| KI-R02 | MUST | general | Winston owns review | YES | +| KI-R04 | MUST | general | Topology contract completeness | YES | +| SVC-01 | MUST | general | Each satellite project must have exactly one evolith.yaml at its project root | no | +| SVC-02 | MUST | general | Satellite name must be unique across all Evolith satellites | no | +| SVC-05 | MUST | general | Core version referenced must exist in Evolith Core registry | no | +| MCP-01 | MUST | protocol | Initialize Request Must Return Capabilities | YES | +| MCP-02 | MUST | tools | Tools List Must Be Complete and Stable | YES | +| MCP-03 | MUST | resources | Resources Must Preserve Core Traceability | YES | +| MCP-04 | MUST | security | HTTP Transport Requires Explicit Authentication Mode | YES | +| MCP-05 | SHOULD | observability | MCP Calls Should Emit Metrics | no | +| OBS-EVD-01 | MUST | tracing | Production Paths Emit Trace Context | YES | +| OBS-EVD-02 | MUST | logging | Structured Logs Carry Request Context | YES | +| OBS-EVD-03 | MUST | metrics | Service Health Metrics Are Reported | YES | +| OBS-EVD-04 | SHOULD | dashboards | Gate Evidence References Dashboard | no | +| QT-05 | MUST | testing | Blocking rule did not run: Testing Pyramid Distribution | YES | +| SEC-INJ-01 | MUST | security | Blocking rule did not run: No shell exec with user input | YES | +| SEC-INJ-02 | MUST | security | Blocking rule did not run: Parameter allowlists for scaffold tools | YES | +| SEC-PATH-01 | MUST | security | Blocking rule did not run: Path input sanitization | YES | +| SEC-PATH-02 | MUST | security | Blocking rule did not run: Base directory containment | YES | +| SEC-RL-01 | MUST | security | Blocking rule did not run: Rate limiting on HTTP endpoints | YES | +| SEC-RL-02 | MUST | security | Blocking rule did not run: Request body size limits | YES | +| SEC-TIMING-01 | MUST | security | Blocking rule did not run: Constant-time credential comparison | YES | +| SEC-TIMING-02 | MUST | security | Blocking rule did not run: No early rejection on credential length | YES | +| SLSA-PROV-L1 | SHOULD | slsa-build | MUST rule not evaluated: Build L1 — EVERY publishing path generates provenance, not just the main one | no | +| SLSA-BUILD-L1 | SHOULD | slsa-build | MUST rule not evaluated: Build L1 — the artifact is built by the run whose provenance describes it | no | +| SLSA-AUTH-L2 | SHOULD | slsa-build | MUST rule not evaluated: Build L2 — the PUBLISHING job can mint the identity that signs the provenance | no | +| SLSA-HOSTED-L2 | SHOULD | slsa-build | MUST rule not evaluated: Build L2 — nothing offers a way to publish from a workstation | no | +| SSDF-PW.4.1 | SHOULD | ssdf-third-party | MUST rule not evaluated: PW.4.1 — third-party components resolve to pinned versions in CI | no | +| SSDF-PW.4.4 | SHOULD | ssdf-third-party | MUST rule not evaluated: PW.4.4 — components are re-verified over their life cycle, not once at adoption | no | +| SSDF-PW.7.2 | SHOULD | ssdf-review | MUST rule not evaluated: PW.7.2 — code is analysed by both a code scanner and a secret scanner | no | +| SSDF-PS.3.2 | SHOULD | ssdf-provenance | MUST rule not evaluated: PS.3.2 — an SBOM that is generated but never published satisfies nothing | no | +| SSDF-RV.1.2 | SHOULD | ssdf-vulnerability | MUST rule not evaluated: RV.1.2 — the code scanner sees the whole change, not a filtered slice | no | +| SSDF-RV.1.3 | SHOULD | ssdf-vulnerability | MUST rule not evaluated: RV.1.3 — there is a disclosure policy that names how to report | no | +| ISO5055-SEC | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Security | no | +| ISO5055-REL | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Reliability | no | +| ISO5055-PERF | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Performance Efficiency | no | +| ISO5055-MAINT | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Maintainability | no | +| GOV-RULE-NOT-APPLICABLE | COULD | governance | 253 corpus rules do not apply to this repository | no | +**Selection:** {"source":"core-default","requested":[],"matched":[],"unmatched":[],"rulesSelected":412,"corpusTotal":412} +**Core Ref:** {"version":"1.0.0","path":"../evolith"} +**Timestamp:** 2026-08-21T16:05:06.083Z +└ ❌ Validation failed. See the errors above. +``` + +## El mismo repositorio, con el motor por defecto + +`--engine opa` evalúa con el bundle Rego compilado. Sin la bandera el CLI corre el +evaluador nativo en TypeScript, y sobre el mismo repositorio, la misma versión y +el mismo corpus no cubre lo mismo: + +| | `validate --engine opa` | `validate` | +|---|---|---| +| Reglas evaluadas | 133 | **41** | +| Reglas saltadas | 26 | **118** | +| Filas de issues | 72 | 114 | +| Bloqueantes | 37 | 77 | +| Código de salida | 2 | 2 | + +CI exige que los dos motores coincidan sobre fixtures. No exige que tengan la +misma cobertura sobre un repositorio real, y hoy no la tienen. Por eso la portada +usa `--engine opa` en todas partes. + +``` +**Status:** failed +**Rules Checked:** 41 +**Rules Skipped:** 118 +**Rules Errored:** 0 +**Rules Total:** 159 + +### Issues +| Rule Id | Severity | Category | Title | Blocking | +| --- | --- | --- | --- | --- | +| ACL-02 | MUST | anti-corruption | Blocking rule did not run: Transformation Traceability | YES | +| ACL-03 | MUST | anti-corruption | Blocking rule did not run: Reject Non-Compliant Data | YES | +| HXA-03 | MUST | layer-structure | Blocking rule did not run: Infrastructure (Adapters) implements Core ports | YES | +| CICD-01 | MUST | security-scan | Blocking rule did not run: CodeQL Static Analysis runs on every PR | YES | +| CICD-02 | MUST | dependency-scan | Blocking rule did not run: Dependency vulnerability scan blocks merge | YES | +| CICD-03 | MUST | secret-detection | Blocking rule did not run: Secret detection enabled on repository | YES | +| CICD-04 | MUST | pipeline-structure | Blocking rule did not run: All quality gates execute before merge | YES | +| CICD-05 | SHOULD | documentation | MUST rule not evaluated: Security findings documented with justification | no | +| CICD-06 | SHOULD | sla-compliance | MUST rule not evaluated: Critical findings resolved within 24 hours | no | +| CICD-07 | SHOULD | sla-compliance | MUST rule not evaluated: High findings resolved within 72 hours | no | +| MTN-01 | MUST | filtering-layer | Blocking rule did not run: Application-layer tenant filtering is primary | YES | +| MTN-02 | MUST | filtering-layer | Blocking rule did not run: Database-native tenant enforcement is secondary | YES | +| MTN-03 | MUST | context-propagation | Blocking rule did not run: Tenant context propagated through all layers | YES | +| MTN-04 | MUST | data-isolation | Blocking rule did not run: Cross-tenant data access prohibited | YES | +| MTN-06 | SHOULD | audit-trail | MUST rule not evaluated: Tenant-scoped audit trail maintained | no | +| MTN-07 | MUST | data-migration | Blocking rule did not run: Tenant migration path defined for schema changes | YES | +| MTN-08 | MUST | external-api | Blocking rule did not run: External APIs validate tenant context on every request | YES | +| TPY-01 | SHOULD | test-layer-distribution | MUST rule not evaluated: Test distribution follows 70/20/10 pyramid | no | +| TPY-02 | MUST | unit-testing | Blocking rule did not run: Unit tests dominate total test volume | YES | +| TPY-03 | SHOULD | integration-testing | MUST rule not evaluated: Integration tests use ephemeral containers | no | +| TPY-04 | SHOULD | e2e-testing | MUST rule not evaluated: E2E tests cover full HTTP routes | no | +| TPY-05 | MUST | coverage-threshold | Blocking rule did not run: Business logic coverage >= 80% | YES | +| TPY-06 | MUST | per-layer-thresholds | Blocking rule did not run: Per-layer coverage thresholds enforced | YES | +| TPY-07 | MUST | test-isolation | Blocking rule did not run: Unit tests do not execute IO | YES | +| PROT-01 | MUST | internal-communication | Blocking rule did not run: Internal service-to-service uses gRPC | YES | +| PROT-02 | MUST | external-communication | Blocking rule did not run: Public and external APIs use REST | YES | +| PROT-04 | MUST | graphql-isolation | Blocking rule did not run: GraphQL resolvers never in domain layer | YES | +| PROT-05 | MUST | protobuf-centralization | Blocking rule did not run: Proto files centralized in Contracts library | YES | +| PROT-07 | MUST | contract-versioning | Blocking rule did not run: Breaking changes require version bump | YES | +| RUNT-01 | MUST | runtime-selection | Blocking rule did not run: Runtime selected by workload profile only | YES | +| RUNT-02 | MUST | web-apis | Blocking rule did not run: Web APIs and BFF use Node.js/TypeScript | YES | +| RUNT-03 | MUST | compute-workloads | Blocking rule did not run: High compute and batch use .NET (C#) | YES | +| RUNT-04 | MUST | mobile-workloads | Blocking rule did not run: Mobile with hardware access uses Android/Kotlin | YES | +| RUNT-05 | MUST | runtime-coupling | Blocking rule did not run: Direct runtime dependency forbidden | YES | +| RUNT-06 | MUST | sync-interop | Blocking rule did not run: Synchronous inter-op uses gRPC | YES | +| RUNT-07 | SHOULD | async-interop | MUST rule not evaluated: Asynchronous inter-op uses message broker | no | +| RUNT-08 | MUST | contract-registry | Blocking rule did not run: Contracts centrally stored and versioned | YES | +| GIT-01 | MUST | branch-naming | Blocking rule did not run: Branch names follow pattern: type/ticket-id-description | YES | +| GIT-02 | MUST | branch-naming | Blocking rule did not run: Protected branches enforce direct push prohibition | YES | +| GIT-03 | MUST | code-review | Blocking rule did not run: PR requires minimum 1 approved review | YES | +| GIT-04 | MUST | release-tagging | Blocking rule did not run: Release tags follow semver format | YES | +| GIT-05 | SHOULD | merge-policy | MUST rule not evaluated: Feature branches merge via squash or rebase | no | +| GIT-06 | MUST | hotfix-flow | Blocking rule did not run: Hotfixes follow expedited merge path | YES | +| GIT-07 | SHOULD | branch-lifetime | MUST rule not evaluated: Stale branches must be deleted after merge | no | +| GIT-09 | MUST | promotion-policy | Blocking rule did not run: Environment promotion follows develop to qa to uat to main | YES | +| GIT-10 | MUST | code-review | Blocking rule did not run: Higher environments require stronger approval | YES | +| DOD-01 | MUST | code | Blocking rule did not run: Code implemented and reviewed | YES | +| DOD-02 | MUST | testing | Blocking rule did not run: Unit tests meet coverage threshold | YES | +| DOD-06 | MUST | security | Blocking rule did not run: Security gates passed | YES | +| DOD-07 | SHOULD | architecture | MUST rule not evaluated: ADR created if architectural decision made | no | +| DOD-08 | MUST | integration | Blocking rule did not run: Integration tests pass | YES | +| DOD-09 | MUST | lint | Blocking rule did not run: Linting and formatting passed | YES | +| DOD-10 | MUST | ci | Blocking rule did not run: CI pipeline green on target branch | YES | +| EM-S-03 | MUST | SOLID | Blocking rule did not run: Liskov Substitution: subtype substitutable for base | YES | +| EM-S-05 | MUST | SOLID | Blocking rule did not run: Dependency Inversion: depend on abstractions | YES | +| EM-K-01 | MUST | KISS | Blocking rule did not run: Keep It Simple, Stupid | YES | +| EM-Y-01 | SHOULD | YAGNI | MUST rule not evaluated: You Aren't Gonna Need It | no | +| TAX-07 | MUST | adr-naming | Blocking rule did not run: ADR files named with zero-padded ID | YES | +| TAX-08 | MUST | adr-naming | Blocking rule did not run: Bilingual ADR files use .es.md suffix | YES | +| ABAC-01 | MUST | access-control | Blocking rule did not run: Tool Access Requires Authorization | YES | +| ABAC-02 | MUST | access-control | Blocking rule did not run: User Context Must Carry Roles | YES | +| ABAC-03 | MUST | access-control | Blocking rule did not run: Tool Must Be Classified in the Tool Registry | YES | +| DORA-01 | SHOULD | metrics | MUST rule not evaluated: Deployment Frequency | no | +| DORA-02 | SHOULD | metrics | MUST rule not evaluated: Lead Time for Changes | no | +| DORA-03 | SHOULD | metrics | MUST rule not evaluated: Change Failure Rate | no | +| DORA-04 | SHOULD | metrics | MUST rule not evaluated: Time to Restore | no | +| SPACE-01 | MUST | metrics | Blocking rule did not run: Reliability (Observability) | YES | +| DRIFT-01 | SHOULD | governance | MUST rule not evaluated: Architecture Drift Index | no | +| INH-06 | MUST | inheritance | Mandatory Architecture Tracker | no | +| KI-R01 | MUST | general | Blocking rule did not run: Provenance and rights are mandatory | YES | +| KI-R02 | MUST | general | Blocking rule did not run: Winston owns review | YES | +| KI-R03 | MUST | general | Blocking rule did not run: Promotion requires executable evidence | YES | +| KI-R04 | MUST | general | Blocking rule did not run: Topology contract completeness | YES | +| KI-R05 | MUST | general | Blocking rule did not run: Source registry linkage | YES | +| KI-R06 | MUST | general | Blocking rule did not run: Promotion state machine | YES | +| KI-R07 | MUST | general | Blocking rule did not run: Promotion evidence and disposition | YES | +| SVC-02 | SHOULD | general | MUST rule not evaluated: Satellite name must be unique across all Evolith satellites | no | +| SVC-05 | SHOULD | general | MUST rule not evaluated: Core version referenced must exist in Evolith Core registry | no | +| SVC-06 | SHOULD | general | MUST rule not evaluated: Workspace integrity: declared projects and discovered manifests must correspond one-to-one | no | +| MCP-01 | MUST | protocol | Blocking rule did not run: Initialize Request Must Return Capabilities | YES | +| MCP-02 | MUST | tools | Blocking rule did not run: Tools List Must Be Complete and Stable | YES | +| MCP-03 | MUST | resources | Blocking rule did not run: Resources Must Preserve Core Traceability | YES | +| MCP-04 | MUST | security | Blocking rule did not run: HTTP Transport Requires Explicit Authentication Mode | YES | +| OBS-EVD-01 | MUST | tracing | Blocking rule did not run: Production Paths Emit Trace Context | YES | +| OBS-EVD-02 | MUST | logging | Blocking rule did not run: Structured Logs Carry Request Context | YES | +| OBS-EVD-03 | MUST | metrics | Blocking rule did not run: Service Health Metrics Are Reported | YES | +| QT-01 | MUST | testing | Blocking rule did not run: Code Coverage | YES | +| QT-02 | MUST | code-quality | Blocking rule did not run: Cyclomatic Complexity | YES | +| QT-03 | MUST | security | Blocking rule did not run: Security Vulnerabilities | YES | +| QT-04 | MUST | code-quality | Blocking rule did not run: Technical Debt Ratio | YES | +| QT-07 | MUST | operations | Blocking rule did not run: Observability Evidence | YES | +| QT-08 | MUST | contract | Blocking rule did not run: API Contract Compatibility | YES | +| SEC-INJ-01 | MUST | security | Blocking rule did not run: No shell exec with user input | YES | +| SEC-INJ-02 | MUST | security | Blocking rule did not run: Parameter allowlists for scaffold tools | YES | +| SEC-PATH-01 | MUST | security | Blocking rule did not run: Path input sanitization | YES | +| SEC-PATH-02 | MUST | security | Blocking rule did not run: Base directory containment | YES | +| SEC-TIMING-01 | MUST | security | Blocking rule did not run: Constant-time credential comparison | YES | +| SEC-TIMING-02 | MUST | security | Blocking rule did not run: No early rejection on credential length | YES | +| SSDF-PO.3.1 | SHOULD | ssdf-toolchain | PO.3.1 — the toolchain is specified as code, not as recollection | no | +| SSDF-PW.4.1 | MUST | ssdf-third-party | PW.4.1 — third-party components resolve to pinned versions in CI | no | +| SSDF-PW.4.4 | MUST | ssdf-third-party | PW.4.4 — components are re-verified over their life cycle, not once at adoption | no | +| SSDF-PW.7.2 | MUST | ssdf-review | PW.7.2 — code is analysed by both a code scanner and a secret scanner | no | +| SSDF-PS.3.2 | MUST | ssdf-provenance | PS.3.2 — an SBOM that is generated but never published satisfies nothing | no | +| SSDF-RV.1.2 | MUST | ssdf-vulnerability | RV.1.2 — the code scanner sees the whole change, not a filtered slice | no | +| SSDF-RV.1.3 | MUST | ssdf-vulnerability | RV.1.3 — there is a disclosure policy that names how to report | no | +| HXA-06 | SHOULD | aop-isolation | MUST rule not evaluated: AOP implemented exclusively in Infrastructure layer | no | +| HXA-07 | SHOULD | testing | MUST rule not evaluated: Core domain tests run without framework bootstrap | no | +| ISO5055-SEC | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Security | no | +| ISO5055-REL | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Reliability | no | +| ISO5055-PERF | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Performance Efficiency | no | +| ISO5055-MAINT | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Maintainability | no | +| GOV-RULE-NON-EXECUTABLE | COULD | governance | 16 corpus rules are not executable by any engine | no | +| GOV-RULE-NOT-APPLICABLE | COULD | governance | 253 corpus rules do not apply to this repository | no | +**Selection:** {"source":"core-default","requested":[],"matched":[],"unmatched":[],"rulesSelected":412,"corpusTotal":412} +**Core Ref:** {"version":"1.0.0","path":"../evolith"} +**Timestamp:** 2026-08-21T16:05:17.202Z +└ ❌ Validation failed. See the errors above. +``` + +## Qué de todo esto es un defecto + +- **La brecha de cobertura entre motores de arriba** es aceptada por diseño: `68-validate-engine-verdict-parity.mjs` exige que los dos motores coincidan sobre hechos, no sobre cobertura. Lo que *no* se acepta es que el comando por defecto nunca diga qué motor corrió ni qué pudo decidir: [#628](https://github.com/beyondnetcode/evolith_arch32/issues/628). +- **Dos reglas de infraestructura no están en ningún denominador.** `INFRA-001` e + `INFRA-OPA-001` no aparecen en ninguna salida. El cargador rechaza tres ficheros + de reglas que viajan dentro del tarball, y desde 1.3.2 ya no lo dice por stderr + — el aviso que lo divulgaba ha desaparecido, así que la omisión es ahora + silenciosa ([#575](https://github.com/beyondnetcode/evolith_arch32/issues/575)). +- **Una primera ejecución sobre un repositorio en fase 0 reporta hallazgos + bloqueantes.** Eso es una línea base, no un aprobado: varias reglas siguen + asumiendo un layout de repositorio más completo. Llevar el default a cero se + sigue como GT-571 en el + [tablero de gaps](../../reference/core/control-center/gaps/gap-tracking.es.md). + +Todo lo demás de arriba es comportamiento por diseño. diff --git a/docs/evidence/first-run-capture.md b/docs/evidence/first-run-capture.md new file mode 100644 index 000000000..882bfaeb3 --- /dev/null +++ b/docs/evidence/first-run-capture.md @@ -0,0 +1,295 @@ +# First-run capture + +The README front page quotes a handful of numbers from one run of the published +CLI against a freshly initialized satellite. This file is that run, in full, so +the counters on the front page can be checked rather than believed. + +## Conditions + +| | | +|---|---| +| **Date** | 2026-08-21 | +| **Package** | `@beyondnet/evolith-cli@1.3.2`, resolved by `npx -y` from the public registry | +| **Corpus in the tarball** | 177 packs · 412 rules · 188 that can fail a run (`evolith rulesets`) | +| **Corpus in this tree** | 182 ruleset files · 415 rules — the tree is ahead of the published package | +| **Repository under test** | an empty directory, then `evolith init --name my-sat --yes` and nothing else | +| **Exit code** | `2` — the gate blocked | + +Reproduce it: + +```bash +mkdir my-sat && cd my-sat +npx -y @beyondnet/evolith-cli@1.3.2 init --name my-sat --yes +npx -y @beyondnet/evolith-cli@1.3.2 validate --engine opa +echo $? +``` + +## The two denominators + +Two different totals appear in the output and they measure different things. A +report that blurred them would be the exact defect this project exists to stop. + +- **412** is the corpus the installed CLI carries. +- **159** is what this satellite's run selected from it. The `GOV-RULE-NOT-APPLICABLE` + row states the remainder in words: 253 corpus rules do not apply to this + repository, and `253 + 159 = 412`. +- Of those 159, **133 were evaluated** and **26 were skipped** — the engine could + not decide them. +- The run reports **72 issues, 37 of them blocking**. **Nine of the 37 are skipped + rules**, not failed ones: they carry the prefix `Blocking rule did not run:`. + A blocking rule that ends undecided fails the run, because an undecided rule is + not a passing one. + +## The run, unedited + +Terminal control sequences and the progress spinner are stripped; nothing else is +removed, reordered or reworded. `stderr` was empty. + +``` +**Status:** failed +**Rules Checked:** 133 +**Rules Skipped:** 26 +**Rules Errored:** 0 +**Rules Total:** 159 + +### Issues +| Rule Id | Severity | Category | Title | Blocking | +| --- | --- | --- | --- | --- | +| ACL-01 | MUST | anti-corruption | Schema Validation Before Ingestion | YES | +| ACL-02 | MUST | anti-corruption | Transformation Traceability | YES | +| ACL-04 | MUST | anti-corruption | ACL Version Synchronization with Core | YES | +| HXA-03 | MUST | layer-structure | Infrastructure (Adapters) implements Core ports | YES | +| CICD-01 | MUST | security-scan | CodeQL Static Analysis runs on every PR | YES | +| CICD-02 | MUST | dependency-scan | Dependency vulnerability scan blocks merge | YES | +| CICD-03 | MUST | secret-detection | Secret detection enabled on repository | YES | +| CICD-04 | MUST | pipeline-structure | All quality gates execute before merge | YES | +| MTN-01 | MUST | filtering-layer | Application-layer tenant filtering is primary | YES | +| MTN-02 | MUST | filtering-layer | Database-native tenant enforcement is secondary | YES | +| MTN-03 | MUST | context-propagation | Tenant context propagated through all layers | YES | +| MTN-06 | MUST | audit-trail | Tenant-scoped audit trail maintained | no | +| MTN-07 | MUST | data-migration | Tenant migration path defined for schema changes | YES | +| MTN-08 | MUST | external-api | External APIs validate tenant context on every request | YES | +| TPY-03 | MUST | integration-testing | Integration tests use ephemeral containers | no | +| TPY-04 | MUST | e2e-testing | E2E tests cover full HTTP routes | no | +| PROT-05 | MUST | protobuf-centralization | Proto files centralized in Contracts library | YES | +| RUNT-01 | MUST | runtime-selection | Runtime selected by workload profile only | YES | +| RUNT-08 | MUST | contract-registry | Contracts centrally stored and versioned | YES | +| GIT-03 | MUST | code-review | PR requires minimum 1 approved review | YES | +| GIT-10 | MUST | code-review | Higher environments require stronger approval | YES | +| DORA-01 | MUST | metrics | Deployment Frequency | no | +| DORA-02 | MUST | metrics | Lead Time for Changes | no | +| DORA-03 | MUST | metrics | Change Failure Rate | no | +| DORA-04 | MUST | metrics | Time to Restore | no | +| SPACE-01 | MUST | metrics | Reliability (Observability) | YES | +| SPACE-02 | SHOULD | metrics | Culture (Team Health) | no | +| SPACE-03 | SHOULD | metrics | Execution (Throughput) | no | +| SPACE-04 | SHOULD | metrics | Communication (Visibility) | no | +| SPACE-05 | MUST | metrics | Sponsorship (Leadership Alignment) | no | +| INH-02 | MUST | inheritance | Version Pinning | no | +| INH-04 | MUST | inheritance | Satellite Extension via Local ADRs | no | +| INH-06 | MUST | inheritance | Mandatory Architecture Tracker | no | +| KI-R02 | MUST | general | Winston owns review | YES | +| KI-R04 | MUST | general | Topology contract completeness | YES | +| SVC-01 | MUST | general | Each satellite project must have exactly one evolith.yaml at its project root | no | +| SVC-02 | MUST | general | Satellite name must be unique across all Evolith satellites | no | +| SVC-05 | MUST | general | Core version referenced must exist in Evolith Core registry | no | +| MCP-01 | MUST | protocol | Initialize Request Must Return Capabilities | YES | +| MCP-02 | MUST | tools | Tools List Must Be Complete and Stable | YES | +| MCP-03 | MUST | resources | Resources Must Preserve Core Traceability | YES | +| MCP-04 | MUST | security | HTTP Transport Requires Explicit Authentication Mode | YES | +| MCP-05 | SHOULD | observability | MCP Calls Should Emit Metrics | no | +| OBS-EVD-01 | MUST | tracing | Production Paths Emit Trace Context | YES | +| OBS-EVD-02 | MUST | logging | Structured Logs Carry Request Context | YES | +| OBS-EVD-03 | MUST | metrics | Service Health Metrics Are Reported | YES | +| OBS-EVD-04 | SHOULD | dashboards | Gate Evidence References Dashboard | no | +| QT-05 | MUST | testing | Blocking rule did not run: Testing Pyramid Distribution | YES | +| SEC-INJ-01 | MUST | security | Blocking rule did not run: No shell exec with user input | YES | +| SEC-INJ-02 | MUST | security | Blocking rule did not run: Parameter allowlists for scaffold tools | YES | +| SEC-PATH-01 | MUST | security | Blocking rule did not run: Path input sanitization | YES | +| SEC-PATH-02 | MUST | security | Blocking rule did not run: Base directory containment | YES | +| SEC-RL-01 | MUST | security | Blocking rule did not run: Rate limiting on HTTP endpoints | YES | +| SEC-RL-02 | MUST | security | Blocking rule did not run: Request body size limits | YES | +| SEC-TIMING-01 | MUST | security | Blocking rule did not run: Constant-time credential comparison | YES | +| SEC-TIMING-02 | MUST | security | Blocking rule did not run: No early rejection on credential length | YES | +| SLSA-PROV-L1 | SHOULD | slsa-build | MUST rule not evaluated: Build L1 — EVERY publishing path generates provenance, not just the main one | no | +| SLSA-BUILD-L1 | SHOULD | slsa-build | MUST rule not evaluated: Build L1 — the artifact is built by the run whose provenance describes it | no | +| SLSA-AUTH-L2 | SHOULD | slsa-build | MUST rule not evaluated: Build L2 — the PUBLISHING job can mint the identity that signs the provenance | no | +| SLSA-HOSTED-L2 | SHOULD | slsa-build | MUST rule not evaluated: Build L2 — nothing offers a way to publish from a workstation | no | +| SSDF-PW.4.1 | SHOULD | ssdf-third-party | MUST rule not evaluated: PW.4.1 — third-party components resolve to pinned versions in CI | no | +| SSDF-PW.4.4 | SHOULD | ssdf-third-party | MUST rule not evaluated: PW.4.4 — components are re-verified over their life cycle, not once at adoption | no | +| SSDF-PW.7.2 | SHOULD | ssdf-review | MUST rule not evaluated: PW.7.2 — code is analysed by both a code scanner and a secret scanner | no | +| SSDF-PS.3.2 | SHOULD | ssdf-provenance | MUST rule not evaluated: PS.3.2 — an SBOM that is generated but never published satisfies nothing | no | +| SSDF-RV.1.2 | SHOULD | ssdf-vulnerability | MUST rule not evaluated: RV.1.2 — the code scanner sees the whole change, not a filtered slice | no | +| SSDF-RV.1.3 | SHOULD | ssdf-vulnerability | MUST rule not evaluated: RV.1.3 — there is a disclosure policy that names how to report | no | +| ISO5055-SEC | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Security | no | +| ISO5055-REL | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Reliability | no | +| ISO5055-PERF | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Performance Efficiency | no | +| ISO5055-MAINT | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Maintainability | no | +| GOV-RULE-NOT-APPLICABLE | COULD | governance | 253 corpus rules do not apply to this repository | no | +**Selection:** {"source":"core-default","requested":[],"matched":[],"unmatched":[],"rulesSelected":412,"corpusTotal":412} +**Core Ref:** {"version":"1.0.0","path":"../evolith"} +**Timestamp:** 2026-08-21T16:05:06.083Z +└ ❌ Validation failed. See the errors above. +``` + +## The same repository, on the default engine + +`--engine opa` evaluates with the compiled Rego bundle. Without the flag the CLI +runs the native TypeScript evaluator, and on the same repository, the same +version and the same corpus it does not cover the same ground: + +| | `validate --engine opa` | `validate` | +|---|---|---| +| Rules checked | 133 | **41** | +| Rules skipped | 26 | **118** | +| Issue rows | 72 | 114 | +| Blocking | 37 | 77 | +| Exit code | 2 | 2 | + +CI holds the two engines to agreement over fixtures. It does not hold them to +equal coverage over a real repository, and today they do not have it. That is why +the front page uses `--engine opa` everywhere. + +``` +**Status:** failed +**Rules Checked:** 41 +**Rules Skipped:** 118 +**Rules Errored:** 0 +**Rules Total:** 159 + +### Issues +| Rule Id | Severity | Category | Title | Blocking | +| --- | --- | --- | --- | --- | +| ACL-02 | MUST | anti-corruption | Blocking rule did not run: Transformation Traceability | YES | +| ACL-03 | MUST | anti-corruption | Blocking rule did not run: Reject Non-Compliant Data | YES | +| HXA-03 | MUST | layer-structure | Blocking rule did not run: Infrastructure (Adapters) implements Core ports | YES | +| CICD-01 | MUST | security-scan | Blocking rule did not run: CodeQL Static Analysis runs on every PR | YES | +| CICD-02 | MUST | dependency-scan | Blocking rule did not run: Dependency vulnerability scan blocks merge | YES | +| CICD-03 | MUST | secret-detection | Blocking rule did not run: Secret detection enabled on repository | YES | +| CICD-04 | MUST | pipeline-structure | Blocking rule did not run: All quality gates execute before merge | YES | +| CICD-05 | SHOULD | documentation | MUST rule not evaluated: Security findings documented with justification | no | +| CICD-06 | SHOULD | sla-compliance | MUST rule not evaluated: Critical findings resolved within 24 hours | no | +| CICD-07 | SHOULD | sla-compliance | MUST rule not evaluated: High findings resolved within 72 hours | no | +| MTN-01 | MUST | filtering-layer | Blocking rule did not run: Application-layer tenant filtering is primary | YES | +| MTN-02 | MUST | filtering-layer | Blocking rule did not run: Database-native tenant enforcement is secondary | YES | +| MTN-03 | MUST | context-propagation | Blocking rule did not run: Tenant context propagated through all layers | YES | +| MTN-04 | MUST | data-isolation | Blocking rule did not run: Cross-tenant data access prohibited | YES | +| MTN-06 | SHOULD | audit-trail | MUST rule not evaluated: Tenant-scoped audit trail maintained | no | +| MTN-07 | MUST | data-migration | Blocking rule did not run: Tenant migration path defined for schema changes | YES | +| MTN-08 | MUST | external-api | Blocking rule did not run: External APIs validate tenant context on every request | YES | +| TPY-01 | SHOULD | test-layer-distribution | MUST rule not evaluated: Test distribution follows 70/20/10 pyramid | no | +| TPY-02 | MUST | unit-testing | Blocking rule did not run: Unit tests dominate total test volume | YES | +| TPY-03 | SHOULD | integration-testing | MUST rule not evaluated: Integration tests use ephemeral containers | no | +| TPY-04 | SHOULD | e2e-testing | MUST rule not evaluated: E2E tests cover full HTTP routes | no | +| TPY-05 | MUST | coverage-threshold | Blocking rule did not run: Business logic coverage >= 80% | YES | +| TPY-06 | MUST | per-layer-thresholds | Blocking rule did not run: Per-layer coverage thresholds enforced | YES | +| TPY-07 | MUST | test-isolation | Blocking rule did not run: Unit tests do not execute IO | YES | +| PROT-01 | MUST | internal-communication | Blocking rule did not run: Internal service-to-service uses gRPC | YES | +| PROT-02 | MUST | external-communication | Blocking rule did not run: Public and external APIs use REST | YES | +| PROT-04 | MUST | graphql-isolation | Blocking rule did not run: GraphQL resolvers never in domain layer | YES | +| PROT-05 | MUST | protobuf-centralization | Blocking rule did not run: Proto files centralized in Contracts library | YES | +| PROT-07 | MUST | contract-versioning | Blocking rule did not run: Breaking changes require version bump | YES | +| RUNT-01 | MUST | runtime-selection | Blocking rule did not run: Runtime selected by workload profile only | YES | +| RUNT-02 | MUST | web-apis | Blocking rule did not run: Web APIs and BFF use Node.js/TypeScript | YES | +| RUNT-03 | MUST | compute-workloads | Blocking rule did not run: High compute and batch use .NET (C#) | YES | +| RUNT-04 | MUST | mobile-workloads | Blocking rule did not run: Mobile with hardware access uses Android/Kotlin | YES | +| RUNT-05 | MUST | runtime-coupling | Blocking rule did not run: Direct runtime dependency forbidden | YES | +| RUNT-06 | MUST | sync-interop | Blocking rule did not run: Synchronous inter-op uses gRPC | YES | +| RUNT-07 | SHOULD | async-interop | MUST rule not evaluated: Asynchronous inter-op uses message broker | no | +| RUNT-08 | MUST | contract-registry | Blocking rule did not run: Contracts centrally stored and versioned | YES | +| GIT-01 | MUST | branch-naming | Blocking rule did not run: Branch names follow pattern: type/ticket-id-description | YES | +| GIT-02 | MUST | branch-naming | Blocking rule did not run: Protected branches enforce direct push prohibition | YES | +| GIT-03 | MUST | code-review | Blocking rule did not run: PR requires minimum 1 approved review | YES | +| GIT-04 | MUST | release-tagging | Blocking rule did not run: Release tags follow semver format | YES | +| GIT-05 | SHOULD | merge-policy | MUST rule not evaluated: Feature branches merge via squash or rebase | no | +| GIT-06 | MUST | hotfix-flow | Blocking rule did not run: Hotfixes follow expedited merge path | YES | +| GIT-07 | SHOULD | branch-lifetime | MUST rule not evaluated: Stale branches must be deleted after merge | no | +| GIT-09 | MUST | promotion-policy | Blocking rule did not run: Environment promotion follows develop to qa to uat to main | YES | +| GIT-10 | MUST | code-review | Blocking rule did not run: Higher environments require stronger approval | YES | +| DOD-01 | MUST | code | Blocking rule did not run: Code implemented and reviewed | YES | +| DOD-02 | MUST | testing | Blocking rule did not run: Unit tests meet coverage threshold | YES | +| DOD-06 | MUST | security | Blocking rule did not run: Security gates passed | YES | +| DOD-07 | SHOULD | architecture | MUST rule not evaluated: ADR created if architectural decision made | no | +| DOD-08 | MUST | integration | Blocking rule did not run: Integration tests pass | YES | +| DOD-09 | MUST | lint | Blocking rule did not run: Linting and formatting passed | YES | +| DOD-10 | MUST | ci | Blocking rule did not run: CI pipeline green on target branch | YES | +| EM-S-03 | MUST | SOLID | Blocking rule did not run: Liskov Substitution: subtype substitutable for base | YES | +| EM-S-05 | MUST | SOLID | Blocking rule did not run: Dependency Inversion: depend on abstractions | YES | +| EM-K-01 | MUST | KISS | Blocking rule did not run: Keep It Simple, Stupid | YES | +| EM-Y-01 | SHOULD | YAGNI | MUST rule not evaluated: You Aren't Gonna Need It | no | +| TAX-07 | MUST | adr-naming | Blocking rule did not run: ADR files named with zero-padded ID | YES | +| TAX-08 | MUST | adr-naming | Blocking rule did not run: Bilingual ADR files use .es.md suffix | YES | +| ABAC-01 | MUST | access-control | Blocking rule did not run: Tool Access Requires Authorization | YES | +| ABAC-02 | MUST | access-control | Blocking rule did not run: User Context Must Carry Roles | YES | +| ABAC-03 | MUST | access-control | Blocking rule did not run: Tool Must Be Classified in the Tool Registry | YES | +| DORA-01 | SHOULD | metrics | MUST rule not evaluated: Deployment Frequency | no | +| DORA-02 | SHOULD | metrics | MUST rule not evaluated: Lead Time for Changes | no | +| DORA-03 | SHOULD | metrics | MUST rule not evaluated: Change Failure Rate | no | +| DORA-04 | SHOULD | metrics | MUST rule not evaluated: Time to Restore | no | +| SPACE-01 | MUST | metrics | Blocking rule did not run: Reliability (Observability) | YES | +| DRIFT-01 | SHOULD | governance | MUST rule not evaluated: Architecture Drift Index | no | +| INH-06 | MUST | inheritance | Mandatory Architecture Tracker | no | +| KI-R01 | MUST | general | Blocking rule did not run: Provenance and rights are mandatory | YES | +| KI-R02 | MUST | general | Blocking rule did not run: Winston owns review | YES | +| KI-R03 | MUST | general | Blocking rule did not run: Promotion requires executable evidence | YES | +| KI-R04 | MUST | general | Blocking rule did not run: Topology contract completeness | YES | +| KI-R05 | MUST | general | Blocking rule did not run: Source registry linkage | YES | +| KI-R06 | MUST | general | Blocking rule did not run: Promotion state machine | YES | +| KI-R07 | MUST | general | Blocking rule did not run: Promotion evidence and disposition | YES | +| SVC-02 | SHOULD | general | MUST rule not evaluated: Satellite name must be unique across all Evolith satellites | no | +| SVC-05 | SHOULD | general | MUST rule not evaluated: Core version referenced must exist in Evolith Core registry | no | +| SVC-06 | SHOULD | general | MUST rule not evaluated: Workspace integrity: declared projects and discovered manifests must correspond one-to-one | no | +| MCP-01 | MUST | protocol | Blocking rule did not run: Initialize Request Must Return Capabilities | YES | +| MCP-02 | MUST | tools | Blocking rule did not run: Tools List Must Be Complete and Stable | YES | +| MCP-03 | MUST | resources | Blocking rule did not run: Resources Must Preserve Core Traceability | YES | +| MCP-04 | MUST | security | Blocking rule did not run: HTTP Transport Requires Explicit Authentication Mode | YES | +| OBS-EVD-01 | MUST | tracing | Blocking rule did not run: Production Paths Emit Trace Context | YES | +| OBS-EVD-02 | MUST | logging | Blocking rule did not run: Structured Logs Carry Request Context | YES | +| OBS-EVD-03 | MUST | metrics | Blocking rule did not run: Service Health Metrics Are Reported | YES | +| QT-01 | MUST | testing | Blocking rule did not run: Code Coverage | YES | +| QT-02 | MUST | code-quality | Blocking rule did not run: Cyclomatic Complexity | YES | +| QT-03 | MUST | security | Blocking rule did not run: Security Vulnerabilities | YES | +| QT-04 | MUST | code-quality | Blocking rule did not run: Technical Debt Ratio | YES | +| QT-07 | MUST | operations | Blocking rule did not run: Observability Evidence | YES | +| QT-08 | MUST | contract | Blocking rule did not run: API Contract Compatibility | YES | +| SEC-INJ-01 | MUST | security | Blocking rule did not run: No shell exec with user input | YES | +| SEC-INJ-02 | MUST | security | Blocking rule did not run: Parameter allowlists for scaffold tools | YES | +| SEC-PATH-01 | MUST | security | Blocking rule did not run: Path input sanitization | YES | +| SEC-PATH-02 | MUST | security | Blocking rule did not run: Base directory containment | YES | +| SEC-TIMING-01 | MUST | security | Blocking rule did not run: Constant-time credential comparison | YES | +| SEC-TIMING-02 | MUST | security | Blocking rule did not run: No early rejection on credential length | YES | +| SSDF-PO.3.1 | SHOULD | ssdf-toolchain | PO.3.1 — the toolchain is specified as code, not as recollection | no | +| SSDF-PW.4.1 | MUST | ssdf-third-party | PW.4.1 — third-party components resolve to pinned versions in CI | no | +| SSDF-PW.4.4 | MUST | ssdf-third-party | PW.4.4 — components are re-verified over their life cycle, not once at adoption | no | +| SSDF-PW.7.2 | MUST | ssdf-review | PW.7.2 — code is analysed by both a code scanner and a secret scanner | no | +| SSDF-PS.3.2 | MUST | ssdf-provenance | PS.3.2 — an SBOM that is generated but never published satisfies nothing | no | +| SSDF-RV.1.2 | MUST | ssdf-vulnerability | RV.1.2 — the code scanner sees the whole change, not a filtered slice | no | +| SSDF-RV.1.3 | MUST | ssdf-vulnerability | RV.1.3 — there is a disclosure policy that names how to report | no | +| HXA-06 | SHOULD | aop-isolation | MUST rule not evaluated: AOP implemented exclusively in Infrastructure layer | no | +| HXA-07 | SHOULD | testing | MUST rule not evaluated: Core domain tests run without framework bootstrap | no | +| ISO5055-SEC | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Security | no | +| ISO5055-REL | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Reliability | no | +| ISO5055-PERF | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Performance Efficiency | no | +| ISO5055-MAINT | SHOULD | iso-5055 | MUST rule not evaluated: ISO/IEC 5055 — Maintainability | no | +| GOV-RULE-NON-EXECUTABLE | COULD | governance | 16 corpus rules are not executable by any engine | no | +| GOV-RULE-NOT-APPLICABLE | COULD | governance | 253 corpus rules do not apply to this repository | no | +**Selection:** {"source":"core-default","requested":[],"matched":[],"unmatched":[],"rulesSelected":412,"corpusTotal":412} +**Core Ref:** {"version":"1.0.0","path":"../evolith"} +**Timestamp:** 2026-08-21T16:05:17.202Z +└ ❌ Validation failed. See the errors above. +``` + +## What in here is a defect + +- **The engine coverage gap above** is accepted by design — `68-validate-engine-verdict-parity.mjs` holds the two engines to agreement about facts, not about coverage. What is *not* accepted is that the default command never says which engine ran or what it could decide: [#628](https://github.com/beyondnetcode/evolith_arch32/issues/628). +- **Two infrastructure rules are in no denominator.** `INFRA-001` and + `INFRA-OPA-001` appear in no output. The loader rejects three ruleset files that + ship inside the tarball, and as of 1.3.2 it no longer says so on stderr — the + warning that used to disclose it is gone, so the omission is now silent + ([#575](https://github.com/beyondnetcode/evolith_arch32/issues/575)). +- **A first run on a phase-0 repository reports blocking findings.** That is a + baseline, not a pass, and several rules still assume a fuller repository layout. + Bringing the default to zero is tracked as GT-571 in the + [gap board](../../reference/core/control-center/gaps/gap-tracking.md). + +Everything else above is behaviour by design. diff --git a/product/suite/vision/evolith-product-vision-master.es.md b/product/suite/vision/evolith-product-vision-master.es.md index c8c0acdb9..0cfe25d22 100644 --- a/product/suite/vision/evolith-product-vision-master.es.md +++ b/product/suite/vision/evolith-product-vision-master.es.md @@ -162,7 +162,7 @@ flowchart TB subgraph CORE["repo · evolith_arch32 (Evolith Core · Constitución)"] subgraph EXP["Capa de Exposición del Core · ADR-0074"] API["apps/core-api
REST · 11 controllers"] - MCP["mcp-server
MCP · 47 tools · 11 resources"] + MCP["mcp-server
MCP · 52 tools · 12 resources"] CLI["evolith-cli
CLI · 31 commands"] end subgraph RT["Agent Runtime · @beyondnet/evolith-agent-runtime"] @@ -204,7 +204,7 @@ flowchart TB | Interfaz | Consumidor | Propósito | |---|---|---| | **API REST** | UI del Tracker, CI/CD e integraciones empresariales | 11 controllers: evaluación, gates, fases, arquitectura, proyectos, satélites, capabilities, composable-validate, reference, metrics, salud | -| **MCP HTTP/SSE** | LLMs y agentes autónomos | 47 tools, 11 resources, 8 prompts: evaluación, validación, agentes, ADRs, MoSCoW, drift, configuración | +| **MCP HTTP/SSE** | LLMs y agentes autónomos | 52 tools, 12 resources, 8 prompts: evaluación, validación, agentes, ADRs, MoSCoW, drift, configuración | | **CLI** | Roles de ingeniería y producto | 31 comandos: validate, evaluate, gate, drift, scaffold, ADR lifecycle, agents, chat, satellite, sdlc | | **Agent Runtime** | Agentes IA, chatboxes, triggers externos | **10 puertos hexagonales en la ruta caliente de ejecución** (7 obligatorios, 3 opcionales), orquestación gobernada con OPA + HITL. El paquete *declara* 17 puertos y 47 módulos adaptadores, incluidos 6 interaction adapters (CLI Command, CLI Chat, Hermes, MCP, OpenCode, External) — ver la nota siguiente para saber cuáles están conectados y cuáles son especulativos. | | **Webhook / Bus de Eventos** — *no implementado, roadmap* | *(ninguno todavía)* | **Hoy no se entrega ninguna superficie de webhook ni de bus de eventos.** Evolith no expone endpoint de webhook entrante ni emite tráfico saliente de webhooks o eventos. El único código relacionado es `src/packages/infra-providers/src/webhook.adapter.ts`, un adaptador **solo-saliente** sin ninguna superficie conectada. Ver [Ecosistema y Comunicación](../../products/ecosystem-and-communication.es.md). Propagar comandos, evidencias, cambios de estado y resultados de gates de forma reactiva sigue siendo un ítem de roadmap. | diff --git a/product/suite/vision/evolith-product-vision-master.md b/product/suite/vision/evolith-product-vision-master.md index a0076aace..2b0b18747 100644 --- a/product/suite/vision/evolith-product-vision-master.md +++ b/product/suite/vision/evolith-product-vision-master.md @@ -162,7 +162,7 @@ flowchart TB subgraph CORE["repo · evolith_arch32 (Evolith Core · Constitution)"] subgraph EXP["Core API Exposure Layer · ADR-0074"] API["apps/core-api
REST · 11 controllers"] - MCP["mcp-server
MCP · 47 tools · 11 resources"] + MCP["mcp-server
MCP · 52 tools · 12 resources"] CLI["evolith-cli
CLI · 31 commands"] end subgraph RT["Agent Runtime · @beyondnet/evolith-agent-runtime"] @@ -204,7 +204,7 @@ flowchart TB | Interface | Consumer | Purpose | |---|---|---| | **REST API** | Tracker UI, CI/CD, enterprise integrations | 11 controllers: evaluation, gates, phases, architecture, projects, satellites, capabilities, composable-validate, reference, metrics, health | -| **MCP HTTP/SSE** | LLMs and autonomous agents | 47 tools, 11 resources, 8 prompts: evaluation, validation, agents, ADRs, MoSCoW, drift, configuration | +| **MCP HTTP/SSE** | LLMs and autonomous agents | 52 tools, 12 resources, 8 prompts: evaluation, validation, agents, ADRs, MoSCoW, drift, configuration | | **CLI** | Engineers and product roles | 31 commands: validate, evaluate, gate, drift, scaffold, ADR lifecycle, agents, chat, satellite, sdlc | | **Agent Runtime** | AI agents, chatboxes, external triggers | **10 hexagonal ports on the execution hot path** (7 required, 3 optional), governed orchestration with OPA + HITL. The package *declares* 17 ports and 47 adapter modules, including 6 interaction adapters (CLI Command, CLI Chat, Hermes, MCP, OpenCode, External) — see the note below for which of those are wired and which are speculative. | | **Webhook / Event Bus** — *not implemented, roadmap* | *(none yet)* | **No webhook or event-bus surface ships today.** Evolith exposes no inbound webhook endpoint and delivers no outbound webhook or event traffic. The only related code is `src/packages/infra-providers/src/webhook.adapter.ts`, an **outbound-only** adapter with no surface wired to it. See [Ecosystem & Communication](../../products/ecosystem-and-communication.md). Propagating commands, evidence, status changes, and gate outcomes reactively remains a roadmap item. | diff --git a/reference/core/README.es.md b/reference/core/README.es.md index ef3bc0f0a..78b03c675 100644 --- a/reference/core/README.es.md +++ b/reference/core/README.es.md @@ -139,7 +139,28 @@ La visión de la Suite, posicionamiento comercial, roadmaps, UX, APIs de product --- -## 8. Navegación Relacionada +## 8. Conceptos Core + +El vocabulario que el resto de este corpus da por sabido. Cada término enlaza a donde se define por completo. + +| Concepto | Qué es | +|---|---| +| **Fases SDLC** | Las cinco etapas de la idea a producción: Discovery → Design → Construction → QA → Delivery | +| **Compuertas** | Puntos de control automatizados que cierran cada fase antes de que empiece la siguiente | +| **Topologías** | Estilos de arquitectura (monolito modular, microservicios, event-driven, agentic AI, y cuatro más) | +| **ADRs** | Architecture Decision Records — el registro autoritativo de decisiones arquitectónicas | +| **Blueprints** | Plantillas de diseño canónicas para cada topología | +| **Rulesets** | Reglas legibles por máquina aplicadas por la CLI y la Core API | +| **Políticas OPA** | Políticas de Open Policy Agent para controles de gobernanza granulares | +| **Artefactos** | Salidas estructuradas en cada fase: specs, schemas, manifests, contratos | +| **Satélite** | Un repositorio gobernado por este Core, declarado por su propio `evolith.yaml` | +| **Agentes de IA** | Agentes especializados que participan en el SDLC como colaboradores de primer nivel | + +Detalle completo: [Topologías](./architecture/topologies/README.es.md) · [Centro de Gobernanza SDLC](./sdlc/README.es.md) · [Glosario del Ecosistema](./sdlc/glossary/glossary-ecosystem.es.md) + +--- + +## 9. Navegación Relacionada Documentos fuera de Core que completan el panorama (los dominios propios de Core están listados en la sección 3): diff --git a/reference/core/README.md b/reference/core/README.md index a76a9ddac..3725641d3 100644 --- a/reference/core/README.md +++ b/reference/core/README.md @@ -139,7 +139,28 @@ The Suite vision, market positioning, roadmaps, UX, product APIs, and commercial --- -## 8. Related Navigation +## 8. Core Concepts + +The vocabulary the rest of this corpus assumes. Each term links to where it is defined in full. + +| Concept | What it is | +|---|---| +| **SDLC phases** | The five stages from idea to production: Discovery → Design → Construction → QA → Delivery | +| **Gates** | Automated checkpoints that close each phase before the next one starts | +| **Topologies** | Architecture styles (modular monolith, microservices, event-driven, agentic AI, and four more) | +| **ADRs** | Architecture Decision Records — the authoritative log of architectural decisions | +| **Blueprints** | Canonical design templates for each topology | +| **Rulesets** | Machine-readable rules enforced by the CLI and the Core API | +| **OPA policies** | Open Policy Agent policies for fine-grained governance controls | +| **Artifacts** | Structured outputs at each phase: specs, schemas, manifests, contracts | +| **Satellite** | A repository governed by this Core, declared by its own `evolith.yaml` | +| **AI agents** | Specialised agents that take part in the SDLC as first-class collaborators | + +Full detail: [Topologies](./architecture/topologies/README.md) · [SDLC Governance Center](./sdlc/README.md) · [Ecosystem Glossary](./sdlc/glossary/glossary-ecosystem.md) + +--- + +## 9. Related Navigation Documents outside of Core that complete the picture (Core's own domains are listed in Section 3): diff --git a/reference/core/control-center/gaps/gap-reference-catalog.es.md b/reference/core/control-center/gaps/gap-reference-catalog.es.md index 13c836acf..613e3036c 100644 --- a/reference/core/control-center/gaps/gap-reference-catalog.es.md +++ b/reference/core/control-center/gaps/gap-reference-catalog.es.md @@ -3871,7 +3871,7 @@ Serie histórica de gaps registrada en el antiguo `gap-analysis-core.es.md`, pre - **Hecho Cuando:** Una aplicación `apps/agent-sandbox` sea creada con un servidor MCP de prueba conectado al Core API. --- -[Volver al Tablero de Seguimiento](./gap-tracking.es.md) · [Volver al Índice de Visión](../../README.es.md) +[Volver al Tablero de Seguimiento](./gap-tracking.es.md) · [Volver al Centro de Control](../README.es.md) #### GT-55 diff --git a/reference/core/control-center/gaps/gap-reference-catalog.md b/reference/core/control-center/gaps/gap-reference-catalog.md index ccb0c03e5..900ed2a48 100644 --- a/reference/core/control-center/gaps/gap-reference-catalog.md +++ b/reference/core/control-center/gaps/gap-reference-catalog.md @@ -3888,7 +3888,7 @@ Historical gap series tracked in the former `gap-analysis-core.md`, preserved fo - **Done When:** An `apps/agent-sandbox` is created with a dummy MCP server and client connecting to the Evolith Core API. --- -[Back to Tracking Board](./gap-tracking.md) · [Back to Vision Index](../README.md) +[Back to Tracking Board](./gap-tracking.md) · [Back to Control Center](../README.md) #### GT-55 diff --git a/reference/core/control-center/gaps/gap-tracking.es.md b/reference/core/control-center/gaps/gap-tracking.es.md index e59c34afd..654a19272 100644 --- a/reference/core/control-center/gaps/gap-tracking.es.md +++ b/reference/core/control-center/gaps/gap-tracking.es.md @@ -789,4 +789,4 @@ Este tablero es la única fuente de verdad para deuda técnica, gaps, oportunida **Ordenamiento:** una sola tabla, ordenada por estado (pendientes luego completados), luego criticidad (`P0` → `P1` → `P2` → `P3`), luego complejidad (`XS` → `S` → `M` → `L` → `XL`). Los IDs `GT-*` enlazan al [Catálogo de Referencia de Gaps](./gap-reference-catalog.es.md); los IDs `MT-A*` enlazan al [plan de implementación Multi-Topology](../audits/multi-topology-reference-corpus-implementation-plan.es.md). --- -[Volver al Índice de Visión](../../README.es.md) +[Volver al Centro de Control](../README.es.md) diff --git a/reference/core/control-center/gaps/gap-tracking.md b/reference/core/control-center/gaps/gap-tracking.md index 82f94b7ba..004f9be00 100644 --- a/reference/core/control-center/gaps/gap-tracking.md +++ b/reference/core/control-center/gaps/gap-tracking.md @@ -811,4 +811,4 @@ This board is the single source of truth for technical debt, gaps, opportunities **Ordering:** one table, ordered by status (pending then completed), then criticality (`P0` → `P1` → `P2` → `P3`), then complexity (`XS` → `S` → `M` → `L` → `XL`). `GT-*` IDs link to the [Gap Reference Catalog](./gap-reference-catalog.md); `MT-A*` IDs link to the supporting [Multi-Topology implementation plan](../audits/multi-topology-reference-corpus-implementation-plan.md). --- -[Back to Vision Index](../README.md) +[Back to Control Center](../README.md) diff --git a/reference/core/control-center/maturity-reports/inventory-summary.es.md b/reference/core/control-center/maturity-reports/inventory-summary.es.md index a9c3b77dc..ff8daf282 100644 --- a/reference/core/control-center/maturity-reports/inventory-summary.es.md +++ b/reference/core/control-center/maturity-reports/inventory-summary.es.md @@ -7,8 +7,8 @@ Este es el conteo automatizado del inventario de la arquitectura de referencia c | Tipo de Artefacto | Conteo | Ubicación | |---|:---:|---| -| **Architecture Decision Records (ADR)** | 141 | `reference/core/architecture/adrs/` | -| **Rulesets Legibles por Máquina** | 181 | `src/rulesets/` (en 20 categorías) | +| **Architecture Decision Records (ADR)** | 142 | `reference/core/architecture/adrs/` | +| **Rulesets Legibles por Máquina** | 182 | `src/rulesets/` (en 20 categorías) | | **Schemas de Phase-Gates** | 50 | `src/rulesets/schema/` | -*Última Actualización: 2026-08-16* +*Última Actualización: 2026-08-21* diff --git a/reference/core/control-center/maturity-reports/inventory-summary.md b/reference/core/control-center/maturity-reports/inventory-summary.md index ed0c64f4d..afa7d939c 100644 --- a/reference/core/control-center/maturity-reports/inventory-summary.md +++ b/reference/core/control-center/maturity-reports/inventory-summary.md @@ -7,8 +7,8 @@ This is the automated inventory tally of the core reference architecture and gov | Artifact Type | Count | Location | |---|:---:|---| -| **Architecture Decision Records (ADR)** | 141 | `reference/core/architecture/adrs/` | -| **Machine-Readable Rulesets** | 181 | `src/rulesets/` (across 20 categories) | +| **Architecture Decision Records (ADR)** | 142 | `reference/core/architecture/adrs/` | +| **Machine-Readable Rulesets** | 182 | `src/rulesets/` (across 20 categories) | | **Phase-Gate Schemas** | 50 | `src/rulesets/schema/` | -*Last Updated: 2026-08-16* +*Last Updated: 2026-08-21* diff --git a/reference/core/control-center/taxonomy/MASTER_INDEX.es.md b/reference/core/control-center/taxonomy/MASTER_INDEX.es.md index 70d9e2306..e708c1308 100644 --- a/reference/core/control-center/taxonomy/MASTER_INDEX.es.md +++ b/reference/core/control-center/taxonomy/MASTER_INDEX.es.md @@ -1,17 +1,20 @@ # Índice Maestro Global Evolith -Este documento de navegación de nivel repositorio fue movido al hub de navegación: +Esta página es una redirección. El índice maestro canónico es el de la raíz del repositorio: -**[Abrir el Índice Maestro Global Evolith](../../README.es.md)** +**[Abrir el Índice Maestro](../../../../MASTER_INDEX.es.md)** ## Por qué este archivo permanece aquí -Esta página ligera se conserva en la raíz para mantener compatibilidad con enlaces, bookmarks y referencias existentes. +Se conserva para que sigan resolviendo los enlaces, bookmarks y referencias de documentación +antigua. No lleva contenido propio: cualquier cosa que se añadiera aquí sería un segundo índice +compitiendo con el canónico, que es justo el defecto que existe para evitar. ## Navegación relacionada | Necesidad | Ir a | |---|---| -| Portal principal | [README.es.md](../../README.es.md) | -| Índice maestro en inglés | [MASTER_INDEX.md](./MASTER_INDEX.md) | -| Hub de navegación | [Centro de Control](../../README.es.md) | +| Índice maestro canónico | [MASTER_INDEX.es.md](../../../../MASTER_INDEX.es.md) | +| Portal principal | [README.es.md](../../../../README.es.md) | +| Redirección en inglés | [MASTER_INDEX.md](./MASTER_INDEX.md) | +| Hub de navegación | [Centro de Control](../README.es.md) | diff --git a/reference/core/control-center/taxonomy/MASTER_INDEX.md b/reference/core/control-center/taxonomy/MASTER_INDEX.md index b94535b4e..6f595cf43 100644 --- a/reference/core/control-center/taxonomy/MASTER_INDEX.md +++ b/reference/core/control-center/taxonomy/MASTER_INDEX.md @@ -1,17 +1,20 @@ # Evolith Global Master Index -This repository-level navigation document has moved to the navigation hub: +This page is a redirect. The canonical master index is the one at the repository root: -**[Open the Evolith Global Master Index](../README.md)** +**[Open the Master Index](../../../../MASTER_INDEX.md)** ## Why this file remains here -This lightweight page is kept at the root path to preserve existing links, bookmarks, and references from older documentation. +It is kept so that existing links, bookmarks and references from older documentation keep +resolving. It carries no content of its own — anything added here would be a second index +competing with the canonical one, which is the defect it exists to avoid. ## Related navigation | Need | Go to | |---|---| -| Main portal | [README.md](../README.md) | -| Spanish master index | [MASTER_INDEX.es.md](./MASTER_INDEX.es.md) | +| Canonical master index | [MASTER_INDEX.md](../../../../MASTER_INDEX.md) | +| Main portal | [README.md](../../../../README.md) | +| Spanish redirect | [MASTER_INDEX.es.md](./MASTER_INDEX.es.md) | | Navigation hub | [Control Center](../README.md) | diff --git a/reference/core/control-center/taxonomy/repository-taxonomy.es.md b/reference/core/control-center/taxonomy/repository-taxonomy.es.md index 7a2b5ea14..3f2d5775f 100644 --- a/reference/core/control-center/taxonomy/repository-taxonomy.es.md +++ b/reference/core/control-center/taxonomy/repository-taxonomy.es.md @@ -7,36 +7,52 @@ Este documento establece la taxonomia oficial y los limites de autoridad de este ## 1. Estructura Estandar de Directorios ```text -/ (raiz del repositorio) - README.md # Portal publico y navegacion inicial - MASTER_INDEX.md # Ruteo exhaustivo por rol e intencion - .bmad-core/ # Implementacion opcional del metodo spec-driven AI-DD - .claude/ # Configuracion de Claude Code (requiere raiz) - .github/ # Workflows CI y plantillas de colaboracion - .harness/ # Reglas de validacion documental y de agentes - .husky/ # Git hooks (requiere raiz) - .mimocode/ # Configuracion de MiMoCode (requiere raiz) - .obsidian/ # Lente opcional de autoria/navegacion Obsidian - .vscode/ # Configuracion de VS Code (requiere raiz) - sdk/ # Tooling de acceso ejecutable, CLI y MCP - rulesets/ # Reglas arquitectonicas legibles por maquina - topologies/ # Rulesets ejecutables especificos por topologia - reference/ # Corpus de referencia arquitectonica - getting-started/ # Rutas cortas de lectura - architecture/ # Autoridad arquitectonica y guia de implementacion - README.es.md # Hub de arquitectura y orden de lectura - blueprints/ # Baselines, topologia y perfiles de stack - adrs/ # Registros de decision y matriz de decisiones - canonical-patterns/ # Patrones por runtime mapeados a ADRs - topologies/ # Corpus multi-topologia legible por humanos - governance/ # Politicas, SDLC, terminologia y onboarding - knowledge/ # Evidencia aplicada, investigacion y aprendizaje - demo/ # Limite de referencia UMS, registro de migracion y ejemplos - operations/ # Guia operativa y activos de observabilidad - infrastructure/ # Activos de referencia de plataforma e infraestructura - apps/ # Workspaces de aplicaciones (core-api, agent-sandbox) - packages/ # Workspaces de paquetes compartidos (core-domain, mcp-server) - tests/ # Tests de contrato e integracion +/ (raíz del repositorio) + README.md # Portal público y navegación inicial + MASTER_INDEX.md # Enrutamiento exhaustivo por rol e intención + action.yml # La GitHub Action publicada (puerta de PR) + evolith.yaml # La configuración de satélite de este mismo repositorio + .bmad-core/ # Implementación opcional del método spec-driven AI-DD + .claude-plugin/ # Manifiesto del plugin de Claude Code + .github/ # Workflows de CI y plantillas de colaboración + .harness/ # Reglas de validación de documentos y agentes, y los guards de CI + .husky/ # Git hooks (requerido en la raíz) + .mimocode/ # Configuración de MiMoCode (requerido en la raíz) + .obsidian/ # Lente opcional de autoría/navegación de Obsidian + .vscode/ # Configuración de VS Code (requerido en la raíz) + docs/ # Guías para el lector y evidencia publicada + guides/ # Guía rápida y guías por tarea + evidence/ # Ejecuciones capturadas que la portada cita + src/ # Todos los workspaces ejecutables + rulesets/ # Reglas de arquitectura legibles por máquina + topologies/ # Rulesets ejecutables por topología + opa/ # Políticas Rego y el bundle compilado + schema/ # Schemas de phase-gate y de artefactos + sdk/ # CLI y herramientas de acceso ejecutables + packages/ # Workspaces compartidos (core-domain, mcp-server, + # agent-runtime, contracts, infra-providers, + # repo-facts, sdk-client, core) + apps/ # Workspaces de aplicación (core-api, agent-runtime-api) + tests/ # Tests de contrato e integración + reference/ # Corpus de referencia arquitectónica + core/ # La constitución del Core + architecture/ # Autoridad arquitectónica y guía de implementación + adrs/ # Decision records y matriz de decisiones + blueprints/ # Líneas base, topología y perfiles de stack + topologies/ # Corpus de referencia multi-topología legible + foundations/ # Documentación del Agent Runtime y Puertos y Adaptadores + sdlc/ # Fases, compuertas, estándares, glosario y Q&A + foundations/ # Principios, reglas comunes y modelo de herencia + control-center/ # Seguimiento de gaps, madurez, auditorías y taxonomía + interfaces/ # Hub de how-to de CLI, MCP y REST + knowledge/ # Evidencia aplicada, investigación y aprendizaje + governance/ # Propuestas upstream y registro de decisiones + product/ # Corpus de producto + products/ # Evolith CLI, Core API, MCP Services, Tracker + operations/ # SRE, infraestructura y compuertas de calidad + suite/ # Visión y narrativa comercial + research/ # Referencias de demo e investigación aplicada + infra/ # Ficheros de compose y activos de despliegue ``` El repositorio contiene artefactos arquitectonicos, no una aplicacion local de producto. La evidencia ejecutable de producto se mantiene externamente en [UMS](https://github.com/beyondnetcode/ums). diff --git a/reference/core/control-center/taxonomy/repository-taxonomy.md b/reference/core/control-center/taxonomy/repository-taxonomy.md index cd04b2283..01f960a68 100644 --- a/reference/core/control-center/taxonomy/repository-taxonomy.md +++ b/reference/core/control-center/taxonomy/repository-taxonomy.md @@ -10,33 +10,49 @@ This document establishes the official taxonomy and authority limits for this ar / (repository root) README.md # Public portal and initial navigation MASTER_INDEX.md # Exhaustive routing by role and intent + action.yml # The published GitHub Action (PR gate) + evolith.yaml # This repository's own satellite configuration .bmad-core/ # Optional spec-driven AI-DD method implementation - .claude/ # Claude Code configuration (root required) + .claude-plugin/ # Claude Code plugin manifest .github/ # CI workflows and collaboration templates - .harness/ # Document and agent validation rules + .harness/ # Document and agent validation rules, and the CI guards .husky/ # Git hooks (root required) .mimocode/ # MiMoCode configuration (root required) .obsidian/ # Optional Obsidian authoring/navigation lens .vscode/ # VS Code configuration (root required) - sdk/ # CLI, MCP, and executable access tooling - rulesets/ # Machine-readable architecture rules - topologies/ # Executable topology-specific rulesets + docs/ # Reader-facing guides and published evidence + guides/ # Quickstart and task guides + evidence/ # Captured runs the front page quotes + src/ # All executable workspaces + rulesets/ # Machine-readable architecture rules + topologies/ # Executable topology-specific rulesets + opa/ # Rego policies and the compiled bundle + schema/ # Phase-gate and artifact schemas + sdk/ # CLI and executable access tooling + packages/ # Shared workspaces (core-domain, mcp-server, + # agent-runtime, contracts, infra-providers, + # repo-facts, sdk-client, core) + apps/ # Application workspaces (core-api, agent-runtime-api) + tests/ # Contract and integration tests reference/ # Architectural reference corpus - getting-started/ # Short reading paths - architecture/ # Architectural authority and implementation guide - README.md # Architecture hub and reading order - blueprints/ # Baselines, topology, and stack profiles - adrs/ # Decision records and decision matrix - canonical-patterns/ # Patterns by runtime mapped to ADRs - topologies/ # Human-readable multi-topology reference corpus - governance/ # Policies, SDLC, terminology, and onboarding + core/ # The Core constitution + architecture/ # Architectural authority and implementation guide + adrs/ # Decision records and decision matrix + blueprints/ # Baselines, topology, and stack profiles + topologies/ # Human-readable multi-topology reference corpus + foundations/ # Agent Runtime and Ports & Adapters documentation + sdlc/ # Phases, gates, standards, glossary, and Q&A + foundations/ # Principles, common rules, and the inheritance model + control-center/ # Gap tracking, maturity, audits, and taxonomy + interfaces/ # CLI, MCP and REST how-to hub knowledge/ # Applied evidence, research, and learning - demo/ # UMS reference boundary, migration record, and examples - operations/ # Operational guide and observability assets - infrastructure/ # Platform and infrastructure reference assets - apps/ # Application workspaces (core-api, agent-sandbox) - packages/ # Shared package workspaces (core-domain, mcp-server) - tests/ # Contract and integration tests + governance/ # Upstream proposals and decision log + product/ # Product corpus + products/ # Evolith CLI, Core API, MCP Services, Tracker + operations/ # SRE, infrastructure, and quality gates + suite/ # Vision and commercial narrative + research/ # Demo references and applied research + infra/ # Compose files and deployment assets ``` The repository contains architectural artifacts, not a local product application. Product executable evidence is maintained externally in [UMS](https://github.com/beyondnetcode/ums). diff --git a/reference/core/foundations/common-rules/ai-augmented/03-tools-catalog/evolith-mcp-tools.es.md b/reference/core/foundations/common-rules/ai-augmented/03-tools-catalog/evolith-mcp-tools.es.md index 996e720d8..ec0acd856 100644 --- a/reference/core/foundations/common-rules/ai-augmented/03-tools-catalog/evolith-mcp-tools.es.md +++ b/reference/core/foundations/common-rules/ai-augmented/03-tools-catalog/evolith-mcp-tools.es.md @@ -4,7 +4,7 @@ Este documento cataloga todas las herramientas MCP proporcionadas por Evolith CL ## Inventario de Herramientas -> **Tabla obsoleta retirada (GT-445).** Esta página listaba 11 herramientas; siete de ellas (`evolith-agent-handoff`, `evolith-architecture-evaluate`, `evolith-gate-status`, `evolith-moscow-analyze`, `evolith-moscow-export`, `evolith-alias`, `evolith-schema`) **no existen en el código**. La superficie real son **51** herramientas MCP de gobernanza. El inventario autoritativo, derivado de la fuente (`src/packages/mcp-server/src/tools/`), se mantiene en la tabla **Tool Inventory** de la [versión en inglés](./evolith-mcp-tools.md#tool-inventory); no se mantiene aquí una segunda copia traducida porque derivaría de la fuente. Regenerar la tabla en español es un follow-on de GT-445. +> **Tabla obsoleta retirada (GT-445).** Esta página listaba 11 herramientas; siete de ellas (`evolith-agent-handoff`, `evolith-architecture-evaluate`, `evolith-gate-status`, `evolith-moscow-analyze`, `evolith-moscow-export`, `evolith-alias`, `evolith-schema`) **no existen en el código**. La superficie real son **52** herramientas MCP de gobernanza. El inventario autoritativo, derivado de la fuente (`src/packages/mcp-server/src/tools/`), se mantiene en la tabla **Tool Inventory** de la [versión en inglés](./evolith-mcp-tools.md#tool-inventory); no se mantiene aquí una segunda copia traducida porque derivaría de la fuente. Regenerar la tabla en español es un follow-on de GT-445. --- diff --git a/reference/core/foundations/common-rules/ai-augmented/03-tools-catalog/evolith-mcp-tools.md b/reference/core/foundations/common-rules/ai-augmented/03-tools-catalog/evolith-mcp-tools.md index 35df95870..ca1dfe831 100644 --- a/reference/core/foundations/common-rules/ai-augmented/03-tools-catalog/evolith-mcp-tools.md +++ b/reference/core/foundations/common-rules/ai-augmented/03-tools-catalog/evolith-mcp-tools.md @@ -46,6 +46,7 @@ This document catalogs all MCP tools provided by the Evolith CLI for AI agent au | `evolith-moscow-report` | Planning | Generate a markdown report of a MoSCoW analysis | No | | `evolith-moscow-update` | Planning | Update a specific item in a MoSCoW analysis | Yes | | `evolith-moscow-validate` | Planning | Validate a MoSCoW analysis rules (e.g. 60/20/20 split) | No | +| `evolith-ruleset-list` | Ruleset-catalog.tool | List the ruleset packs this Core can evaluate. Returns the canonica… | No | | `evolith-satellite-adopt` | Satellite-adopt.tool | Adopt an existing GitHub repository as an Evolith satellite. Return… | Yes | | `evolith-satellite-create` | Satellite-create.tool | Create a new satellite repository on GitHub and register it with Ev… | Yes | | `evolith-satellite-list` | Satellite-list.tool | List all registered Evolith satellites from the local satellite-reg… | No | @@ -58,13 +59,13 @@ This document catalogs all MCP tools provided by the Evolith CLI for AI agent au | `evolith-sdlc-generate` | Sdlc-generate.tool | Generate a Hexagonal Architecture scaffold from a Mermaid classDiag… | Yes | | `evolith-validate` | Validate.tool | Validate a satellite repository against Evolith rules. Supports end… | No | -> **Derived from source (GT-445).** The inventory above is the complete set of **51** governance MCP tools, reconciled from the canonical registration sources under `src/packages/mcp-server/src/tools/` (name + description) — it is the authoritative surface alongside the generated [Product Surface Inventory](../../../../../../product/products/smart-cli/product-inventory.md) and the live MCP registry. Category is derived from the tool source file; *Mutative* is a verb heuristic. Regenerate when tools change. +> **Derived from source (GT-445).** The inventory above is the complete set of **52** governance MCP tools, reconciled from the canonical registration sources under `src/packages/mcp-server/src/tools/` (name + description) — it is the authoritative surface alongside the generated [Product Surface Inventory](../../../../../../product/products/smart-cli/product-inventory.md) and the live MCP registry. Category is derived from the tool source file; *Mutative* is a verb heuristic. Regenerate when tools change. --- ## Tool Specifications -> **Legacy curated subset — being superseded.** The detailed specs below predate the current 47-tool surface: several document **obsolete tool names that no longer exist** (`evolith-agent-handoff`, `evolith-architecture-evaluate`, `evolith-gate-status`, `evolith-moscow-analyze`, `evolith-moscow-export`, `evolith-alias`, `evolith-schema`). The authoritative, complete list is the **Tool Inventory** table above. Full per-tool spec regeneration from source is a follow-on (GT-445). +> **Legacy curated subset — being superseded.** The detailed specs below predate the current 52-tool surface: several document **obsolete tool names that no longer exist** (`evolith-agent-handoff`, `evolith-architecture-evaluate`, `evolith-gate-status`, `evolith-moscow-analyze`, `evolith-moscow-export`, `evolith-alias`, `evolith-schema`). The authoritative, complete list is the **Tool Inventory** table above. Full per-tool spec regeneration from source is a follow-on (GT-445). ### evolith-agent-handoff diff --git a/reference/core/interfaces/README.es.md b/reference/core/interfaces/README.es.md index b9c6416ed..211bbcf85 100644 --- a/reference/core/interfaces/README.es.md +++ b/reference/core/interfaces/README.es.md @@ -1,6 +1,6 @@ # Evolith Core — How-To de Interfaces -> Navegación bilingüe: [English](./README.md) +> **Navegación Bilingüe:** [English](./README.md) Cómo operar Evolith Core desde sus tres superficies — **CLI** (`evolith …`), **MCP** (tools `evolith-*`) y **REST** (`/api/v1/…`). diff --git a/reference/core/interfaces/README.md b/reference/core/interfaces/README.md index 94db9d183..3c5e40e09 100644 --- a/reference/core/interfaces/README.md +++ b/reference/core/interfaces/README.md @@ -1,5 +1,7 @@ # Evolith Core — Interface How-To +> **Bilingual Navigation:** [Versión en Español](./README.es.md) + How to drive Evolith Core across its three surfaces — **CLI** (`evolith …`), **MCP** (`evolith-*` tools), and **REST** (`/api/v1/…`). diff --git a/reference/core/sdlc/q-and-a.es.md b/reference/core/sdlc/q-and-a.es.md index b2d26c810..6160d9b5e 100644 --- a/reference/core/sdlc/q-and-a.es.md +++ b/reference/core/sdlc/q-and-a.es.md @@ -31,7 +31,7 @@ Piensa en él como una "constitución" para tu software: define las reglas y lue **Respuesta:** 1. **Feedback instantáneo** en decisiones arquitectónicas — ejecuta `evolith validate` y sabe en segundos si tu código cumple. -2. **Sin refactors sorpresa** — el drift se detecta en el gate, no六个月 después. +2. **Sin refactors sorpresa** — el drift se detecta en el gate, no seis meses después. 3. **Gobernanza a prueba de AI** — cuando un agente AI escribe código, Evolith asegura que siga las mismas reglas que un arquitecto senior. **Evidencia:** [Gap Tracking Board](../control-center/gaps/gap-tracking.md), [ADR-0002](../architecture/adrs/nodejs/0002-clean-architecture-nestjs.md) @@ -254,7 +254,15 @@ Los productos reales no caben en una caja. Evolith permite composición libre en
-T04-P04: ¿Por qué empezar con monolito modular? +T04-P04: ¿Qué es la composición de topologías? + +Puedes combinar topologías de dimensiones distintas. Dos topologías hub componen con todo: **Event-Driven** y **Agentic AI**. Ejemplo: `modular-monolith + event-driven` es válido. `modular-monolith + microservices` NO lo es (misma dimensión). + +**Evidencia:** [Schema de Composición](../../../src/rulesets/schema/topology-composition.schema.json) +
+ +
+T04-P05: ¿Por qué empezar con monolito modular? Distribución prematura es el error #1. Empezar simple (F1), extraer cuando justificado (ADR-0045), microservicios solo cuando la madurez operacional lo justifique. @@ -347,6 +355,14 @@ Servicios tan acoplados que no puedes desplegar independientemente. Evolith prev **Evidencia:** [ADR-0015](../architecture/adrs/core/0015-event-driven-architecture-intra-domain.md)
+
+T07-P03: ¿Qué es el "Strangler Fig"? + +Patrón de migración incremental: reemplazar partes del legacy con componentes nuevos sin una reescritura big-bang. En Evolith los módulos están aislados desde el día uno, así que la extracción es incremental. + +**Evidencia:** [Matriz de Madurez de Patrones](../control-center/maturity-reports/maturity-assessment.es.md) +
+ --- From 23417512360db63c8b85070cb8f239017a4e8ecb Mon Sep 17 00:00:00 2001 From: Alberto Arroyo Raygada Date: Fri, 21 Aug 2026 12:35:35 -0500 Subject: [PATCH 2/3] fix(deps): close the seven open advisories, none of which the open dependabot PRs touch (#631) Dependabot has five pull requests open (#435-#439) and they cover nestjs, opentelemetry, types/node and eslint-plugin-boundaries. The seven open alerts are about three other packages entirely, so merging all five would have closed none of them. - `@hono/node-server` 1.19.14 -> 1.19.15 (alerts 80, 81) - `esbuild` ^0.24.2 -> ^0.25.0 (alert 82) - `hono` 4.12.27 -> 4.12.34 via a root override (alerts 75, 77, 78, 79): ReDoS in CORS middleware, `memo()` retaining SSR output across requests, Proxy Helper leaking `Connection`-listed headers, and complexity DoS in the language middleware `hono` needs the override rather than a bump: it is transitive, reached through `@modelcontextprotocol/sdk` (`^4.11.4`) and as a peer of `@hono/node-server` (`^4`), so neither consumer's range forces the patched version. Changing `overrides` alone did not move it -- npm leaves an already-locked package where it is -- so the lock entry was re-resolved deliberately and its `resolved` and `integrity` restored from the registry, since dropping those would break `npm ci`. Verified, not assumed: - `npm ci` from a clean directory with only the manifests present: 1303 packages, hono 4.12.34 installed, **0 vulnerabilities** - esbuild 0.25 still vendors the ESM dependencies the packaged binary needs (GT-707): `dist/vendor/clack.cjs` 107 kB / 59 exports, `dist/vendor/conf.cjs` 410 kB / 1 export, and the built CLI answers `--version` and `rulesets` - tests on the three workspaces that touch hono: agent-runtime-api 86 passed, agent-runtime 483 passed, CLI 133 passed Signed-off-by: aarroyo Co-authored-by: Claude Opus 5 --- package-lock.json | 236 +++++++++++++++++++++------------------ package.json | 3 +- src/sdk/cli/package.json | 4 +- 3 files changed, 133 insertions(+), 110 deletions(-) diff --git a/package-lock.json b/package-lock.json index 37fb163dd..0fd1f0c15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1105,9 +1105,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", - "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", "cpu": [ "ppc64" ], @@ -1122,9 +1122,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", - "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", "cpu": [ "arm" ], @@ -1139,9 +1139,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", - "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", "cpu": [ "arm64" ], @@ -1156,9 +1156,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", - "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", "cpu": [ "x64" ], @@ -1173,9 +1173,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", - "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", "cpu": [ "arm64" ], @@ -1190,9 +1190,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", - "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", "cpu": [ "x64" ], @@ -1207,9 +1207,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", - "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", "cpu": [ "arm64" ], @@ -1224,9 +1224,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", - "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", "cpu": [ "x64" ], @@ -1241,9 +1241,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", - "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", "cpu": [ "arm" ], @@ -1258,9 +1258,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", - "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", "cpu": [ "arm64" ], @@ -1275,9 +1275,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", - "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", "cpu": [ "ia32" ], @@ -1292,9 +1292,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", - "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", "cpu": [ "loong64" ], @@ -1309,9 +1309,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", - "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", "cpu": [ "mips64el" ], @@ -1326,9 +1326,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", - "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", "cpu": [ "ppc64" ], @@ -1343,9 +1343,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", - "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", "cpu": [ "riscv64" ], @@ -1360,9 +1360,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", - "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", "cpu": [ "s390x" ], @@ -1377,9 +1377,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", - "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", "cpu": [ "x64" ], @@ -1394,9 +1394,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", - "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", "cpu": [ "arm64" ], @@ -1411,9 +1411,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", - "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", "cpu": [ "x64" ], @@ -1428,9 +1428,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", - "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", "cpu": [ "arm64" ], @@ -1445,9 +1445,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", - "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", "cpu": [ "x64" ], @@ -1461,10 +1461,27 @@ "node": ">=18" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", - "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", "cpu": [ "x64" ], @@ -1479,9 +1496,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", - "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", "cpu": [ "arm64" ], @@ -1496,9 +1513,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", - "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", "cpu": [ "ia32" ], @@ -1513,9 +1530,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", - "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", "cpu": [ "x64" ], @@ -1772,7 +1789,9 @@ } }, "node_modules/@hono/node-server": { - "version": "1.19.14", + "version": "1.19.15", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.15.tgz", + "integrity": "sha512-Za2ai6TLdKjUvnur+eenO6nuYYipVAEhyCAdaV8IRvmU9kK8crOZUSYvIXn72E4f8fJqyAbpcJuTsYYmZp9Deg==", "license": "MIT", "engines": { "node": ">=18.14.1" @@ -11036,9 +11055,9 @@ ] }, "node_modules/esbuild": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", - "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -11049,31 +11068,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.24.2", - "@esbuild/android-arm": "0.24.2", - "@esbuild/android-arm64": "0.24.2", - "@esbuild/android-x64": "0.24.2", - "@esbuild/darwin-arm64": "0.24.2", - "@esbuild/darwin-x64": "0.24.2", - "@esbuild/freebsd-arm64": "0.24.2", - "@esbuild/freebsd-x64": "0.24.2", - "@esbuild/linux-arm": "0.24.2", - "@esbuild/linux-arm64": "0.24.2", - "@esbuild/linux-ia32": "0.24.2", - "@esbuild/linux-loong64": "0.24.2", - "@esbuild/linux-mips64el": "0.24.2", - "@esbuild/linux-ppc64": "0.24.2", - "@esbuild/linux-riscv64": "0.24.2", - "@esbuild/linux-s390x": "0.24.2", - "@esbuild/linux-x64": "0.24.2", - "@esbuild/netbsd-arm64": "0.24.2", - "@esbuild/netbsd-x64": "0.24.2", - "@esbuild/openbsd-arm64": "0.24.2", - "@esbuild/openbsd-x64": "0.24.2", - "@esbuild/sunos-x64": "0.24.2", - "@esbuild/win32-arm64": "0.24.2", - "@esbuild/win32-ia32": "0.24.2", - "@esbuild/win32-x64": "0.24.2" + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" } }, "node_modules/escalade": { @@ -12311,7 +12331,9 @@ "license": "MIT" }, "node_modules/hono": { - "version": "4.12.27", + "version": "4.12.34", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.34.tgz", + "integrity": "sha512-GqXJqY/xJkJmuloTrnV1ZEXG3fqte+VjkUqoRNZXcrUidiUOP4fMSIHHY4tsqZBK++kVyWmt/AAfSUuy57/eSA==", "license": "MIT", "engines": { "node": ">=16.9.0" @@ -17399,7 +17421,7 @@ "@beyondnet/evolith-infra-providers": "1.2.1", "@beyondnet/evolith-sdk": "2.0.0", "@clack/prompts": "1.5.1", - "@hono/node-server": "1.19.14", + "@hono/node-server": "1.19.15", "@modelcontextprotocol/sdk": "1.29.0", "@nestjs/common": "11.1.27", "@nestjs/core": "11.1.27", @@ -17434,7 +17456,7 @@ "@typescript-eslint/eslint-plugin": "8.62.0", "@typescript-eslint/parser": "8.64.0", "debug": "4.4.3", - "esbuild": "^0.24.2", + "esbuild": "^0.25.0", "eslint": "9.39.4", "eslint-plugin-boundaries": "6.0.2", "fast-json-stable-stringify": "2.1.0", diff --git a/package.json b/package.json index 61193d373..f8e39f66c 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@eslint/eslintrc": { "ajv": "^6.12.6" }, - "ip-address": "10.4.0" + "ip-address": "10.4.0", + "hono": "4.12.34" } } diff --git a/src/sdk/cli/package.json b/src/sdk/cli/package.json index 26a5d8970..21d2682d6 100644 --- a/src/sdk/cli/package.json +++ b/src/sdk/cli/package.json @@ -75,7 +75,7 @@ "@beyondnet/evolith-infra-providers": "1.2.1", "@beyondnet/evolith-sdk": "2.0.0", "@clack/prompts": "1.5.1", - "@hono/node-server": "1.19.14", + "@hono/node-server": "1.19.15", "@modelcontextprotocol/sdk": "1.29.0", "@nestjs/common": "11.1.27", "@nestjs/core": "11.1.27", @@ -106,7 +106,7 @@ "@typescript-eslint/eslint-plugin": "8.62.0", "@typescript-eslint/parser": "8.64.0", "debug": "4.4.3", - "esbuild": "^0.24.2", + "esbuild": "^0.25.0", "eslint": "9.39.4", "eslint-plugin-boundaries": "6.0.2", "fast-json-stable-stringify": "2.1.0", From 6e2710d12f9e2b1045817279c3b5021bdecab8db Mon Sep 17 00:00:00 2001 From: Alberto Arroyo Raygada Date: Fri, 21 Aug 2026 13:11:06 -0500 Subject: [PATCH 3/3] fix(release): refuse a tag that names a version the package does not carry (#633) Five consecutive tags failed, each one filing a "Release Pipeline Failed" issue, and all five had the same cause: v1.3.3 -> cli 1.3.1 (#599) v1.3.4 -> cli 1.3.1 (#603) v1.3.5 -> cli 1.3.1 (#606) v1.3.6 -> cli 1.3.2 v1.3.7 -> cli 1.3.2 (#627) The pipeline reads the version from two places and never compared them. `publish-npm` reads `package.json` -- correctly -- and since #569 it asks the registry first, so an already-published version is skipped as a non-failure. `smoke-test-functional` then installs `@beyondnet/evolith-cli@${tag#v}`. When the two disagree, publish "succeeds" by skipping and the smoke test dies on `npm error code ETARGET / No matching version found`. Nothing was ever wrong with the build: the tag named a version that was never built. No re-run could fix it, and the run spent a full build, three binary packagings and three platform smoke tests before finding out. The question now lives in `release-gate`, before anything is built or published: if the tag and `src/sdk/cli/package.json` disagree, the run stops with both numbers named and a step summary saying which of the two to change. `release-gate` gains the checkout it needs to read the file. Verified: the assertion logic run against this tree rejects `v1.3.7` (package carries 1.3.2) and accepts `v1.3.2`. Workflow parses as YAML. Signed-off-by: aarroyo Co-authored-by: Claude Opus 5 --- .github/workflows/sdk-cli-release.yml | 54 +++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/.github/workflows/sdk-cli-release.yml b/.github/workflows/sdk-cli-release.yml index 5b49161eb..5a2aa5472 100644 --- a/.github/workflows/sdk-cli-release.yml +++ b/.github/workflows/sdk-cli-release.yml @@ -91,6 +91,9 @@ jobs: tag_name: ${{ steps.gate.outputs.tag_name }} version: ${{ steps.gate.outputs.version }} steps: + - name: Checkout + uses: actions/checkout@v7 + - name: Resolve release intent id: gate env: @@ -113,6 +116,57 @@ jobs: echo "No release requested for $GITHUB_REF — validation only." fi + # THE TAG AND THE PACKAGE MUST AGREE, AND UNTIL NOW NOTHING ASKED. + # + # This pipeline reads the version from two places and never compared them. + # `publish-npm` reads `package.json` — correctly — and since #569 it asks the + # registry first, so a version already published is skipped as a non-failure. + # `smoke-test-functional` then installs `@beyondnet/evolith-cli@${tag#v}`. + # + # When the two disagree, publish "succeeds" by skipping and the smoke test dies + # on `npm error code ETARGET / No matching version found`. That is not a flake and + # no re-run fixes it: the tag names a version that was never built. + # + # It happened on five consecutive tags, and each one filed an issue: + # v1.3.3 -> cli 1.3.1 (#599) + # v1.3.4 -> cli 1.3.1 (#603) + # v1.3.5 -> cli 1.3.1 (#606) + # v1.3.6 -> cli 1.3.2 + # v1.3.7 -> cli 1.3.2 (#627) + # + # Every one was doomed the moment the tag was pushed, and the pipeline spent a full + # build, three binary packagings and three platform smoke tests finding that out. + # The question belongs here, in the gate, before anything is built or published. + - name: Tag must name the version the package carries + if: steps.gate.outputs.release_created == 'true' + env: + TAG_NAME: ${{ steps.gate.outputs.tag_name }} + EXPECTED: ${{ steps.gate.outputs.version }} + run: | + set -euo pipefail + ACTUAL=$(node -p "require('./${CLI_DIR}/package.json').version") + if [ "$ACTUAL" != "$EXPECTED" ]; then + echo "::error::Tag $TAG_NAME asks to release $EXPECTED, but ${CLI_DIR}/package.json carries $ACTUAL." + { + echo "### Release refused: the tag and the package disagree" + echo "" + echo "| | |" + echo "|---|---|" + echo "| Tag | \`$TAG_NAME\` (asks for \`$EXPECTED\`) |" + echo "| \`${CLI_DIR}/package.json\` | \`$ACTUAL\` |" + echo "" + echo "Nothing was published. Publishing reads the package version and would have" + echo "shipped \`$ACTUAL\`, or skipped it as already-published; the smoke test then" + echo "installs \`@beyondnet/evolith-cli@$EXPECTED\`, which does not exist, and fails" + echo "with \`ETARGET\`." + echo "" + echo "Fix one of the two: bump the package to \`$EXPECTED\`, or delete this tag and" + echo "push \`v$ACTUAL\`." + } >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + echo "Tag $TAG_NAME and ${CLI_DIR}/package.json agree on $ACTUAL." + # ============================================ # GATE 2: Build and Test # ============================================