Ir al contenido
OmniRoute source

Quality-Gate System — Critical Assessment, Catalog and Replication Playbook (Español)

Parte 1 — Veredicto y clasificación de madurez

Sección titulada «Parte 1 — Veredicto y clasificación de madurez»

Calificación general: A− / “Avanzado”. Entre el ~5–10 % de los mejores proyectos. El sistema implementa de manera independiente varios patrones que el sector identifica explícitamente, lo cual constituye la señal de alineación más sólida (no copiamos una lista de comprobación; convergimos en las prácticas correctas).

Marco de referencia Nuestra situación Calificación
OWASP DSOMM (5 niveles, 5 dimensiones) Nivel 3 sólido, aproximándose al 4 en Intensidad de las pruebas y Profundidad estática. La mayoría de las organizaciones se sitúan en los niveles 1–2. L3→L4
OpenSSF Scorecard (18 comprobaciones) Superamos CI-Tests, Code-Review, Dependency-Update-Tool, Fuzzing, SAST, Signed-Releases (procedencia), Token-Permissions, Vulnerabilities y Dangerous-Workflow. Carencias: Branch-Protection en main está desactivada; algunas acciones no están fijadas. ~7–8/10
SLSA (4 niveles) npm publish --provenance + id-token: write + compilación alojada en GitHub = L2, aproximándose a L3. Falta un entorno de compilación reforzado/hermético para L3+. L2→L3
SonarQube “Clean as You Code” Filosofía idéntica: el ratchet garantiza la ausencia de regresiones (el código nuevo no empeora la métrica). Divergencia: Sonar recomienda pocas condiciones; nosotros tenemos ~46 controles (riesgo de fatiga). Alineado, con matices
Patrón Quality-Ratchet Implementación de referencia: ratchet + dedicatedGate + tightenSlack + --require-tighten + omisión controlada. Más sofisticada que la mayoría de los ejemplos públicos. Ejemplar
DORA 2024 Muy sólido en el eje de estabilidad. Riesgo: unos controles exigentes pueden aumentar el tiempo de entrega — mitigado mediante la división de controles rápidos, aunque con una carencia de cobertura (véase la Parte 2). Sólido (estabilidad)
OWASP LLM Top 10 (2025) Cubrimos el riesgo n.º 1 (inyección de prompts) con una protección en tiempo de ejecución + promptfoo (evaluación) + garak (red teaming). Herramientas estándar del sector. Cubierto
Pruebas de mutación Stryker se ejecuta cada noche, con umbrales de 70/50 y 8 módulos críticos. Consenso del sector (60 % en código existente / 80 % en código nuevo, ejecución nocturna) — lo superamos. Carencia: la puntuación aún no utiliza un ratchet. Casi logrado

Parte 2 — Evaluación crítica (fortalezas + debilidades sinceras)

Sección titulada «Parte 2 — Evaluación crítica (fortalezas + debilidades sinceras)»

Fortalezas (lo que está por encima de la media)

Sección titulada «Fortalezas (lo que está por encima de la media)»
  1. Motor de trinquete multimétrica. El corazón del sistema. 24 métricas en quality-baseline.json
    • 4 líneas base específicas, cada una con dirección (up/down), tolerancia (eps), margen (tightenSlack) y el indicador dedicatedGate. Lo que se corrige permanece corregido: es el antídoto contra la entropía de la base de código.
  2. Defensa en profundidad para la cadena de suministro. SAST (CodeQL/Sonar) + secretos (gitleaks con useDefault) + SCA (osv/npm-audit/Trivy/Dependabot) + licencias + lockfile + SBOM + procedencia SLSA + Scorecard + refuerzo de workflows (zizmor). Pocas bases de código tienen una pila tan completa.
  3. Antídotos contra la ley de Goodhart. Usar la cobertura como objetivo es un antipatrón clásico («cuando una medida se convierte en objetivo, deja de ser una buena medida»). Contamos con los contrapesos: pruebas de mutación (miden si la prueba detecta el error, no solo si ejecuta la línea), check-test-masking (impide debilitar las aserciones para aprobar), umbrales mínimos de cobertura por módulo (obligan a probar el código de ALTO riesgo, no solo las partes fáciles) y check-pr-evidence (regla estricta n.º 18).
  4. Controles contra alucinaciones y de coherencia. Una categoría poco común y valiosa: check-known-symbols, check-fetch-targets, check-openapi-routes y check-docs-symbols garantizan que la documentación, las especificaciones y los despachos mediante cadenas apunten a símbolos existentes. Detectan el «deterioro» que el linting y las pruebas no detectan.
  5. Ciclo de vida consultivo→bloqueante. Los nuevos controles se incorporan como consultivos (no bloquean las fusiones mientras maduran) y después pasan a ser bloqueantes al final del ciclo. Esto reduce la fricción sin perder el nivel máximo de exigencia.
  6. Omisión controlada cuando falta infraestructura. Los analizadores (--ratchet) terminan con exit 0 si falla el binario o la red: la falta de infraestructura nunca bloquea una PR legítima. Ingeniería madura.
  7. Cultura codificada. Las reglas estrictas + trust-but-verify + la lista de excepciones obsoletas + el control de evidencias convierten la disciplina en verificación automatizada.
  1. 🔴 La separación de controles rápidos aún deja un vacío estructural. quality.yml (PR→release/**) ahora ejecuta la comprobación de tipos, pruebas deterministas rápidas y una compilación de producción consultiva para las PR de código, pero todavía no ejecuta toda la superficie de PR de lanzamiento de ci.yml (trinquetes de cobertura, artefacto de paquete, integración, E2E, SonarQube). La motivación (velocidad) es válida, pero el control debería estar donde se produce la fusión (shift-left). La mayor corrección estructural pendiente.
  2. 🟠 Riesgo de proliferación y fatiga de controles. ~46 controles + 25 jobs es MUCHO. El propio Sonar advierte de que demasiadas condiciones provocan «fatiga de controles» y debates sobre prioridades, con el riesgo de que se ignore algún control. DORA advierte de que los controles pesados perjudican el tiempo de entrega. Lo mitigamos con niveles consultivos y trinquetes no absolutos, pero falta una revisión periódica del ROI de cada control (algunos microcontroles de sincronización de documentación se pueden consolidar).
  3. 🟠 La puntuación de mutación aún no es un trinquete. El antídoto más potente contra la manipulación de la cobertura es consultivo. Es el elemento pendiente de mayor valor (y ya está construido al 90 %).
  4. 🟡 Controles consultivos que deberían bloquear (con el alcance adecuado). osv (vulnCount) y oasdiff son consultivos a pesar de tener líneas base congeladas. Que osv sea consultivo tiene sentido (un nuevo CVE en una dependencia antigua bloquearía una PR no relacionada), pero existe un término medio (bloquear solo vulnerabilidades CRITICAL+corregibles, como hicimos con Trivy). Que oasdiff sea consultivo implica que puede pasar un cambio que rompa el contrato.
  5. 🟡 La seguridad en tiempo de ejecución solo se comprueba por la noche. schemathesis/garak/promptfoo/chaos/k6 se ejecutan por la noche. Es una decisión correcta (son lentos y necesitan un servidor activo), pero una PR puede introducir una regresión en la protección contra inyecciones que solo se detectará la noche siguiente.
  6. 🟡 La protección de la rama main está DESACTIVADA. BRANCH_LOCK_TOKEN bloquea las ramas de release, pero main no está protegida. Scorecard/DSOMM lo penalizan. Se requiere una acción del propietario.
  7. 🟡 Configuración predeterminada de CodeQL; semgrep no está codificado. La configuración predeterminada funciona (0 alertas), pero un codeql.yml confirmado en el repositorio ofrece más control; semgrep se ejecuta mediante una plataforma externa en la nube y no está versionado en el repositorio.

Parte 3 — Catálogo completo de puntos de control de calidad (portable)

Sección titulada «Parte 3 — Catálogo completo de puntos de control de calidad (portable)»

Las 12 categorías siguientes constituyen el «sistema de calidad» en formato reutilizable. Cada una enumera el objetivo (qué proteger), las herramientas que utilizamos y el equivalente independiente de las herramientas para reproducirlo en cualquier stack.

1. Estilo y formato (deterministas, rápidos)

Sección titulada «1. Estilo y formato (deterministas, rápidos)»
  • OmniRoute: Prettier + ESLint mediante lint-staged (pre-commit), 2 espacios/comillas dobles/100 columnas.
  • Genérico: un formateador con corrección automática + un linter, ejecutados en pre-commit sobre los archivos preparados.
  • OmniRoute: typecheck:core (bloqueante) + typecheck:noimplicit:core (orientativo) + umbral incremental de type-coverage del 92.17% + presupuesto de any por archivo.
  • Genérico: comprobación estricta de tipos en CI + métrica incremental de cobertura de tipos + presupuesto por archivo para any/vías de escape.
  • OmniRoute: 2 ejecutores sin solapamiento (Node nativo + vitest), 8 particiones, cobertura global 60/60/60/60 + umbral incremental de ~76% + 8 mínimos por módulo para módulos críticos + pruebas de propiedades nocturnas + pruebas de mutación nocturnas.
  • Genérico: ejecutor(es) de pruebas + mínimo absoluto de cobertura (evita el cero) + umbral incremental de cobertura (evita regresiones) + mínimos por módulo para código de alto riesgo (antídoto contra la ley de Goodhart) + pruebas basadas en propiedades para lógica pura + pruebas de mutación nocturnas como medida real de la calidad de las pruebas.
  • OmniRoute: pr-test-policy (el código de producción requiere una prueba), check-test-masking (bloquea aserciones debilitadas), pr-evidence (una afirmación de éxito requiere un bloque de evidencias), test-discovery (cada prueba es recopilada por un ejecutor).
  • Genérico: control «código nuevo ⇒ prueba nueva» + detector de aserciones eliminadas/tautologías + requisito de evidencias (TDD o prueba viva) + garantía de que ninguna prueba quede huérfana fuera de los patrones glob.

5. Complejidad y salud del código (umbrales incrementales)

Sección titulada «5. Complejidad y salud del código (umbrales incrementales)»
  • OmniRoute: advertencias de ESLint (3769↓), duplicación con jscpd (5.72%↓), complejidad ciclomática+máximo de líneas (1800↓), complejidad cognitiva con sonarjs (753↓), código muerto/exportaciones sin usar con knip (339↓), tamaño por archivo (congelado, solo puede reducirse), dependencias circulares (Tarjan personalizado, bloqueante).
  • Genérico: aplicar un umbral incremental a cada métrica de salud (advertencias, duplicación, complejidad ciclomática y cognitiva, código muerto, tamaño de archivos, ciclos de importación). La dirección siempre es «no empeorar».
  • OmniRoute: CodeQL (umbral incremental de alertas = 0), gitleaks ([extend] useDefault=true — ¡crítico!), SonarQube, reglas de seguridad personalizadas (public-creds, error-helper, route-guard-membership, route-validation).
  • Genérico: SAST (CodeQL/Sonar/semgrep) con umbral incremental de alertas + escáner de secretos con conjunto de reglas predeterminado heredado (una configuración personalizada que reemplace la predeterminada = punto ciego) + controles de seguridad de Reglas Estrictas específicos del proyecto.
  • OmniRoute: osv-scanner + npm-audit + Trivy + Dependabot (SCA), license-checker (lista de permitidos SPDX), lockfile-lint (HTTPS+sha512+registro), check-deps contra slopsquatting (lista de permitidos + antigüedad ≥72 h).
  • Genérico: SCA con múltiples fuentes + lista de licencias permitidas + comprobación de integridad del archivo de bloqueo + lista de dependencias permitidas con comprobación de antigüedad/typosquatting + bot de actualizaciones agrupadas.

8. Cadena de suministro (compilación y publicación)

Sección titulada «8. Cadena de suministro (compilación y publicación)»
  • OmniRoute: SBOM (CycloneDX + syft), procedencia SLSA (--provenance), OpenSSF Scorecard (semanal), refuerzo de workflows (zizmor: artipacked→persist-credentials:false, envenenamiento de caché, permisos de tokens).
  • Genérico: generar una SBOM al publicar + procedencia firmada (SLSA L2+) + Scorecard programado + reforzar todos los workflows (tokens con privilegios mínimos, sin credenciales persistentes en checkouts que no realizan push, acciones fijadas por SHA).
  • OmniRoute: oasdiff (cambios incompatibles de OpenAPI), schemathesis (fuzzing de contratos nocturno), openapi-coverage (% de rutas documentadas, umbral incremental del 38.3%), openapi-security-tiers (especificación frente a protección de rutas).
  • Genérico: comparación de contratos para detectar cambios incompatibles (oasdiff/buf) + fuzzing basado en propiedades contra la especificación (schemathesis) + cobertura de documentación con umbral incremental + coherencia entre especificación↔código.
  • OmniRoute: docs-sync (versiones reflejadas), docs-counts-sync (cifras de la documentación frente al código), env-doc-sync, doc-links, fabricated-docs, cli-i18n, i18n-ui-coverage (--threshold=65 + umbral incremental del 80.1%).
  • Genérico: sincronizar versiones/cifras/variables de entorno entre la documentación y el código (mediante un control, no por confianza) + validar enlaces internos + cobertura de i18n con umbral incremental.

11. Antialucinaciones/coherencia (la categoría poco común)

Sección titulada «11. Antialucinaciones/coherencia (la categoría poco común)»
  • OmniRoute: known-symbols (despacho por cadenas ⇒ símbolo vivo), provider-consistency, fetch-targets (fetch del cliente ⇒ ruta real), docs-symbols, db-rules (Reglas Estrictas n.º 2/n.º 5), migration-numbering.
  • Genérico: para cada «fuente de verdad duplicada» (registro, despacho por cadenas, referencias entre capas), un control que demuestre que ambos lados coinciden. Detecta el deterioro que la comprobación de tipos y las pruebas no detectan.

12. Resiliencia y dominio (específico del producto)

Sección titulada «12. Resiliencia y dominio (específico del producto)»
  • OmniRoute: caos (inyección de fallos), crecimiento del heap (fugas), k6 (prueba prolongada), promptfoo+garak (red team de LLM según OWASP LLM Top 10), las 3 leyes de resiliencia (circuit-breaker/cooldown/lockout).
  • Genérico: identificar los modos de fallo de tu dominio y disponer de un control (aunque sea nocturno) para cada uno. Para aplicaciones de IA: red team contra inyecciones. Para sistemas distribuidos: caos + fugas + pruebas prolongadas.

Parte 4 — Plan de replicación para cualquier proyecto

Sección titulada «Parte 4 — Plan de replicación para cualquier proyecto»

Constrúyalo en fases, cada una de las cuales aporta valor por sí sola. No intente implementar las 12 categorías a la vez — eso provoca exactamente la fatiga de controles sobre la que advierte la Parte 2. Cada nuevo control comienza como consultivo y se vuelve bloqueante cuando es estable.

La pieza central reutilizable: la «anatomía de un control de trinquete»

Sección titulada «La pieza central reutilizable: la «anatomía de un control de trinquete»»

Todo el sistema gira en torno a este patrón de 3 archivos. Cópielo primero:

  1. baseline.json — el valor congelado de la métrica + direction (up/down) + eps (antifallos intermitentes) + tightenSlack + dedicatedGate.
  2. collect-metrics.<ext> — ejecuta la herramienta, extrae el número y escribe metrics.json.
  3. check-ratchet.<ext> — compara metrics.json con baseline.json; exit 1 solo si ha empeorado más allá de eps; exit 0 (omisión controlada) si faltaba la herramienta/infraestructura; con --require-tighten, exit 1 si mejoró sin actualizar la línea base (consolida la mejora).

Una vez implementado esto, cada nueva métrica (cobertura, complejidad, advertencias, alertas SAST, tamaño del paquete, puntuación de mutación…) es simplemente una línea en la línea base.

Existe CI; formateador + linter + comprobación de tipos + 1 ejecutor de pruebas + umbral absoluto de cobertura (p. ej., 60 %). El pre-commit ejecuta comprobaciones rápidas que pueden corregirse automáticamente. Resultado: ninguna PR rompe lo básico.

Fase 1 — El motor de trinquete (semana 2) — la base de todo

Sección titulada «Fase 1 — El motor de trinquete (semana 2) — la base de todo»

Implemente los 3 archivos anteriores. Congele las líneas base de: advertencias, cobertura, complejidad, duplicación, código muerto y tamaño de archivo. Resultado: a partir de aquí, el código base solo puede mejorar.

Fase 2 — Profundidad del análisis estático (semana 3)

Sección titulada «Fase 2 — Profundidad del análisis estático (semana 3)»

SAST (CodeQL/Sonar/semgrep) con trinquete de alertas; escáner de secretos (herede el conjunto de reglas predeterminado); SCA (osv/Dependabot) + lista de licencias permitidas + lockfile-lint. Resultado: las vulnerabilidades conocidas y los secretos filtrados no pasan.

Fase 3 — Cadena de suministro de compilación (semana 4)

Sección titulada «Fase 3 — Cadena de suministro de compilación (semana 4)»

SBOM al publicar + procedencia firmada (SLSA L2) + Scorecard programado + refuerzo de los workflows (zizmor: permisos mínimos de tokens, sin credenciales persistentes y acciones ancladas a versiones específicas). Resultado: versiones trazables y a prueba de manipulaciones.

Fase 4 — Intensidad de las pruebas (semanas 5–6)

Sección titulada «Fase 4 — Intensidad de las pruebas (semanas 5–6)»

Un segundo ejecutor si resulta útil; umbrales de cobertura por módulo para módulos críticos (anti-Goodhart); pruebas basadas en propiedades para lógica pura; pruebas de mutación nocturnas → cuando llegue la primera puntuación, convierta mutationScore en un trinquete. Resultado: la cobertura deja de ser una métrica de vanidad; las pruebas demuestran que detectan errores.

Fase 5 — Contratos y análisis dinámico (semana 7)

Sección titulada «Fase 5 — Contratos y análisis dinámico (semana 7)»

Si existe una API pública: oasdiff (cambios incompatibles, bloqueante) + schemathesis (fuzzing nocturno). DAST/equipo rojo nocturno según corresponda al dominio. Resultado: los contratos no se rompen silenciosamente.

Fase 6 — Antialucinaciones y dominio (semana 8)

Sección titulada «Fase 6 — Antialucinaciones y dominio (semana 8)»

Un control de coherencia por cada «verdad duplicada» del proyecto. Controles de modos de fallo específicos del dominio (para IA: equipo rojo contra inyección). Resultado: la degradación estructural y los fallos del dominio cuentan con una red de seguridad.

  • Ciclo consultivo→bloqueante para cada nuevo control.
  • stale-allowlist: cada supresión tiene una justificación + incidencia; se detectan las supresiones obsoletas.
  • evidence-gate: toda afirmación de éxito en una PR requiere pruebas (una prueba o prueba viva).
  • Revisión trimestral del ROI por control (elimine o retire la financiación a los que no resulten rentables; combate la fatiga).
  • Convierta las reglas estrictas de su proyecto en controles ejecutables.
  • Trinquete, no valor absoluto. Controle la ausencia de regresiones, no un número fijo (excepto los umbrales anti-cero).
  • Umbral absoluto y trinquete juntos. El umbral evita el colapso; el trinquete evita la erosión gradual.
  • Anti-Goodhart por diseño. Cada métrica objetivo necesita un contrapeso (cobertura ⇒ mutación + antienmascaramiento; umbrales por módulo para forzar las pruebas del código difícil).
  • Omisión controlada. La falta de infraestructura nunca bloquea; solo bloquean las regresiones reales.
  • dedicatedGate para métricas costosas. Las métricas que requieren un binario externo obtienen su propio script (con omisión), fuera del trinquete central síncrono.
  • Coloque el control donde se produce la fusión. No deje una brecha entre el control rápido y la fusión real (la lección de la separación de controles rápidos).
  • Pocos controles bloqueantes, bien elegidos. Sonar/DORA: demasiadas condiciones = fatiga. Prefiera controles consultivos + trinquete antes que un muro de controles bloqueantes.

Parte 5 — Mejoras recomendadas (priorizadas, compatibles)

Sección titulada «Parte 5 — Mejoras recomendadas (priorizadas, compatibles)»

P0 — mayor ROI, casi listo

  1. Ratchet de puntuación de mutación (después de que la primera ejecución nocturna de Stryker produzca valores). Antídoto clave contra el Goodhart de cobertura; ~90% completado.
  2. Cerrar el agujero restante de las verificaciones rápidas — promover la compilación de producción de quality.yml después de su semana de advertencia y seguir trasladando las verificaciones deterministas exclusivas de las PR de publicación a la ruta PR→publicación.
  3. Protección de ramas en main (configuración del propietario) — mejora Scorecard y cierra la brecha de DSOMM.

P1 — valioso 4. osv/oasdiff → bloqueantes con el alcance adecuado — osv solo para vulnerabilidades CRITICAL+corregibles (en dos pasos, como Trivy); oasdiff bloquea los cambios incompatibles. 5. require-tighten → bloqueante (fin del ciclo) — consolida las mejoras en las métricas. 6. Revisión de ROI/tiempo por verificación en ci-summary — identificar y eliminar verificaciones lentas o de poco valor.

P2 — rendimientos decrecientes 7. SLSA L3 — compilador hermético/reproducible (generador SLSA de GitHub) si se desea avanzar desde L2. 8. Configuración de CodeQL incluida en el repositorio + semgrep versionado — mayor control/reproducibilidad. 9. Pruebas de humo DAST por PR — subconjunto rápido de schemathesis/promptfoo en los endpoints de mayor riesgo (no solo cada noche). 10. Panel de inestabilidad + métricas DORA — garantizar que las verificaciones no estén reduciendo la velocidad.


Parte 6 — Lecciones concretas de publicación (verificaciones que añadir en la Fase 9)

Sección titulada «Parte 6 — Lecciones concretas de publicación (verificaciones que añadir en la Fase 9)»

Esta sección registra incidentes reales de cierres de publicaciones en los que faltaba una verificación, con evidencias concretas y la verificación propuesta. Cada elemento es un candidato para la Parte 5.

Lección de v3.8.27 (2026-06-17) — el «agujero de las verificaciones rápidas» permite que regresiones deterministas lleguen al día de publicación

Sección titulada «Lección de v3.8.27 (2026-06-17) — el «agujero de las verificaciones rápidas» permite que regresiones deterministas lleguen al día de publicación»

Qué ocurrió. Durante /generate-release de v3.8.27, la PR de publicación (release/v3.8.27 → main) fue la primera ejecución de la matriz completa de ci.yml en el ciclo integrado. Resultado: 12 fallos a la vez — 3 pruebas deterministas + ~9 fallos intermitentes/del entorno. Ninguno era una regresión activa del producto, pero todos pasaron inadvertidos porque las PR del ciclo entran en release/** mediante el Fast QG (quality.yml), que NO ejecuta el conjunto completo de pruebas unitarias, ni pr-test-policy (enmascaramiento de pruebas), ni el conjunto completo de pruebas de integración, ni la comprobación de paridad de esquemas. Los 3 deterministas fueron:

  1. Prueba desactualizada por un cambio en la interfaz de usuario — permissions modal switch buttons declare button type: #4034 añadió un cuarto interruptor (se mantuvo type="button" para a11y); el recuento === 3 de la prueba quedó desactualizado. El análisis estático debería haberlo detectado en la PR #4034.
  2. Prueba desactualizada por un cambio de empaquetado — findMissingArtifactPaths ... root runtime files: dist/http-method-guard.cjs pasó a ser una ruta requerida legítima; la lista esperada de la prueba quedó desactualizada.
  3. Divergencia por modularización con pérdida de datos (la más grave) — settings schemas accept ... unprefixed toggle: el updateSettingsSchema modularizado (schemas/settings.ts, creado por #3988) divergió del canónico (settingsSchemas.ts): 45 campos frente a 85 — 40 eliminados + 6 divergentes (qdrant*). Era código muerto (el entorno de ejecución usa el canónico), por lo que no hubo impacto real, pero solo una prueba de paridad escrita a mano lo detectó. #4030 restauró 16 eliminaciones análogas de #3988/#3993, pero esta pasó inadvertida.

Verificaciones propuestas (Fase 9):

  • G1 — Cerrar realmente el agujero de las verificaciones rápidas (amplía P0 #2). En quality.yml (PR→release/**), además de la comprobación de tipos + las pruebas afectadas, ejecutar pr-test-policy (enmascaramiento de pruebas) + el conjunto completo de pruebas unitarias deterministas (o, al menos, los archivos estáticos/de paridad, que son rápidos y no intermitentes). De esta manera, las pruebas desactualizadas y la eliminación de aserciones se detectan en la PR que las introduce, no el día de publicación. Mantener fuera las pruebas de integración/e2e (lentas/inestables), pero la capa determinista NO PUEDE permanecer únicamente en PR→main.
  • G2 — Verificación de paridad de modularización (NUEVA, no cubierta actualmente). Una comprobación que, para cada símbolo reexportado por un barrel modularizado (src/shared/validation/schemas/*, módulos de providerRegistry, etc.), compare la estructura (claves de z.object, entradas del registro) con la fuente canónica y falle si existe divergencia (campo eliminado/adicional). Habría detectado la eliminación de 40 campos de #3988 en esa misma PR. Generaliza las pruebas de paridad escritas a mano (que solo existen cuando alguien recordó escribirlas). Es barata: importa ambos elementos y compara Object.keys(shape).
  • G3 — Triaje determinista de fallos intermitentes (apoyo). Las pruebas de inicio de LiveWS y de combinación de integración/breaker fallan debido a tiempos de espera del servidor/fallos en cascada en CI (entorno), no por la lógica. Marcarlas como known-flaky (puestas en cuarentena con una incidencia) para que el estado rojo de la PR de publicación contenga solo señales reales, no ruido que enmascare regresiones deterministas entre medias.

Principio: la verificación debe ejecutarse donde ocurre la fusión (ya incluido en «Principios transversales»). El incidente de v3.8.27 demuestra que esto también se aplica a la capa de pruebas deterministas, no solo a lint/comprobación de tipos; de lo contrario, la deuda de pruebas desactualizadas + modularización con pérdida de datos solo aparece en PR→main, en bloque y en el peor momento.


Fuentes (mejores prácticas de la industria)

Sección titulada «Fuentes (mejores prácticas de la industria)»

Código fuente de OmniRoute (a58000c7685f)

HagiCode

HagiCode es un espacio de trabajo de programación con agentes, flujos estructurados, ejecución multiagente y vistas de Hero Dungeon.

Convierte ideas en software útil con un flujo de trabajo con agentes más inteligente, rápido y ameno.

Interfaz principal de HagiCode con tema claro
  • SmartLos flujos estructurados convierten la intención en un itinerario ejecutable desde la idea hasta la entrega.
  • EfficientLos flujos multiagente permiten avanzar en paralelo con la investigación, implementación y revisión.
  • FunHero Dungeon hace que las largas sesiones de programación sean visuales y colaborativas.
Visitar HagiCode