use god_graph::transformer::optimization::constraints::{DefectType, Severity, TopologyDefect};
use tokitai_operator::verify::support_matrix::{SupportStatus, TheorySupportMatrixRow};
use crate::BridgeError;
pub fn defect_to_non_claims_row(
defect: &TopologyDefect,
) -> Result<TheorySupportMatrixRow, BridgeError> {
let defect_kind = defect_kind_label(&defect.defect_type);
let severity = severity_label(defect.severity);
let description = if defect.description.is_empty() {
format!("{} @ node {}", defect_kind, defect.location)
} else {
defect.description.clone()
};
let suggested = defect
.suggested_fix
.clone()
.map(|f| format!(" suggested_fix={f}"));
let mut non_claims = vec![format!(
"{severity} {defect_kind}: {description}{}",
suggested.as_deref().unwrap_or("")
)];
non_claims.push(format!(
"god_graph CAD-LLM defect type={} at node {}",
defect_kind, defect.location
));
Ok(TheorySupportMatrixRow {
domain: "topology_defect".to_string(),
operator: defect_kind.to_string(),
theory_constraints: vec![format!("god_graph.cad_llm.{defect_kind}")],
theorem_packages: vec!["none".to_string()],
backend: "god_graph_cad_llm".to_string(),
backend_capability: format!(
"god_graph CAD-LLM defect detector; severity={severity}; location=node {}",
defect.location
),
lowering_rule_id: Some(format!("god_graph.cad_llm.{defect_kind}")),
support_status: SupportStatus::Unsupported,
fallback_mode: "no fallback; the defect is an observation, not a path".to_string(),
public_api: "src/transformer/optimization/constraints.rs (TopologyValidator)".to_string(),
tests: vec!["tests/cad_bridge.rs".to_string()],
non_claims,
})
}
fn defect_kind_label(kind: &DefectType) -> &'static str {
match kind {
DefectType::IsolatedNode => "isolated_node",
DefectType::DisconnectedComponent => "disconnected_component",
DefectType::UnexpectedCycle => "unexpected_cycle",
DefectType::MissingResidual => "missing_residual",
DefectType::UnbalancedAttention => "unbalanced_attention",
DefectType::BlockedGradientFlow => "blocked_gradient_flow",
DefectType::Custom(_) => "custom",
}
}
fn severity_label(s: Severity) -> &'static str {
match s {
Severity::Info => "info",
Severity::Warning => "warning",
Severity::Error => "error",
Severity::Critical => "critical",
}
}