diff --git a/Cargo.toml b/Cargo.toml index 20ec79c..085ed43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -154,3 +154,7 @@ path = "examples/soluciones/chaos_testing_nivel_2.rs" [[example]] name = "chaos_testing_nivel_3" path = "examples/soluciones/chaos_testing_nivel_3.rs" + +[[example]] +name = "quality_strategy" +path = "examples/quality_strategy.rs" diff --git a/diagrams/10-estrategia-de-calidad.mmd b/diagrams/10-estrategia-de-calidad.mmd new file mode 100644 index 0000000..99587b9 --- /dev/null +++ b/diagrams/10-estrategia-de-calidad.mmd @@ -0,0 +1,10 @@ +flowchart TD + A[Riesgo de calidad] --> B[Elegir señal adecuada] + B --> C[Pruebas locales y de integración] + B --> D[CI y revisión] + B --> E[Observabilidad operativa] + C --> F[Aprendizaje de regresiones] + D --> F + E --> F + F --> G[Criterio humano y siguiente decisión] + G --> A diff --git a/docs/10-estrategia-de-calidad-para-sistemas-reales.md b/docs/10-estrategia-de-calidad-para-sistemas-reales.md index 3d05d59..cad4f93 100644 --- a/docs/10-estrategia-de-calidad-para-sistemas-reales.md +++ b/docs/10-estrategia-de-calidad-para-sistemas-reales.md @@ -46,4 +46,73 @@ los conceptos del curso en una forma de decidir, revisar y aprender. El modelo representará una señal, el riesgo que reduce y sus límites, sin agregar dependencias externas. +## Teoría + +Una estrategia sana no pregunta cuál técnica es la mejor en abstracto. Pregunta +qué riesgo importa ahora y qué señal puede reducir la incertidumbre con menor +costo. Las técnicas se complementan: una prueba local no observa producción; +una alerta no explica por sí sola la intención; una revisión no sustituye una +regresión ejecutable. + +La retroalimentación completa forma un ciclo. Incidentes y observabilidad +generan nuevas hipótesis; esas hipótesis se convierten en pruebas, contratos, +guardas de CI o decisiones de diseño revisables por personas. + +## Diagrama + +```mermaid +flowchart TD + A[Riesgo de calidad] --> B[Elegir señal adecuada] + B --> C[Pruebas locales y de integración] + B --> D[CI y revisión] + B --> E[Observabilidad operativa] + C --> F[Aprendizaje de regresiones] + D --> F + E --> F + F --> G[Criterio humano y siguiente decisión] + G --> A +``` + +El archivo fuente vive en `diagrams/10-estrategia-de-calidad.mmd`. + +## Complejidad + +Una estrategia puede degradarse por duplicar señales que responden la misma +pregunta o por dejar sin dueño los riesgos operativos. El modelo no calcula una +calificación global: obliga a nombrar decisión, señal y límite antes de sumar +más automatización. + +## Implementación + +`StrategyDecision` en `src/quality_strategy.rs` relaciona una decisión con su +fuente de señal y el riesgo que reduce. También registra huecos como tratar una +automatización como aprobación humana. + +## Pruebas + +El módulo incluye pruebas unitarias, un consumidor externo y un doctest para +su API pública. + +## Benchmarks + +No hay benchmark propio. El modelo clasifica decisiones de calidad y medirlo +no representa la salud de un sistema. `cargo bench --all-targets` se conserva +como verificación de ruta. + +## Ejemplos + +```bash +cargo run --example quality_strategy +``` + +## Ejercicios + +Los ejercicios y soluciones graduadas se agregan al cerrar el capítulo. + +## Referencias internas + +- RFC-0001 §13: Rust como núcleo técnico. +- RFC-0001 §14: anatomía de cursos y capítulos. +- RFC-0001 §20: revisión humana diferida. + No está marcado como `reviewed` ni `published`. diff --git a/examples/quality_strategy.rs b/examples/quality_strategy.rs new file mode 100644 index 0000000..a6f686c --- /dev/null +++ b/examples/quality_strategy.rs @@ -0,0 +1,24 @@ +use rust_testing::quality_strategy::{QualityRisk, QualitySignal, StrategyDecision, StrategyGap}; +fn main() -> Result<(), rust_testing::quality_strategy::StrategyError> { + for d in [ + StrategyDecision::new( + "protege invariantes de precio", + QualitySignal::LocalTest, + QualityRisk::LocalRegression, + )?, + StrategyDecision::new( + "observa errores reales", + QualitySignal::Observability, + QualityRisk::ProductionBehavior, + )?, + StrategyDecision::new( + "aprueba cambio", + QualitySignal::ContinuousIntegration, + QualityRisk::KnownRegression, + )? + .with_gap(StrategyGap::AutomationAsApproval), + ] { + println!("{} => {:?}", d.decision(), d.signal()); + } + Ok(()) +}