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 @@ -8855,7 +8855,7 @@
"dependencyRationale": "What this gate does NOT do is stated rather than left to be discovered. It detects a security-marked commit that no published version contains; it cannot detect a security fix nobody marked, which is a convention problem and belongs to GT-623 (release-please derives no bump from the non-conventional `security(...)` type this repository has used twice). It also reports, but does not fail on, a package whose published version is absent from this history -- an INEXACT boundary after a history rewrite -- because scanning the whole history conservatively is better than skipping the package silently. Finally, the gate needs the network: without a registry answer the package is skipped and named, and a run where EVERY package is skipped is a failure rather than a pass."
},
{
"id": "GT-633",
"id": "GT-640",
"closedAt": "2026-07-30",
"closureCommit": "29e940d4",
"evidence": [
Expand Down Expand Up @@ -8931,7 +8931,7 @@
],
"validationCommands": [
"node .harness/scripts/ci/49-validate-gap-id-allocation.mjs --verbose -> 515 ids on base, 515 on HEAD, 0 newly allocated, 0 collisions against origin/main.",
"IT FOUND A SECOND COLLISION ON ITS FIRST REAL RUN, which nobody knew about. Against origin/develop it reports GT-633: on develop that id is `evolith init` scaffolds a repository that cannot pass its own governance on the first run (c8270e48, 2026-07-29); on main it is the tautological-guard row (c3221276, 2026-07-30). Two gaps, one number, and the merge had not surfaced it yet.",
"IT FOUND A SECOND COLLISION ON ITS FIRST REAL RUN, which nobody knew about. Against origin/develop it reports GT-633: on develop that id is `evolith init` scaffolds a repository that cannot pass its own governance on the first run (c8270e48, 2026-07-29); on main it is the tautological-guard row (c3221276, 2026-07-30). Two gaps, one number, and the merge had not surfaced it yet. RESOLVED the same day by renumbering the newer row -- main's -- to GT-640, per the guard's own advice.",
"THE DISCRIMINATOR IS THE TITLE, deliberately. `the id already exists on base` is the normal case for 500-odd rows and says nothing; what makes it a defect is the id naming a DIFFERENT gap on each side. Evidence, status and criteria are all expected to change on a branch.",
"It refuses to guess which side is wrong -- a retitle and a collision are indistinguishable from outside -- so it names both titles and both refs, and says in the failure that it should not guess.",
"node --test .harness/scripts/ci/49-validate-gap-id-allocation.test.mjs -> 13/13, including the GT-634 collision reproduced over real git repositories rather than a mock of `git show`.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7860,7 +7860,7 @@ Serie histórica de gaps registrada en el antiguo `gap-analysis-core.es.md`, pre
**Title:** Nada hace visible el trabajo en vuelo entre ramas, así que el mismo gap se arregla dos veces

- **Purpose:** Que un gap que ya se está trabajando sea descubrible ANTES de que una segunda sesión lo empiece, y no en el merge.
- **Evidence:** **El 2026-07-30 el mismo trabajo se hizo dos veces, en tres ocasiones distintas, por sesiones que no podían verse.** (1) [`GT-633`](./gap-reference-catalog.es.md#gt-633) se arregló dos veces: un script de captura aterrizó en `main` como #276 y un renderer independiente dentro del spec aterrizó en `develop` como #279. Los dos eran correctos, los dos recapturaron los mismos números — y dos generadores para un artefacto es el defecto del propio GT-633 un nivel más arriba, así que una TERCERA sesión gastó una reconciliación entera (#294, #295, #296, #297) en dejar un solo renderer. (2) El parser del guard de evidencias se arregló dos veces: `d1ea72a3` en `main` ("stop the evidence guard blaming the evidence for two parser defects") y `5acb29ed` en `develop` ("the ratchet was stuck by two bugs in itself"). (3) Un id de GT se asignó dos veces, forzando la renumeración que registra [`GT-638`](./gap-reference-catalog.es.md#gt-638). **El coste no es el conflicto de merge.** Es el trabajo duplicado que ocurrió antes de que nadie llegara al conflicto, más la reconciliación que hizo falta después — y esa reconciliación introdujo un defecto propio (una comparación sensible al orden que reescribía la fecha de captura en cada corrida, invisible durante un día porque ambas estampaban la misma fecha). Tres duplicaciones, una sesión de reparación y un bug nuevo: ésa es la factura real. **Por qué el tablero no lo ve hoy:** una fila lleva estado (`PENDIENTE`, `EN-PROGRESO`) pero no QUIÉN la trabaja ni DÓNDE. Dos sesiones pueden leer ambas `GT-633 · PENDIENTE` y empezar ambas, correctamente. `08-validate-tracking` valida dentro de un único árbol de trabajo por construcción, así que no puede saber que existe otra rama. **Esto no es una convención que falte — la convención existe.** La regla de un solo driver para las olas de gaps es práctica establecida; lo que falta es cualquier mecanismo que la haga observable, así que en un día cargado se degrada en silencio y nadie se entera hasta el merge. Direcciones de arreglo: exigir una reclamación (rama o PR) en la fila que pasa a `EN-PROGRESO`, y derivar el conjunto de reclamaciones de los PR abiertos para que no pueda quedarse rancio; después, fallar en PR cuando un id `GT-*` esté reclamado por más de una rama abierta, nombrando a las dos. **CERRADO el 2026-07-30 — y en su primera corrida real encontró una SEGUNDA colisión que nadie conocía.** `49-validate-gap-id-allocation` compara el **Title:** de cada id en HEAD contra el título que ese mismo id lleva en la rama base: ausente en base es id nuevo, presente con el mismo título es el mismo gap editado, presente con título DISTINTO es un número nombrando dos gaps. El título es el discriminador a propósito — "el id ya existe en base" es el caso normal de 500 y pico filas y no dice nada. Corrido contra `origin/develop` reporta **`GT-633`**: en develop es "`evolith init` scaffolds a repository that cannot pass its own governance on the first run" (`c8270e48`, 2026-07-29) y en main es la fila del guard tautológico (`c3221276`, 2026-07-30). Dos gaps, un número, y el merge todavía no lo había sacado a la luz. **El guard se niega a adivinar qué lado está mal** — un retítulo y una colisión se ven igual desde fuera —, así que nombra los dos y lo dice. Cableado en `Governance guards (GT-578)` con un `git fetch` explícito de la base, porque un checkout superficial de CI no la tiene y un guard que fallara por ESO enseñaría a ignorarlo. Observado en rojo por `43-validate-guard-negative-fixtures` (38/38). **Lo que sigue sin ver, dicho y no insinuado:** un número asignado en una rama de la que nadie ha abierto PR. La salida `--verbose` lo advierte en cada id recién asignado en vez de dejar que el lector suponga una cobertura que no tiene.
- **Evidence:** **El 2026-07-30 el mismo trabajo se hizo dos veces, en tres ocasiones distintas, por sesiones que no podían verse.** (1) [`GT-640`](./gap-reference-catalog.es.md#gt-640) — registrado como GT-633 hasta la renumeración de abajo — se arregló dos veces: un script de captura aterrizó en `main` como #276 y un renderer independiente dentro del spec aterrizó en `develop` como #279. Los dos eran correctos, los dos recapturaron los mismos números — y dos generadores para un artefacto es el defecto del propio GT-633 un nivel más arriba, así que una TERCERA sesión gastó una reconciliación entera (#294, #295, #296, #297) en dejar un solo renderer. (2) El parser del guard de evidencias se arregló dos veces: `d1ea72a3` en `main` ("stop the evidence guard blaming the evidence for two parser defects") y `5acb29ed` en `develop` ("the ratchet was stuck by two bugs in itself"). (3) Un id de GT se asignó dos veces, forzando la renumeración que registra [`GT-638`](./gap-reference-catalog.es.md#gt-638). **El coste no es el conflicto de merge.** Es el trabajo duplicado que ocurrió antes de que nadie llegara al conflicto, más la reconciliación que hizo falta después — y esa reconciliación introdujo un defecto propio (una comparación sensible al orden que reescribía la fecha de captura en cada corrida, invisible durante un día porque ambas estampaban la misma fecha). Tres duplicaciones, una sesión de reparación y un bug nuevo: ésa es la factura real. **Por qué el tablero no lo ve hoy:** una fila lleva estado (`PENDIENTE`, `EN-PROGRESO`) pero no QUIÉN la trabaja ni DÓNDE. Dos sesiones pueden leer ambas `GT-640 · PENDIENTE` (registrado como GT-633 entonces) y empezar ambas, correctamente. `08-validate-tracking` valida dentro de un único árbol de trabajo por construcción, así que no puede saber que existe otra rama. **Esto no es una convención que falte — la convención existe.** La regla de un solo driver para las olas de gaps es práctica establecida; lo que falta es cualquier mecanismo que la haga observable, así que en un día cargado se degrada en silencio y nadie se entera hasta el merge. Direcciones de arreglo: exigir una reclamación (rama o PR) en la fila que pasa a `EN-PROGRESO`, y derivar el conjunto de reclamaciones de los PR abiertos para que no pueda quedarse rancio; después, fallar en PR cuando un id `GT-*` esté reclamado por más de una rama abierta, nombrando a las dos. **CERRADO el 2026-07-30 — y en su primera corrida real encontró una SEGUNDA colisión que nadie conocía.** `49-validate-gap-id-allocation` compara el **Title:** de cada id en HEAD contra el título que ese mismo id lleva en la rama base: ausente en base es id nuevo, presente con el mismo título es el mismo gap editado, presente con título DISTINTO es un número nombrando dos gaps. El título es el discriminador a propósito — "el id ya existe en base" es el caso normal de 500 y pico filas y no dice nada. Corrido contra `origin/develop` reporta **`GT-633`**: en develop es "`evolith init` scaffolds a repository that cannot pass its own governance on the first run" (`c8270e48`, 2026-07-29) y en main es la fila del guard tautológico (`c3221276`, 2026-07-30). Dos gaps, un número, y el merge todavía no lo había sacado a la luz. **RESUELTO el 2026-07-30 renumerando la fila más nueva —la de main— a [`GT-640`](./gap-reference-catalog.es.md#gt-640)**, según el propio consejo del guard. Hacerlo a mano es el coste que esta fila existe para describir: hubo que cambiar el id en la fila del tablero, el ancla del catálogo, el registro de evidencia de cierre, las referencias cruzadas de otras dos filas en los dos idiomas y tres comentarios de código — y los mensajes de commit y cuerpos de PR que nombran GT-633 no se pueden cambiar. **El guard se niega a adivinar qué lado está mal** — un retítulo y una colisión se ven igual desde fuera —, así que nombra los dos y lo dice. Cableado en `Governance guards (GT-578)` con un `git fetch` explícito de la base, porque un checkout superficial de CI no la tiene y un guard que fallara por ESO enseñaría a ignorarlo. Observado en rojo por `43-validate-guard-negative-fixtures` (38/38). **Lo que sigue sin ver, dicho y no insinuado:** un número asignado en una rama de la que nadie ha abierto PR. La salida `--verbose` lo advierte en cada id recién asignado en vez de dejar que el lector suponga una cobertura que no tiene.
- **Component:** `Governance` · **Criticality:** P2 · **Complexity:** M
- **Provenance:** Registrado el 2026-07-30 a partir de tres instancias observadas en un solo día, todas en el merge `develop` → `main` que las hizo visibles. Relacionado pero distinto de [`GT-638`](./gap-reference-catalog.es.md#gt-638): aquella fila trata de asignar un NOMBRE dos veces, ésta de hacer el TRABAJO dos veces. La misma carencia de coordinación produce ambas, y la colisión de id es su síntoma más barato.
- **Acceptance criteria:**
Expand All @@ -7874,7 +7874,7 @@ Serie histórica de gaps registrada en el antiguo `gap-analysis-core.es.md`, pre
**Title:** El tablero no tiene asignador de ids, así que dos ramas paralelas reparten el mismo número GT

- **Purpose:** Que un id de gap sea único por construcción y no por que quien registró el último leyera la rama correcta.
- **Evidence:** **Un id de gap se elige leyendo el `GT-*` más alto de la rama en la que uno está, y nada lo contrasta con ninguna otra rama.** Así que dos sesiones en paralelo asignan el mismo número, y una se entera en el merge. Ya ha pasado: `8449af3d` en `develop` lleva el mensaje *"chore(board): renumber the ratchet fix GT-634 -> GT-637, ID collision with develop"* — esa fila y [`GT-634`](./gap-reference-catalog.es.md#gt-634) en `main` recibieron el mismo id con horas de diferencia, por sesiones que no podían verse. **La renumeración es manual y con pérdidas**, que es lo que cuesta más que el choque: un id aparece en la fila del tablero, en el ancla del catálogo, en el registro de evidencia de cierre, en referencias cruzadas desde otras filas en los dos idiomas, en mensajes de commit y en cuerpos de PR — y sólo los tres primeros son comprobables mecánicamente. `08-validate-tracking` no puede ayudar, y no por falta de ganas: valida paridad EN/ES, registros de cierre y contadores **dentro de un único árbol de trabajo**, y las ramas quedan fuera de su mundo por construcción. **Por qué merece fila y no una convención:** el tablero es la única fuente de verdad de 635 gaps, y un id que significa dos cosas distintas en dos ramas vuelve ambigua toda referencia a él — incluidas las de `gap-closure-evidence.json`, que son datos validados por máquina. Tampoco es un desliz aislado: en el merge `develop` → `main` del 2026-07-30 el mismo patrón de duplicación convergente aparece **tres veces**: GT-633 se arregló dos veces por dos sesiones, el parser del guard de evidencias se arregló dos veces, y este id se asignó dos veces. Arreglo: asignar ids desde algo que no se pueda leer rancio — una marca de agua reservada y commiteada en la rama por defecto, o una comprobación en PR que falle cuando una rama introduce un id que ya existe en su base o en otro PR abierto, nombrando a ambos usuarios.
- **Evidence:** **Un id de gap se elige leyendo el `GT-*` más alto de la rama en la que uno está, y nada lo contrasta con ninguna otra rama.** Así que dos sesiones en paralelo asignan el mismo número, y una se entera en el merge. Ya ha pasado: `8449af3d` en `develop` lleva el mensaje *"chore(board): renumber the ratchet fix GT-634 -> GT-637, ID collision with develop"* — esa fila y [`GT-634`](./gap-reference-catalog.es.md#gt-634) en `main` recibieron el mismo id con horas de diferencia, por sesiones que no podían verse. **La renumeración es manual y con pérdidas**, que es lo que cuesta más que el choque: un id aparece en la fila del tablero, en el ancla del catálogo, en el registro de evidencia de cierre, en referencias cruzadas desde otras filas en los dos idiomas, en mensajes de commit y en cuerpos de PR — y sólo los tres primeros son comprobables mecánicamente. `08-validate-tracking` no puede ayudar, y no por falta de ganas: valida paridad EN/ES, registros de cierre y contadores **dentro de un único árbol de trabajo**, y las ramas quedan fuera de su mundo por construcción. **Por qué merece fila y no una convención:** el tablero es la única fuente de verdad de 635 gaps, y un id que significa dos cosas distintas en dos ramas vuelve ambigua toda referencia a él — incluidas las de `gap-closure-evidence.json`, que son datos validados por máquina. Tampoco es un desliz aislado: en el merge `develop` → `main` del 2026-07-30 el mismo patrón de duplicación convergente aparece **tres veces**: GT-640 (entonces GT-633) se arregló dos veces por dos sesiones, el parser del guard de evidencias se arregló dos veces, y este id se asignó dos veces. Arreglo: asignar ids desde algo que no se pueda leer rancio — una marca de agua reservada y commiteada en la rama por defecto, o una comprobación en PR que falle cuando una rama introduce un id que ya existe en su base o en otro PR abierto, nombrando a ambos usuarios.
- **Component:** `Governance` · **Criticality:** P2 · **Complexity:** S
- **Provenance:** Registrado el 2026-07-30 tras la colisión que describe, que obligó a renumerar en `develop`. El id de ESTA fila se asignó tomando la unión de ids entre `main` y `develop` en vez del máximo de una — que es justo el apaño que el arreglo debería volver innecesario.
- **Acceptance criteria:**
Expand Down Expand Up @@ -7908,7 +7908,7 @@ Serie histórica de gaps registrada en el antiguo `gap-analysis-core.es.md`, pre
- [x] Los fixes que reclama la ola de seguridad del 2026-07-23 se verifican presentes en la versión del SDK que el CLI y el MCP resuelven de verdad, en vez de asumirse por el número de versión — y la verificación REFUTÓ la premisa: ninguno de los siete commits de la ola toca `src/packages/sdk-client`, así que no hay fixes de la ola en el SDK que puedan estar o faltar.
- [x] `@beyondnet/evolith-sdk@1.1.0` queda deprecada en cuanto exista un sucesor al que sus consumidores puedan llegar — hecho el 2026-07-30, con un mensaje que da el motivo real (superseded por 2.0.0, `.passed` → `verdict`) y dice explícitamente que no es un aviso de seguridad.

#### GT-633
#### GT-640

**Title:** Un guard cuyo valor esperado era una copia de su valor real, sobre una entrada que se blanquea en un artefacto cinco veces mayor

Expand Down
Loading
Loading