Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10635,6 +10635,23 @@
"BOTH HALVES: evolith_arch32#623 (144fce23) and evolith_tracker#153 (97e1bc8e).",
"node .harness/scripts/ci/08-validate-tracking.mjs && node --test src/rulesets/standards/iso-5055-mapping.test.mjs"
]
},
{
"id": "GT-709",
"closedAt": "2026-09-05",
"closureCommit": "eb458372",
"dependencyDisposition": "none",
"evidence": [
"package.json",
"package-lock.json"
],
"validationCommands": [
"BASELINE MEASURED ON THE TREE WITHOUT THE CHANGE, with the same guard CI runs, rather than inherited from the CI log: `63-validate-npm-audit-gate.mjs` on `origin/main` (11562cce) reports 11 blocking rows / 7 high, naming fast-uri's four advisories (GHSA-jqff-g426-hqxp, GHSA-5jgf-p345-68v8, GHSA-f65p-4m7j-42xc, GHSA-fph4-wmhf-6fwf), the five ajv/commitlint chain rows it reports as `via:fast-uri`, and browserslist's two (GHSA-73wf-gq98-2v4g, GHSA-c83g-rgw3-j3cx).",
"THE CAUSE WAS A PIN OF OUR OWN, NOT A MISSING UPSTREAM FIX. `overrides.fast-uri` was `3.1.5` — exactly the last vulnerable release of the 3.x line. The advisory patches in `3.1.6`, inside the `^3.0.1` that `ajv@8.20.0` declares, so the fix fitted in the pin that already existed.",
"AFTER `fast-uri` 3.1.7: 2 blocking rows / 2 high, both browserslist — so 9 of the 11 rows are attributable to the single pin, measured and not inferred. AFTER `browserslist` 4.28.9: `0 undeclared high/critical advisories; 0 accepted with a recorded reason, 0 stale`.",
"NO EXCEPTION WAS DECLARED. `.harness/config/npm-audit-exceptions.json` still holds zero entries; that file is for advisories with no upstream fix, and both of these had one. The moderate `qs` advisory survives on purpose — the gate does not block below HIGH.",
"WHY THE GATE STOPPED NOTHING is registered as its own row rather than as prose here: `Security Audit` is not among the nine required contexts, and eight PRs merged into `main` while it was red. See GT-710."
]
}
]
}
63 changes: 63 additions & 0 deletions reference/core/control-center/gaps/gap-reference-catalog.es.md
Original file line number Diff line number Diff line change
Expand Up @@ -10050,3 +10050,66 @@ Los dos se arreglaron de forma estructural y no como correcciones: el rethrow no
- [x] **FALSABILIDAD:** ningún enlace de ninguno de los dos repositorios resuelve a un fichero KDD borrado, comprobado tras el barrido y no supuesto desde la lista de borrados. **CUMPLIDO para el Core** — buscar los ocho nombres borrados en todos los markdown no devuelve nada fuera del `ADR-0127` y del aviso de corrección del documento de rediseño, que los nombran como retirados en vez de enlazarlos.
- **Estado:** `COMPLETADO`

#### GT-709

**Título:** Un `overrides` puesto para cerrar un advisory se vuelve el techo que impide cerrarlo la vez siguiente

- **Propósito:** Que el bloque de `overrides` deje de ser el sitio donde una CVE se queda a vivir, y que `Security Audit` vuelva a significar algo.
- **Evidencia, medida el 2026-09-05 con `63-validate-npm-audit-gate.mjs` —el guard que corre CI— sobre el mismo árbol:**

| árbol | filas bloqueantes | altas |
|---|---:|---:|
| `origin/main` (`11562cce`) | 11 | 7 |
| + `fast-uri` `3.1.7` | 2 | 2 |
| + `browserslist` `4.28.9` | **0** | **0** |

- **La causa no era una dependencia sin arreglo, sino dos pins propios.** `overrides.fast-uri` estaba fijado en `3.1.5` — exactamente la última versión vulnerable de la rama 3.x. `GHSA-jqff-g426-hqxp` parchea en `3.1.6`, dentro del `^3.0.1` que declara `ajv@8.20.0`, así que el arreglo cabía en el pin que ya existía. Las nueve filas que se van con ese cambio son las cuatro advisories de `fast-uri` (`GHSA-jqff-g426-hqxp`, `GHSA-5jgf-p345-68v8`, `GHSA-f65p-4m7j-42xc`, `GHSA-fph4-wmhf-6fwf`) más las cinco filas de la cadena `ajv` / `@commitlint/config-validator` / `@commitlint/resolve-extends` / `@commitlint/load` / `@commitlint/cli`, que el gate reportaba `via:fast-uri`.
- **Las dos restantes eran el mismo patrón otra vez.** `browserslist` `4.28.4`, transitivo solo-dev por `ts-jest`→`@babel/core`→`@babel/helper-compilation-targets` y por `@nestjs/cli`→`webpack`, con `GHSA-73wf-gq98-2v4g` y `GHSA-c83g-rgw3-j3cx` parcheados en `4.28.7`. Se pinea `4.28.9` con la misma forma de override que el comentario del propio `sdk-cli-ci.yml` prescribe para este caso.
- **Lo que NO se hizo, y por qué:** no se declaró ninguna excepción en `.harness/config/npm-audit-exceptions.json`. Ese fichero es para advisories sin arreglo upstream, y aquí había arreglo en las dos; declararlas habría convertido un pin caduco en una excepción permanente.
- **Casos de uso:**
- Un revisor ve `Security Audit` en rojo, comprueba que la advisory es de un transitivo y la descarta como ajena, sin mirar que el techo lo pone un `overrides` propio.
- Alguien añade un `overrides` para cerrar una CVE y con ello fija la versión que impedirá cerrar la siguiente de ese mismo paquete.
- **Impacto:** Una CVE ALTA viva en `main` durante tres días, con el gate que la detecta en rojo y ocho merges pasando por encima.
- **Resultado esperado:** `63-validate-npm-audit-gate.mjs` en verde sobre `main` sin excepciones declaradas.
- **Ficheros afectados:** `package.json`, `package-lock.json`
- **Componente:** `Infra` · **Criticidad:** P2 · **Complejidad:** S
- **Principal:** `XS` · **Interest:** `HIGH` · **Basis:** `estimate`
- **Procedencia:** Registrado el 2026-09-05, encontrado barriendo los pull requests de dependabot: los cinco de npm salían con `Security Audit` en rojo, y contrastarlo contra `main` mostró que el rojo era anterior a los cinco.
- **Criterios de aceptación:**
- [x] El gate pasa de 11 filas bloqueantes a 0, medido con el guard real sobre el árbol y no deducido del advisory. **CUMPLIDO** — `0 undeclared high/critical advisories; 0 accepted with a recorded reason, 0 stale`.
- [x] El arreglo es un cambio de versión, no una excepción declarada. **CUMPLIDO** — `npm-audit-exceptions.json` sigue con cero entradas.
- [x] La versión elegida respeta el rango que declara el consumidor, en vez de forzarlo. **CUMPLIDO** — `3.1.7` cae dentro del `^3.0.1` de `ajv@8.20.0`.
- [x] **FALSABILIDAD:** el baseline se midió sobre el árbol SIN el cambio y con el mismo guard, no se heredó del log de CI. **CUMPLIDO** — 11 filas / 7 altas sobre `origin/main`, con las cuatro filas de `fast-uri` y las dos de `browserslist` nombradas una a una antes de tocar nada.
- **Estado:** `COMPLETADO`

#### GT-710

**Título:** El gate que mide las CVE no es un check requerido, así que ocho merges pasaron por encima de él en rojo

- **Propósito:** Que un advisory ALTA sin declarar bloquee el merge en lugar de limitarse a informarlo.
- **Evidencia, medida el 2026-09-05:**

| dato | valor |
|---|---|
| contextos requeridos en `main` y `develop` | 9 |
| ¿incluyen `Security Audit`? | **no** (tampoco `Trivy` ni `build-and-test`) |
| `Security Audit` en rojo desde | `b84523b4`, 2026-09-02 |
| merges a `main` en ese intervalo | **8**, cuatro de ellos de dependencias npm |
| cómo lo presenta GitHub | `UNSTABLE`, no `BLOCKED` |

- **Los nueve requeridos son** `CodeQL SAST`, `Secret Detection (gitleaks)`, `Services build (GHCR)`, `Test`, `Test core`, `Test core-api`, `Test core-domain`, `Test mcp-server` y `Validate documentation`.
- **El workflow nombra el modo de fallo y luego lo construye.** El comentario de `sdk-cli-ci.yml` advierte de que un check permanentemente rojo enseña a los revisores a descontar el rojo — y el check queda fuera del conjunto requerido, que es la vía más directa a ese resultado. Los cuatro PR de dependencias npm mergeados en el intervalo ([#664](https://github.com/beyondnetcode/evolith_arch32/pull/664), [#665](https://github.com/beyondnetcode/evolith_arch32/pull/665), [#666](https://github.com/beyondnetcode/evolith_arch32/pull/666), [#667](https://github.com/beyondnetcode/evolith_arch32/pull/667)) son exactamente la clase de cambio que el gate existe para juzgar.
- **Casos de uso:**
- Un bump de dependencias introduce una CVE ALTA y se mergea igual, porque el único check que la ve no es requerido.
- Un revisor aprende que `Security Audit` rojo es normal y deja de leerlo.
- **Impacto:** El gate de seguridad de dependencias es informativo y no impide ningún merge, incluidos los de dependencias.
- **Resultado esperado:** `Security Audit` entre los contextos requeridos de `main` y `develop`, con un PR que lleve una alta sin declarar quedando `BLOCKED`.
- **Ficheros afectados:** protección de rama de `main` y `develop`, `.github/workflows/sdk-cli-ci.yml`
- **Componente:** `Infra` · **Criticidad:** P1 · **Complejidad:** S
- **Principal:** `XS` · **Interest:** `HIGH` · **Basis:** `estimate`
- **Procedencia:** Registrado el 2026-09-05 al cerrar [`GT-709`](#gt-709): explicar por qué una CVE ALTA había sobrevivido tres días exigía mirar qué checks bloquean de verdad, y `Security Audit` no estaba entre ellos.
- **Criterios de aceptación:**
- [ ] `Security Audit` figura en los contextos requeridos de `main` y de `develop`.
- [ ] **FALSABILIDAD:** un PR con un advisory ALTA sin declarar sale `BLOCKED` y no `UNSTABLE`, observado y no supuesto.
- [ ] La decisión sobre `Trivy` y `build-and-test` queda escrita — requeridos también, o registrado por qué no lo son.
- **Estado:** `PENDIENTE`
63 changes: 63 additions & 0 deletions reference/core/control-center/gaps/gap-reference-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10143,3 +10143,66 @@ Both were fixed structurally rather than corrected: the rethrow now names BOTH f
- [x] **FALSIFIABILITY:** no link in either repository resolves to a deleted KDD file, checked after the sweep rather than assumed from the delete list. **MET for the Core** — searching the eight deleted filenames across every markdown file returns nothing outside `ADR-0127` and the redesign doc's correction notice, both of which name them as retired rather than link to them.
- **Status:** `DONE`

#### GT-709

**Title:** An `overrides` pin added to close an advisory becomes the ceiling that prevents closing it the next time

- **Purpose:** Stop the `overrides` block being the place a CVE settles in, and make `Security Audit` mean something again.
- **Evidence, measured 2026-09-05 with `63-validate-npm-audit-gate.mjs` — the guard CI runs — against the same tree:**

| tree | blocking rows | high |
|---|---:|---:|
| `origin/main` (`11562cce`) | 11 | 7 |
| + `fast-uri` `3.1.7` | 2 | 2 |
| + `browserslist` `4.28.9` | **0** | **0** |

- **The cause was not a dependency without a fix, but two pins of our own.** `overrides.fast-uri` was set to `3.1.5` — exactly the last vulnerable release of the 3.x line. `GHSA-jqff-g426-hqxp` patches in `3.1.6`, inside the `^3.0.1` that `ajv@8.20.0` declares, so the fix fitted in the pin that was already there. The nine rows that go with that change are `fast-uri`'s own four advisories (`GHSA-jqff-g426-hqxp`, `GHSA-5jgf-p345-68v8`, `GHSA-f65p-4m7j-42xc`, `GHSA-fph4-wmhf-6fwf`) plus the five rows of the `ajv` / `@commitlint/config-validator` / `@commitlint/resolve-extends` / `@commitlint/load` / `@commitlint/cli` chain, which the gate reported as `via:fast-uri`.
- **The remaining two were the same pattern again.** `browserslist` `4.28.4`, a dev-only transitive through `ts-jest`→`@babel/core`→`@babel/helper-compilation-targets` and `@nestjs/cli`→`webpack`, with `GHSA-73wf-gq98-2v4g` and `GHSA-c83g-rgw3-j3cx` patched in `4.28.7`. Pinned to `4.28.9` with the same override shape `sdk-cli-ci.yml`'s own comment prescribes for this case.
- **What was NOT done, and why:** no exception was declared in `.harness/config/npm-audit-exceptions.json`. That file is for advisories with no upstream fix, and both of these had one; declaring them would have turned a stale pin into a permanent exception.
- **Use cases:**
- A reviewer sees `Security Audit` red, checks that the advisory is transitive and dismisses it as somebody else's, without noticing that the ceiling is set by an `overrides` entry of our own.
- Someone adds an `overrides` entry to close a CVE and thereby pins the version that will prevent closing the next one in that same package.
- **Impact:** A HIGH CVE live on `main` for three days, with the gate that detects it red and eight merges going past it.
- **Expected outcome:** `63-validate-npm-audit-gate.mjs` green on `main` with no declared exceptions.
- **Files affected:** `package.json`, `package-lock.json`
- **Component:** `Infra` · **Criticality:** P2 · **Complexity:** S
- **Principal:** `XS` · **Interest:** `HIGH` · **Basis:** `estimate`
- **Provenance:** Registered 2026-09-05, found while sweeping the dependabot pull requests: all five npm ones came out with `Security Audit` red, and contrasting that against `main` showed the red predated all five.
- **Acceptance criteria:**
- [x] The gate goes from 11 blocking rows to 0, measured with the real guard against the tree rather than deduced from the advisory. **MET** — `0 undeclared high/critical advisories; 0 accepted with a recorded reason, 0 stale`.
- [x] The fix is a version change, not a declared exception. **MET** — `npm-audit-exceptions.json` still holds zero entries.
- [x] The chosen version respects the range the consumer declares rather than forcing it. **MET** — `3.1.7` falls inside `ajv@8.20.0`'s `^3.0.1`.
- [x] **FALSIFIABILITY:** the baseline was measured on the tree WITHOUT the change and with the same guard, not inherited from the CI log. **MET** — 11 rows / 7 high on `origin/main`, with `fast-uri`'s four rows and `browserslist`'s two named one by one before anything was touched.
- **Status:** `DONE`

#### GT-710

**Title:** The gate that measures CVEs is not a required check, so eight merges went past it while it was red

- **Purpose:** Make an undeclared HIGH advisory block the merge instead of merely reporting it.
- **Evidence, measured 2026-09-05:**

| fact | value |
|---|---|
| required contexts on `main` and `develop` | 9 |
| do they include `Security Audit`? | **no** (nor `Trivy` nor `build-and-test`) |
| `Security Audit` red since | `b84523b4`, 2026-09-02 |
| merges into `main` in that window | **8**, four of them npm dependency changes |
| how GitHub renders them | `UNSTABLE`, not `BLOCKED` |

- **The nine required are** `CodeQL SAST`, `Secret Detection (gitleaks)`, `Services build (GHCR)`, `Test`, `Test core`, `Test core-api`, `Test core-domain`, `Test mcp-server` and `Validate documentation`.
- **The workflow names the failure mode and then builds it.** The comment in `sdk-cli-ci.yml` warns that a permanently red check trains reviewers to discount red — and the check is left out of the required set, which is the most direct route to that outcome. The four npm dependency PRs merged in the window ([#664](https://github.com/beyondnetcode/evolith_arch32/pull/664), [#665](https://github.com/beyondnetcode/evolith_arch32/pull/665), [#666](https://github.com/beyondnetcode/evolith_arch32/pull/666), [#667](https://github.com/beyondnetcode/evolith_arch32/pull/667)) are exactly the class of change that gate exists to judge.
- **Use cases:**
- A dependency bump introduces a HIGH CVE and merges anyway, because the only check that sees it is not required.
- A reviewer learns that a red `Security Audit` is normal and stops reading it.
- **Impact:** The dependency security gate is advisory and blocks no merge, including dependency merges.
- **Expected outcome:** `Security Audit` among the required contexts on `main` and `develop`, with a PR carrying an undeclared high coming out `BLOCKED`.
- **Files affected:** branch protection on `main` and `develop`, `.github/workflows/sdk-cli-ci.yml`
- **Component:** `Infra` · **Criticality:** P1 · **Complexity:** S
- **Principal:** `XS` · **Interest:** `HIGH` · **Basis:** `estimate`
- **Provenance:** Registered 2026-09-05 while closing [`GT-709`](#gt-709): explaining why a HIGH CVE had survived three days required looking at which checks actually block, and `Security Audit` was not among them.
- **Acceptance criteria:**
- [ ] `Security Audit` appears in the required contexts of both `main` and `develop`.
- [ ] **FALSIFIABILITY:** a PR carrying an undeclared HIGH advisory comes out `BLOCKED` rather than `UNSTABLE`, observed and not assumed.
- [ ] The decision on `Trivy` and `build-and-test` is written down — required too, or a recorded reason why not.
- **Status:** `PENDING`
Loading
Loading