async fn handle_gate(
path: &PathBuf,
min_score: f64,
fail_on_p0: bool,
config: &CudaTdgCommandConfig,
) -> Result<()> {
let analyzer_config = CudaSimdConfig {
min_score,
fail_on_p0,
..Default::default()
};
let analyzer = CudaSimdAnalyzer::with_config(analyzer_config);
let result = analyzer.analyze(path)?;
if report_if_unmeasured(&result, config)? {
return Err(anyhow!(
"Quality gate not evaluated: no analysable source files found under {}",
path.display()
));
}
let passes = analyzer.passes_quality_gate(&result);
let output = match config.format {
CudaTdgOutputFormat::Json => serde_json::to_string_pretty(&serde_json::json!({
"passes": passes,
"score": result.score.total,
"min_score": min_score,
"grade": result.score.grade.to_string(),
"gateway_passed": result.score.gateway_passed,
"p0_defects": result.defects.iter()
.filter(|d| d.defect_class.severity == DefectSeverity::P0Critical)
.count(),
}))?,
_ => format_gate_text(&result, passes, min_score),
};
write_output(&output, config)?;
if !passes {
return Err(anyhow!("Quality gate failed"));
}
Ok(())
}
fn format_gate_text(result: &CudaSimdTdgResult, passes: bool, min_score: f64) -> String {
let mut output = String::new();
output.push_str("CUDA-TDG Quality Gate\n");
output.push_str("=====================\n\n");
output.push_str(&format!(
"Score: {:.1}/100 (Grade: {})\n",
result.score.total, result.score.grade
));
output.push_str(&format!("Minimum Required: {:.1}\n", min_score));
output.push_str(&format!(
"Gateway (Falsifiability): {}\n",
if result.score.gateway_passed {
"PASSED"
} else {
"FAILED"
}
));
let p0_count = result
.defects
.iter()
.filter(|d| d.defect_class.severity == DefectSeverity::P0Critical)
.count();
output.push_str(&format!("P0 Critical Defects: {}\n\n", p0_count));
output.push_str(&format!(
"Result: {}\n",
if passes { "PASSED" } else { "FAILED" }
));
output
}
fn kaizen_metric(value: f64, unit: &str) -> String {
if value.is_finite() {
format!("{:.1}{}", value, unit)
} else {
"not measured".to_string()
}
}
fn kaizen_percentage(value: f64) -> String {
kaizen_metric(value * 100.0, "%")
}
async fn handle_kaizen(
path: &PathBuf,
since: Option<&str>,
config: &CudaTdgCommandConfig,
) -> Result<()> {
if let Some(since) = since {
eprintln!(
"Warning: --since {since} ignored — cuda-tdg kaizen reports no history-derived metrics"
);
}
let analyzer = CudaSimdAnalyzer::new();
let result = analyzer.analyze(path)?;
let output = match config.format {
CudaTdgOutputFormat::Json => serde_json::to_string_pretty(&result.kaizen)?,
CudaTdgOutputFormat::Markdown => format_kaizen_markdown(&result),
_ => format_kaizen_text(&result),
};
write_output(&output, config)?;
Ok(())
}
fn format_kaizen_markdown(result: &CudaSimdTdgResult) -> String {
let mut md = String::new();
md.push_str("# Kaizen Continuous Improvement Report\n\n");
md.push_str("## Metrics\n\n");
md.push_str(&format!(
"- **Tickets Resolved**: {}\n",
result.kaizen.tickets_resolved
));
md.push_str(&format!(
"- **Mean Time to Detect**: {}\n",
kaizen_metric(result.kaizen.mttd, " hours")
));
md.push_str(&format!(
"- **Mean Time to Fix**: {}\n",
kaizen_metric(result.kaizen.mttf, " hours")
));
md.push_str(&format!(
"- **Escape Rate**: {}\n",
kaizen_percentage(result.kaizen.escape_rate)
));
md.push_str(&format!(
"- **Regression Rate**: {}\n\n",
kaizen_percentage(result.kaizen.regression_rate)
));
if !result.kaizen.ticket_references.is_empty() {
md.push_str("## Ticket References\n\n");
for ticket in &result.kaizen.ticket_references {
md.push_str(&format!("- {}\n", ticket));
}
}
md
}
fn format_kaizen_text(result: &CudaSimdTdgResult) -> String {
let mut output = String::new();
output.push_str("Kaizen Continuous Improvement Report\n");
output.push_str("====================================\n\n");
output.push_str(&format!(
"Tickets Resolved: {}\n",
result.kaizen.tickets_resolved
));
output.push_str(&format!(
"Mean Time to Detect: {}\n",
kaizen_metric(result.kaizen.mttd, " hours")
));
output.push_str(&format!(
"Mean Time to Fix: {}\n",
kaizen_metric(result.kaizen.mttf, " hours")
));
output.push_str(&format!(
"Escape Rate: {}\n",
kaizen_percentage(result.kaizen.escape_rate)
));
output.push_str(&format!(
"Regression Rate: {}\n",
kaizen_percentage(result.kaizen.regression_rate)
));
output
}
#[cfg(test)]
mod kaizen_honesty_tests {
use super::*;
#[test]
fn test_unmeasured_kaizen_metrics_render_as_not_measured() {
assert_eq!(kaizen_metric(f64::NAN, " hours"), "not measured");
assert_eq!(kaizen_percentage(f64::NAN), "not measured");
assert_eq!(kaizen_metric(12.5, " hours"), "12.5 hours");
assert_eq!(kaizen_percentage(0.05), "5.0%");
}
#[test]
fn test_kaizen_report_does_not_quote_the_old_defaults() {
let dir = tempfile::TempDir::new().unwrap();
std::fs::write(dir.path().join("lib.rs"), "pub fn f() {}\n").unwrap();
let result = CudaSimdAnalyzer::new().analyze(dir.path()).unwrap();
let text = format_kaizen_text(&result);
assert!(
text.contains("Mean Time to Detect: not measured"),
"MTTD must not be a hardcoded estimate: {text}"
);
assert!(
text.contains("Escape Rate: not measured"),
"escape rate must not be a hardcoded estimate: {text}"
);
assert!(!text.contains("24.0 hours"), "{text}");
assert!(!text.contains("5.0%"), "{text}");
}
}
async fn handle_taxonomy(config: &CudaTdgCommandConfig) -> Result<()> {
let taxonomy = DefectTaxonomy::with_tauranta_patterns();
let output = match config.format {
CudaTdgOutputFormat::Json => {
let patterns: Vec<_> = taxonomy.all().collect();
serde_json::to_string_pretty(&patterns)?
}
CudaTdgOutputFormat::Markdown => format_taxonomy_markdown(&taxonomy),
_ => format_taxonomy_text(&taxonomy),
};
write_output(&output, config)?;
Ok(())
}
fn format_taxonomy_markdown(taxonomy: &DefectTaxonomy) -> String {
let mut md = String::new();
md.push_str("# Tauranta Fault Taxonomy\n\n");
md.push_str("## P0 Critical Defects\n\n");
md.push_str("| Ticket | Description | Detection | Status |\n");
md.push_str("|--------|-------------|-----------|--------|\n");
for defect in taxonomy.all() {
if defect.severity == DefectSeverity::P0Critical {
md.push_str(&format!(
"| {} | {} | {} | {} |\n",
defect.ticket_id,
defect.description,
defect.detection_method,
if defect.resolved { "Resolved" } else { "Open" }
));
}
}
md.push_str("\n## P1 Performance Defects\n\n");
md.push_str("| Ticket | Description | Detection | Status |\n");
md.push_str("|--------|-------------|-----------|--------|\n");
for defect in taxonomy.all() {
if defect.severity == DefectSeverity::P1Performance {
md.push_str(&format!(
"| {} | {} | {} | {} |\n",
defect.ticket_id,
defect.description,
defect.detection_method,
if defect.resolved { "Resolved" } else { "Open" }
));
}
}
md.push_str("\n## P2 Efficiency Defects\n\n");
md.push_str("| Ticket | Description | Detection | Status |\n");
md.push_str("|--------|-------------|-----------|--------|\n");
for defect in taxonomy.all() {
if defect.severity == DefectSeverity::P2Efficiency {
md.push_str(&format!(
"| {} | {} | {} | {} |\n",
defect.ticket_id,
defect.description,
defect.detection_method,
if defect.resolved { "Resolved" } else { "Open" }
));
}
}
md
}
fn format_taxonomy_text(taxonomy: &DefectTaxonomy) -> String {
let mut output = String::new();
output.push_str("Tauranta Fault Taxonomy\n");
output.push_str("=======================\n\n");
output.push_str("P0 Critical Defects:\n");
output.push_str("-------------------\n");
for defect in taxonomy.all() {
if defect.severity == DefectSeverity::P0Critical {
output.push_str(&format!(
" {} - {}\n Detection: {}\n",
defect.ticket_id, defect.description, defect.detection_method
));
}
}
output.push_str("\nP1 Performance Defects:\n");
output.push_str("-----------------------\n");
for defect in taxonomy.all() {
if defect.severity == DefectSeverity::P1Performance {
output.push_str(&format!(
" {} - {}\n Detection: {}\n",
defect.ticket_id, defect.description, defect.detection_method
));
}
}
output.push_str("\nP2 Efficiency Defects:\n");
output.push_str("----------------------\n");
for defect in taxonomy.all() {
if defect.severity == DefectSeverity::P2Efficiency {
output.push_str(&format!(
" {} - {}\n Detection: {}\n",
defect.ticket_id, defect.description, defect.detection_method
));
}
}
output
}