Testing y calidad
ospec-workflow aplica Strict TDD a su propio desarrollo y ofrece una
política declarativa de quality gates que sdd-verify evalúa en los cambios
que gestiona. Este dominio cubre ambas capas: cómo se testea el propio
harness y cómo un proyecto que lo adopta puede declarar sus propias puertas
de calidad.
Cómo se testea el propio harness
Section titled “Cómo se testea el propio harness”- Runner: Node.js native test runner (
node --test), sin frameworks externos. - Comando único:
npm test→node scripts/check.js. - Cobertura: 20+ archivos
scripts/**/*.test.js(unitarios e integración) más los tests Go eninternal/hooks/*_test.goycmd/ospec-hooks/*_test.go. - Suite de evals golden:
scripts/evals/contiene escenarios reproducibles del orquestador (JSON de input/output esperado) y un benchmark O2 para regresión continua. Los fixtures cubren rutas comohigh-risk-clarify-route,vague-request-no-artifact,apply-design-mismatch-blocked,document-batched-gateyverify-fail-spec-gap-routes-sdd-spec.
scripts/check.js es el comando único de verificación local y CI: ejecuta la
suite de tests, genera y valida los tres targets no-canónicos (claude,
github-copilot, opencode) contra sus validadores, y sondea si el CLI
externo claude está disponible — si no lo está, valida solo la generación
(ejercita la transformación) sin el gate estricto de claude plugin validate.
flowchart TD
A[npm test] --> B[node scripts/check.js]
B --> C["Suite de tests<br/>node --test scripts/**/*.test.js"]
B --> D[Genera dist/claude, dist/github-copilot, dist/opencode]
D --> E{claude CLI disponible?}
E -->|sí| F[claude plugin validate --strict]
E -->|no| G[Solo validación de generación]
D --> H[validate-github-copilot.js]
D --> I[validate-opencode.js]
Strict TDD en el propio repositorio
Section titled “Strict TDD en el propio repositorio”El hook pre-commit (ver Guardrails de seguridad)
hace cumplir la paridad código/test localmente: si hay código de producción
staged (internal/**/*.go, scripts/hooks/*.js, etc.) sin un test
correspondiente (*_test.go, *.test.js) o sin tasks.md del cambio activo
staged, el commit se bloquea.
Quality gates declarativos para proyectos adoptantes (sdd-verify)
Section titled “Quality gates declarativos para proyectos adoptantes (sdd-verify)”openspec/config.yaml soporta una clave opcional quality_gates: con cuatro
slots tipados: tests, lint, architecture, security. La ausencia de
este bloque es un no-op estricto — el comportamiento de verify es idéntico
al baseline previo a esta funcionalidad.
| Campo | Tipo | Default | Descripción |
|---|---|---|---|
{gate}.required | boolean | false | Si el fallo del gate afecta el resultado de verificación |
{gate}.command | string | ausente | Comando shell a ejecutar; ausente = se salta con advertencia |
{gate}.on_fail | advisory | halt | advisory | Enforcement cuando required: true y el gate falla |
tests.coverage.minimum | integer 0–100 | ausente | Piso de cobertura; ausente = sin chequeo de cobertura |
tests.coverage.command | string | ausente | Comando cuyo stdout es el % de cobertura |
Claves de gate desconocidas se ignoran silenciosamente (forward-compat).
Semántica de evaluación por gate
Section titled “Semántica de evaluación por gate”- Si
commandestá ausente/vacío → estado skipped. - Ejecuta el
commandconfigurado. Exit code 0 → pass; no-cero → fail. - Para
tests: sicoverage.minimumestá definido, corretests.coverage.commandy parsea su stdout como porcentaje. Por debajo del mínimo → fail, independientemente del exit code del comando principal. Sitests.coverage.commandestá ausente → se salta con advertencia, nunca hace fallar el gate. sdd-verifyDEBE evaluar todos los gates declarados antes de aplicar cualquier enforcement — fail-fast dentro del loop de gates está prohibido.on_fail: advisory(default) registra un hallazgo WARNING sin bloquear archive;on_fail: haltregistra un BLOCKER que bloquea archive hasta resolverse o anularse explícitamente.
Módulos de revisión 4R selectiva
Section titled “Módulos de revisión 4R selectiva”El sistema de revisión introduce tres módulos puros (sin IO) testeados bajo Strict TDD:
| Módulo | Responsabilidad |
|---|---|
review-dimensions.js | Normaliza la evidencia del diff (facts, signals, capabilities), calcula un fingerprint SHA-256 y deriva qué dimensiones 4R (risk, reliability, resilience, readability) aplican para el cambio. |
review-gate-state.js | Gestiona el estado de la compuerta: consume la decisión del generalista, produce el resultado ejecutable (next_action) y adapta la selección de especialistas. |
review-lineage.js | Congela el linaje de revisión: candidato inmutable, genesis paths, IDs de findings, presupuesto de líneas (min(200, ceil(changed_lines/2))). Cada lente se ejecuta una sola vez; tres validaciones fallidas agotan el linaje. |
Tres tests suite contratos en: scripts/review-dimensions.test.js, scripts/review-gate-state.test.js, scripts/review-lineage.test.js, scripts/selective-4r-parity.test.js.
Ver también Lint de Contratos y Reglas de Validación, que resume cómo este pipeline se aplica como regla de validación dentro del contract lint.
Por qué la arquitectura está diseñada así
Section titled “Por qué la arquitectura está diseñada así”Que quality_gates: sea estrictamente opt-in y no-op en ausencia evita
romper proyectos que adoptan ospec-workflow sin configurar nada extra. Que
sdd-verify evalúe todos los gates antes de aplicar enforcement da al
usuario visibilidad completa del estado de calidad en un solo reporte, en vez
de detenerse en el primer fallo y ocultar el resto.
Principales puntos de extensión
Section titled “Principales puntos de extensión”- Declarar quality gates en un proyecto: descomentar y completar el bloque
quality_gates:enopenspec/config.yaml(ver el bloque comentado de referencia al final del archivo). - Agregar un nuevo slot de gate: requiere un cambio de spec explícito (los
cuatro slots actuales son el contrato reconocido; nuevas claves a nivel
quality_gates:se ignoran hasta que se documenten).
Cosas a vigilar al editar
Section titled “Cosas a vigilar al editar”- No asumas que
on_failbloquea por defecto — el default es siempreadvisoryincluso sirequired: true; hace falta declararon_fail: haltexplícitamente. - Un stdout de cobertura fuera de rango (no 0–100) se trata como skip-with-warning, nunca se clampa.
scripts/check.jsno falla si el CLIclaudeno está instalado — solo reduce el alcance de validación del target claude a generación pura.
Mapa de fuentes
Section titled “Mapa de fuentes”/openspec/specs/quality-gates/spec.md/scripts/check.js/package.json(scripttest)/skills/sdd-verify/SKILL.md/openspec/config.yaml(bloque comentadoquality_gates:)/scripts/evals/—git log:ddf50ae(benchmark O2),2bba33f(golden suite bloque 2.1)/scripts/lib/review-dimensions.js,/scripts/lib/review-gate-state.js,/scripts/lib/review-lineage.js/scripts/review-dimensions.test.js,/scripts/review-gate-state.test.js,/scripts/review-lineage.test.js/scripts/selective-4r-parity.test.js