{
    "sourceFile": "tests/validation_framework.rs",
    "activeCommit": 0,
    "commits": [
        {
            "activePatchIndex": 2,
            "patches": [
                {
                    "date": 1760243825129,
                    "content": "Index: \n===================================================================\n--- \n+++ \n"
                },
                {
                    "date": 1760251604317,
                    "content": "Index: \n===================================================================\n--- \n+++ \n@@ -0,0 +1,615 @@\n+//! LLM Output Validation Framework\n+//!\n+//! This module provides comprehensive testing and scoring for LLM-generated content\n+//! across all ggen AI commands. It simulates real user behavior and evaluates output\n+//! quality on a 0-10 scale with detailed feedback.\n+\n+use serde::{Deserialize, Serialize};\n+use std::collections::HashMap;\n+\n+/// Scoring dimensions for LLM output quality\n+#[derive(Debug, Clone, Serialize, Deserialize)]\n+pub struct QualityScore {\n+    /// Overall score (0-10)\n+    pub total: f32,\n+    /// Individual dimension scores\n+    pub dimensions: HashMap<String, DimensionScore>,\n+    /// Actionable feedback for improvement\n+    pub feedback: Vec<String>,\n+    /// Test metadata\n+    pub metadata: TestMetadata,\n+}\n+\n+/// Individual scoring dimension\n+#[derive(Debug, Clone, Serialize, Deserialize)]\n+pub struct DimensionScore {\n+    /// Score for this dimension (0-10)\n+    pub score: f32,\n+    /// Weight in overall score\n+    pub weight: f32,\n+    /// Description of what was evaluated\n+    pub description: String,\n+    /// Specific issues found\n+    pub issues: Vec<String>,\n+    /// Suggestions for improvement\n+    pub suggestions: Vec<String>,\n+}\n+\n+/// Test metadata\n+#[derive(Debug, Clone, Serialize, Deserialize)]\n+pub struct TestMetadata {\n+    pub command: String,\n+    pub scenario: String,\n+    pub timestamp: String,\n+    pub model: String,\n+    pub execution_time_ms: u64,\n+}\n+\n+/// User behavior simulation scenarios\n+#[derive(Debug, Clone)]\n+#[allow(dead_code)]\n+pub struct UserScenario {\n+    pub name: String,\n+    pub description: String,\n+    pub command: String,\n+    pub args: Vec<String>,\n+    pub expected_behavior: ExpectedBehavior,\n+}\n+\n+/// Expected behavior for validation\n+#[derive(Debug, Clone)]\n+#[allow(dead_code)]\n+pub struct ExpectedBehavior {\n+    pub min_length: usize,\n+    pub max_length: usize,\n+    pub required_patterns: Vec<String>,\n+    pub forbidden_patterns: Vec<String>,\n+    pub quality_criteria: Vec<QualityCriterion>,\n+}\n+\n+/// Quality criterion for evaluation\n+#[derive(Debug, Clone)]\n+#[allow(dead_code)]\n+pub struct QualityCriterion {\n+    pub name: String,\n+    pub description: String,\n+    pub weight: f32,\n+    pub validator: fn(&str) -> (f32, Vec<String>),\n+}\n+\n+/// Validation framework\n+pub struct ValidationFramework {\n+    scenarios: Vec<UserScenario>,\n+}\n+\n+impl Default for ValidationFramework {\n+    fn default() -> Self {\n+        Self::new()\n+    }\n+}\n+\n+impl ValidationFramework {\n+    /// Create new validation framework with predefined scenarios\n+    pub fn new() -> Self {\n+        Self {\n+            scenarios: Self::create_user_scenarios(),\n+        }\n+    }\n+\n+    /// Create realistic user behavior scenarios\n+    fn create_user_scenarios() -> Vec<UserScenario> {\n+        vec![\n+            // Scenario 1: Simple template generation\n+            UserScenario {\n+                name: \"simple_template\".to_string(),\n+                description: \"User wants a basic hello world template\".to_string(),\n+                command: \"ai generate\".to_string(),\n+                args: vec![\n+                    \"--description\".to_string(),\n+                    \"Create a simple hello world web page with HTML and CSS\".to_string(),\n+                    \"--max-tokens\".to_string(),\n+                    \"500\".to_string(),\n+                ],\n+                expected_behavior: ExpectedBehavior {\n+                    min_length: 100,\n+                    max_length: 2000,\n+                    required_patterns: vec![\"html\".to_string(), \"hello\".to_string()],\n+                    forbidden_patterns: vec![\"error\".to_string(), \"undefined\".to_string()],\n+                    quality_criteria: vec![\n+                        QualityCriterion {\n+                            name: \"structure\".to_string(),\n+                            description: \"Has proper structure and formatting\".to_string(),\n+                            weight: 0.3,\n+                            validator: validate_structure,\n+                        },\n+                        QualityCriterion {\n+                            name: \"completeness\".to_string(),\n+                            description: \"Contains all requested elements\".to_string(),\n+                            weight: 0.3,\n+                            validator: validate_completeness,\n+                        },\n+                        QualityCriterion {\n+                            name: \"usability\".to_string(),\n+                            description: \"Code is ready to use without modification\".to_string(),\n+                            weight: 0.2,\n+                            validator: validate_usability,\n+                        },\n+                        QualityCriterion {\n+                            name: \"clarity\".to_string(),\n+                            description: \"Code is well-commented and clear\".to_string(),\n+                            weight: 0.2,\n+                            validator: validate_clarity,\n+                        },\n+                    ],\n+                },\n+            },\n+            // Scenario 2: Complex SPARQL query\n+            UserScenario {\n+                name: \"complex_sparql\".to_string(),\n+                description: \"User needs a SPARQL query for data analysis\".to_string(),\n+                command: \"ai sparql\".to_string(),\n+                args: vec![\n+                    \"--description\".to_string(),\n+                    \"Find all users with age > 18 who have made purchases in the last 30 days\"\n+                        .to_string(),\n+                    \"--max-tokens\".to_string(),\n+                    \"300\".to_string(),\n+                ],\n+                expected_behavior: ExpectedBehavior {\n+                    min_length: 50,\n+                    max_length: 1000,\n+                    required_patterns: vec![\n+                        \"SELECT\".to_string(),\n+                        \"WHERE\".to_string(),\n+                        \"FILTER\".to_string(),\n+                    ],\n+                    forbidden_patterns: vec![\"syntax error\".to_string()],\n+                    quality_criteria: vec![\n+                        QualityCriterion {\n+                            name: \"correctness\".to_string(),\n+                            description: \"SPARQL syntax is valid\".to_string(),\n+                            weight: 0.4,\n+                            validator: validate_sparql_syntax,\n+                        },\n+                        QualityCriterion {\n+                            name: \"efficiency\".to_string(),\n+                            description: \"Query is optimized\".to_string(),\n+                            weight: 0.3,\n+                            validator: validate_query_efficiency,\n+                        },\n+                        QualityCriterion {\n+                            name: \"readability\".to_string(),\n+                            description: \"Query is formatted well\".to_string(),\n+                            weight: 0.3,\n+                            validator: validate_readability,\n+                        },\n+                    ],\n+                },\n+            },\n+            // Scenario 3: Frontmatter generation\n+            UserScenario {\n+                name: \"blog_frontmatter\".to_string(),\n+                description: \"User needs frontmatter for a blog post\".to_string(),\n+                command: \"ai frontmatter\".to_string(),\n+                args: vec![\n+                    \"--description\".to_string(),\n+                    \"Blog post about AI ethics with SEO optimization\".to_string(),\n+                    \"--max-tokens\".to_string(),\n+                    \"200\".to_string(),\n+                ],\n+                expected_behavior: ExpectedBehavior {\n+                    min_length: 50,\n+                    max_length: 800,\n+                    required_patterns: vec![\"title\".to_string(), \"description\".to_string()],\n+                    forbidden_patterns: vec![],\n+                    quality_criteria: vec![\n+                        QualityCriterion {\n+                            name: \"seo_quality\".to_string(),\n+                            description: \"Contains proper SEO metadata\".to_string(),\n+                            weight: 0.4,\n+                            validator: validate_seo,\n+                        },\n+                        QualityCriterion {\n+                            name: \"completeness\".to_string(),\n+                            description: \"All standard fields present\".to_string(),\n+                            weight: 0.3,\n+                            validator: validate_frontmatter_completeness,\n+                        },\n+                        QualityCriterion {\n+                            name: \"validity\".to_string(),\n+                            description: \"Valid YAML format\".to_string(),\n+                            weight: 0.3,\n+                            validator: validate_yaml,\n+                        },\n+                    ],\n+                },\n+            },\n+            // Scenario 4: RDF graph generation\n+            UserScenario {\n+                name: \"ontology_graph\".to_string(),\n+                description: \"User wants an RDF ontology for a specific domain\".to_string(),\n+                command: \"ai graph\".to_string(),\n+                args: vec![\n+                    \"--description\".to_string(),\n+                    \"E-commerce product catalog with categories and pricing\".to_string(),\n+                    \"--include-examples\".to_string(),\n+                    \"--max-tokens\".to_string(),\n+                    \"400\".to_string(),\n+                ],\n+                expected_behavior: ExpectedBehavior {\n+                    min_length: 100,\n+                    max_length: 2000,\n+                    required_patterns: vec![\"@prefix\".to_string(), \"owl:Class\".to_string()],\n+                    forbidden_patterns: vec![\"syntax error\".to_string()],\n+                    quality_criteria: vec![\n+                        QualityCriterion {\n+                            name: \"ontology_quality\".to_string(),\n+                            description: \"Well-structured ontology\".to_string(),\n+                            weight: 0.4,\n+                            validator: validate_ontology,\n+                        },\n+                        QualityCriterion {\n+                            name: \"examples\".to_string(),\n+                            description: \"Contains useful examples\".to_string(),\n+                            weight: 0.3,\n+                            validator: validate_examples,\n+                        },\n+                        QualityCriterion {\n+                            name: \"turtle_validity\".to_string(),\n+                            description: \"Valid Turtle syntax\".to_string(),\n+                            weight: 0.3,\n+                            validator: validate_turtle,\n+                        },\n+                    ],\n+                },\n+            },\n+        ]\n+    }\n+\n+    /// Run all validation scenarios\n+    #[allow(dead_code)]\n+    pub fn run_all_scenarios(&self) -> Vec<QualityScore> {\n+        self.scenarios\n+            .iter()\n+            .map(|scenario| self.run_scenario(scenario))\n+            .collect()\n+    }\n+\n+    /// Run a single validation scenario\n+    #[allow(dead_code)]\n+    pub fn run_scenario(&self, scenario: &UserScenario) -> QualityScore {\n+        // Execute command and capture output\n+        let output = self.execute_command(scenario);\n+\n+        // Score the output\n+        self.score_output(&output, scenario)\n+    }\n+\n+    /// Execute command and capture output\n+    #[allow(dead_code)]\n+    fn execute_command(&self, scenario: &UserScenario) -> String {\n+        // This would actually run the command - placeholder for now\n+        format!(\"Output from {}\", scenario.command)\n+    }\n+\n+    /// Score output against expected behavior\n+    #[allow(dead_code)]\n+    fn score_output(&self, output: &str, scenario: &UserScenario) -> QualityScore {\n+        let mut dimension_scores = HashMap::new();\n+        let mut total_weighted_score = 0.0;\n+        let mut total_weight = 0.0;\n+        let mut all_feedback = Vec::new();\n+\n+        // Score each quality criterion\n+        for criterion in &scenario.expected_behavior.quality_criteria {\n+            let (score, issues) = (criterion.validator)(output);\n+\n+            total_weighted_score += score * criterion.weight;\n+            total_weight += criterion.weight;\n+\n+            let suggestions = self.generate_suggestions(&criterion.name, score, &issues);\n+            all_feedback.extend(suggestions.clone());\n+\n+            dimension_scores.insert(\n+                criterion.name.clone(),\n+                DimensionScore {\n+                    score,\n+                    weight: criterion.weight,\n+                    description: criterion.description.clone(),\n+                    issues,\n+                    suggestions,\n+                },\n+            );\n+        }\n+\n+        // Calculate final score\n+        let total = if total_weight > 0.0 {\n+            total_weighted_score / total_weight\n+        } else {\n+            0.0\n+        };\n+\n+        QualityScore {\n+            total,\n+            dimensions: dimension_scores,\n+            feedback: all_feedback,\n+            metadata: TestMetadata {\n+                command: scenario.command.clone(),\n+                scenario: scenario.name.clone(),\n+                timestamp: chrono::Utc::now().to_rfc3339(),\n+                model: \"qwen3-coder:30b\".to_string(),\n+                execution_time_ms: 0,\n+            },\n+        }\n+    }\n+\n+    /// Generate improvement suggestions based on score\n+    #[allow(dead_code)]\n+    fn generate_suggestions(&self, dimension: &str, score: f32, issues: &[String]) -> Vec<String> {\n+        let mut suggestions = Vec::new();\n+\n+        if score < 7.0 {\n+            match dimension {\n+                \"structure\" => suggestions\n+                    .push(\"Consider adding more semantic structure and proper nesting\".to_string()),\n+                \"completeness\" => suggestions\n+                    .push(\"Ensure all requested elements are included in the output\".to_string()),\n+                \"usability\" => {\n+                    suggestions.push(\"Add more examples and usage documentation\".to_string())\n+                }\n+                \"clarity\" => {\n+                    suggestions.push(\"Improve code comments and variable naming\".to_string())\n+                }\n+                \"correctness\" => {\n+                    suggestions.push(\"Review syntax and semantic correctness\".to_string())\n+                }\n+                \"efficiency\" => suggestions.push(\"Optimize for better performance\".to_string()),\n+                \"readability\" => {\n+                    suggestions.push(\"Improve formatting and organization\".to_string())\n+                }\n+                \"seo_quality\" => {\n+                    suggestions.push(\"Add meta tags, keywords, and descriptions\".to_string())\n+                }\n+                \"ontology_quality\" => {\n+                    suggestions.push(\"Add more relationships and properties\".to_string())\n+                }\n+                _ => suggestions.push(format!(\"Improve {} quality\", dimension)),\n+            }\n+        }\n+\n+        // Add issue-specific suggestions\n+        for issue in issues {\n+            suggestions.push(format!(\"Fix: {}\", issue));\n+        }\n+\n+        suggestions\n+    }\n+\n+    /// Generate comprehensive report\n+    #[allow(dead_code)]\n+    pub fn generate_report(&self, scores: &[QualityScore]) -> String {\n+        let mut report = String::new();\n+\n+        report.push_str(\"# LLM Output Validation Report\\n\\n\");\n+        report.push_str(&format!(\n+            \"Generated: {}\\n\\n\",\n+            chrono::Utc::now().to_rfc3339()\n+        ));\n+\n+        // Overall statistics\n+        let avg_score: f32 = scores.iter().map(|s| s.total).sum::<f32>() / scores.len() as f32;\n+        report.push_str(\"## Overall Statistics\\n\\n\");\n+        report.push_str(&format!(\"- **Average Score**: {:.2}/10\\n\", avg_score));\n+        report.push_str(&format!(\"- **Tests Run**: {}\\n\", scores.len()));\n+        report.push_str(\"- **Model**: qwen3-coder:30b\\n\\n\");\n+\n+        // Individual test results\n+        report.push_str(\"## Individual Test Results\\n\\n\");\n+        for score in scores {\n+            report.push_str(&format!(\n+                \"### {} (Score: {:.2}/10)\\n\\n\",\n+                score.metadata.scenario, score.total\n+            ));\n+            report.push_str(&format!(\"**Command**: `{}`\\n\\n\", score.metadata.command));\n+\n+            // Dimension scores\n+            report.push_str(\"#### Dimension Scores:\\n\\n\");\n+            for (name, dim) in &score.dimensions {\n+                report.push_str(&format!(\n+                    \"- **{}** ({:.1}/10, weight {:.0}%): {}\\n\",\n+                    name,\n+                    dim.score,\n+                    dim.weight * 100.0,\n+                    dim.description\n+                ));\n+                if !dim.issues.is_empty() {\n+                    report.push_str(\"  - Issues:\\n\");\n+                    for issue in &dim.issues {\n+                        report.push_str(&format!(\"    - {}\\n\", issue));\n+                    }\n+                }\n+            }\n+\n+            // Feedback\n+            if !score.feedback.is_empty() {\n+                report.push_str(\"\\n#### Improvement Suggestions:\\n\\n\");\n+                for feedback in &score.feedback {\n+                    report.push_str(&format!(\"- {}\\n\", feedback));\n+                }\n+            }\n+\n+            report.push_str(\"\\n---\\n\\n\");\n+        }\n+\n+        report\n+    }\n+}\n+\n+// Validator functions\n+\n+fn validate_structure(output: &str) -> (f32, Vec<String>) {\n+    let mut score: f32 = 10.0;\n+    let mut issues = Vec::new();\n+\n+    if output.len() < 50 {\n+        score -= 5.0;\n+        issues.push(\"Output too short\".to_string());\n+    }\n+\n+    if !output.contains('\\n') {\n+        score -= 2.0;\n+        issues.push(\"No line breaks - poor formatting\".to_string());\n+    }\n+\n+    (score.max(0.0f32), issues)\n+}\n+\n+fn validate_completeness(output: &str) -> (f32, Vec<String>) {\n+    let mut score: f32 = 10.0;\n+    let mut issues = Vec::new();\n+\n+    if output.is_empty() {\n+        score = 0.0;\n+        issues.push(\"Empty output\".to_string());\n+    }\n+\n+    (score, issues)\n+}\n+\n+fn validate_usability(output: &str) -> (f32, Vec<String>) {\n+    let mut score: f32 = 10.0;\n+    let mut issues = Vec::new();\n+\n+    if output.contains(\"TODO\") || output.contains(\"FIXME\") {\n+        score -= 3.0;\n+        issues.push(\"Contains TODO/FIXME markers\".to_string());\n+    }\n+\n+    (score.max(0.0f32), issues)\n+}\n+\n+fn validate_clarity(_output: &str) -> (f32, Vec<String>) {\n+    let score: f32 = 8.0; // Base score\n+    let issues = Vec::new();\n+    (score, issues)\n+}\n+\n+fn validate_sparql_syntax(output: &str) -> (f32, Vec<String>) {\n+    let mut score: f32 = 10.0;\n+    let mut issues = Vec::new();\n+\n+    let required_keywords = [\"SELECT\", \"WHERE\"];\n+    for keyword in required_keywords {\n+        if !output.to_uppercase().contains(keyword) {\n+            score -= 5.0;\n+            issues.push(format!(\"Missing required keyword: {}\", keyword));\n+        }\n+    }\n+\n+    (score.max(0.0f32), issues)\n+}\n+\n+fn validate_query_efficiency(_output: &str) -> (f32, Vec<String>) {\n+    let score: f32 = 8.0;\n+    let issues = Vec::new();\n+    (score, issues)\n+}\n+\n+fn validate_readability(output: &str) -> (f32, Vec<String>) {\n+    let mut score: f32 = 10.0;\n+    let mut issues = Vec::new();\n+\n+    if output.lines().count() < 3 {\n+        score -= 2.0;\n+        issues.push(\"Query is not well formatted\".to_string());\n+    }\n+\n+    (score.max(0.0f32), issues)\n+}\n+\n+fn validate_seo(output: &str) -> (f32, Vec<String>) {\n+    let mut score: f32 = 10.0;\n+    let mut issues = Vec::new();\n+\n+    let seo_fields = [\"title\", \"description\", \"keywords\"];\n+    for field in seo_fields {\n+        if !output.to_lowercase().contains(field) {\n+            score -= 2.0;\n+            issues.push(format!(\"Missing SEO field: {}\", field));\n+        }\n+    }\n+\n+    (score.max(0.0f32), issues)\n+}\n+\n+fn validate_frontmatter_completeness(_output: &str) -> (f32, Vec<String>) {\n+    let score: f32 = 8.0;\n+    let issues = Vec::new();\n+    (score, issues)\n+}\n+\n+fn validate_yaml(output: &str) -> (f32, Vec<String>) {\n+    let mut score: f32 = 10.0;\n+    let mut issues = Vec::new();\n+\n+    if !output.contains(':') {\n+        score -= 5.0;\n+        issues.push(\"Not valid YAML format\".to_string());\n+    }\n+\n+    (score.max(0.0f32), issues)\n+}\n+\n+fn validate_ontology(output: &str) -> (f32, Vec<String>) {\n+    let mut score: f32 = 10.0;\n+    let mut issues = Vec::new();\n+\n+    if !output.contains(\"owl:Class\") && !output.contains(\"rdfs:Class\") {\n+        score -= 5.0;\n+        issues.push(\"Missing class definitions\".to_string());\n+    }\n+\n+    (score.max(0.0f32), issues)\n+}\n+\n+fn validate_examples(_output: &str) -> (f32, Vec<String>) {\n+    let score: f32 = 7.0;\n+    let issues = Vec::new();\n+    (score, issues)\n+}\n+\n+fn validate_turtle(output: &str) -> (f32, Vec<String>) {\n+    let mut score: f32 = 10.0;\n+    let mut issues = Vec::new();\n+\n+    if !output.contains(\"@prefix\") {\n+        score -= 5.0;\n+        issues.push(\"Missing @prefix declarations\".to_string());\n+    }\n+\n+    (score.max(0.0f32), issues)\n+}\n+\n+#[cfg(test)]\n+mod tests {\n+    use super::*;\n+\n+    #[test]\n+    fn test_framework_creation() {\n+        let framework = ValidationFramework::new();\n+        assert!(!framework.scenarios.is_empty());\n+    }\n+\n+    #[test]\n+    fn test_structure_validation() {\n+        let (score, issues) = validate_structure(\"# Test\\n\\nContent here\");\n+        assert!(score > 5.0);\n+        assert!(issues.is_empty());\n+    }\n+\n+    #[test]\n+    fn test_sparql_validation() {\n+        let (score, _) = validate_sparql_syntax(\"SELECT ?s WHERE { ?s ?p ?o }\");\n+        assert!(score > 8.0);\n+    }\n+}\n"
                },
                {
                    "date": 1760251836380,
                    "content": "Index: \n===================================================================\n--- \n+++ \n@@ -612,604 +612,4 @@\n         let (score, _) = validate_sparql_syntax(\"SELECT ?s WHERE { ?s ?p ?o }\");\n         assert!(score > 8.0);\n     }\n }\n-//! LLM Output Validation Framework\n-//!\n-//! This module provides comprehensive testing and scoring for LLM-generated content\n-//! across all ggen AI commands. It simulates real user behavior and evaluates output\n-//! quality on a 0-10 scale with detailed feedback.\n-\n-use serde::{Deserialize, Serialize};\n-use std::collections::HashMap;\n-\n-/// Scoring dimensions for LLM output quality\n-#[derive(Debug, Clone, Serialize, Deserialize)]\n-pub struct QualityScore {\n-    /// Overall score (0-10)\n-    pub total: f32,\n-    /// Individual dimension scores\n-    pub dimensions: HashMap<String, DimensionScore>,\n-    /// Actionable feedback for improvement\n-    pub feedback: Vec<String>,\n-    /// Test metadata\n-    pub metadata: TestMetadata,\n-}\n-\n-/// Individual scoring dimension\n-#[derive(Debug, Clone, Serialize, Deserialize)]\n-pub struct DimensionScore {\n-    /// Score for this dimension (0-10)\n-    pub score: f32,\n-    /// Weight in overall score\n-    pub weight: f32,\n-    /// Description of what was evaluated\n-    pub description: String,\n-    /// Specific issues found\n-    pub issues: Vec<String>,\n-    /// Suggestions for improvement\n-    pub suggestions: Vec<String>,\n-}\n-\n-/// Test metadata\n-#[derive(Debug, Clone, Serialize, Deserialize)]\n-pub struct TestMetadata {\n-    pub command: String,\n-    pub scenario: String,\n-    pub timestamp: String,\n-    pub model: String,\n-    pub execution_time_ms: u64,\n-}\n-\n-/// User behavior simulation scenarios\n-#[derive(Debug, Clone)]\n-pub struct UserScenario {\n-    pub name: String,\n-    pub description: String,\n-    pub command: String,\n-    pub args: Vec<String>,\n-    pub expected_behavior: ExpectedBehavior,\n-}\n-\n-/// Expected behavior for validation\n-#[derive(Debug, Clone)]\n-pub struct ExpectedBehavior {\n-    pub min_length: usize,\n-    pub max_length: usize,\n-    pub required_patterns: Vec<String>,\n-    pub forbidden_patterns: Vec<String>,\n-    pub quality_criteria: Vec<QualityCriterion>,\n-}\n-\n-/// Quality criterion for evaluation\n-#[derive(Debug, Clone)]\n-pub struct QualityCriterion {\n-    pub name: String,\n-    pub description: String,\n-    pub weight: f32,\n-    pub validator: fn(&str) -> (f32, Vec<String>),\n-}\n-\n-/// Validation framework\n-pub struct ValidationFramework {\n-    scenarios: Vec<UserScenario>,\n-}\n-\n-impl ValidationFramework {\n-    /// Create new validation framework with predefined scenarios\n-    pub fn new() -> Self {\n-        Self {\n-            scenarios: Self::create_user_scenarios(),\n-        }\n-    }\n-\n-    /// Create realistic user behavior scenarios\n-    fn create_user_scenarios() -> Vec<UserScenario> {\n-        vec![\n-            // Scenario 1: Simple template generation\n-            UserScenario {\n-                name: \"simple_template\".to_string(),\n-                description: \"User wants a basic hello world template\".to_string(),\n-                command: \"ai generate\".to_string(),\n-                args: vec![\n-                    \"--description\".to_string(),\n-                    \"Create a simple hello world web page with HTML and CSS\".to_string(),\n-                    \"--max-tokens\".to_string(),\n-                    \"500\".to_string(),\n-                ],\n-                expected_behavior: ExpectedBehavior {\n-                    min_length: 100,\n-                    max_length: 2000,\n-                    required_patterns: vec![\"html\".to_string(), \"hello\".to_string()],\n-                    forbidden_patterns: vec![\"error\".to_string(), \"undefined\".to_string()],\n-                    quality_criteria: vec![\n-                        QualityCriterion {\n-                            name: \"structure\".to_string(),\n-                            description: \"Has proper structure and formatting\".to_string(),\n-                            weight: 0.3,\n-                            validator: validate_structure,\n-                        },\n-                        QualityCriterion {\n-                            name: \"completeness\".to_string(),\n-                            description: \"Contains all requested elements\".to_string(),\n-                            weight: 0.3,\n-                            validator: validate_completeness,\n-                        },\n-                        QualityCriterion {\n-                            name: \"usability\".to_string(),\n-                            description: \"Code is ready to use without modification\".to_string(),\n-                            weight: 0.2,\n-                            validator: validate_usability,\n-                        },\n-                        QualityCriterion {\n-                            name: \"clarity\".to_string(),\n-                            description: \"Code is well-commented and clear\".to_string(),\n-                            weight: 0.2,\n-                            validator: validate_clarity,\n-                        },\n-                    ],\n-                },\n-            },\n-            // Scenario 2: Complex SPARQL query\n-            UserScenario {\n-                name: \"complex_sparql\".to_string(),\n-                description: \"User needs a SPARQL query for data analysis\".to_string(),\n-                command: \"ai sparql\".to_string(),\n-                args: vec![\n-                    \"--description\".to_string(),\n-                    \"Find all users with age > 18 who have made purchases in the last 30 days\"\n-                        .to_string(),\n-                    \"--max-tokens\".to_string(),\n-                    \"300\".to_string(),\n-                ],\n-                expected_behavior: ExpectedBehavior {\n-                    min_length: 50,\n-                    max_length: 1000,\n-                    required_patterns: vec![\n-                        \"SELECT\".to_string(),\n-                        \"WHERE\".to_string(),\n-                        \"FILTER\".to_string(),\n-                    ],\n-                    forbidden_patterns: vec![\"syntax error\".to_string()],\n-                    quality_criteria: vec![\n-                        QualityCriterion {\n-                            name: \"correctness\".to_string(),\n-                            description: \"SPARQL syntax is valid\".to_string(),\n-                            weight: 0.4,\n-                            validator: validate_sparql_syntax,\n-                        },\n-                        QualityCriterion {\n-                            name: \"efficiency\".to_string(),\n-                            description: \"Query is optimized\".to_string(),\n-                            weight: 0.3,\n-                            validator: validate_query_efficiency,\n-                        },\n-                        QualityCriterion {\n-                            name: \"readability\".to_string(),\n-                            description: \"Query is formatted well\".to_string(),\n-                            weight: 0.3,\n-                            validator: validate_readability,\n-                        },\n-                    ],\n-                },\n-            },\n-            // Scenario 3: Frontmatter generation\n-            UserScenario {\n-                name: \"blog_frontmatter\".to_string(),\n-                description: \"User needs frontmatter for a blog post\".to_string(),\n-                command: \"ai frontmatter\".to_string(),\n-                args: vec![\n-                    \"--description\".to_string(),\n-                    \"Blog post about AI ethics with SEO optimization\".to_string(),\n-                    \"--max-tokens\".to_string(),\n-                    \"200\".to_string(),\n-                ],\n-                expected_behavior: ExpectedBehavior {\n-                    min_length: 50,\n-                    max_length: 800,\n-                    required_patterns: vec![\"title\".to_string(), \"description\".to_string()],\n-                    forbidden_patterns: vec![],\n-                    quality_criteria: vec![\n-                        QualityCriterion {\n-                            name: \"seo_quality\".to_string(),\n-                            description: \"Contains proper SEO metadata\".to_string(),\n-                            weight: 0.4,\n-                            validator: validate_seo,\n-                        },\n-                        QualityCriterion {\n-                            name: \"completeness\".to_string(),\n-                            description: \"All standard fields present\".to_string(),\n-                            weight: 0.3,\n-                            validator: validate_frontmatter_completeness,\n-                        },\n-                        QualityCriterion {\n-                            name: \"validity\".to_string(),\n-                            description: \"Valid YAML format\".to_string(),\n-                            weight: 0.3,\n-                            validator: validate_yaml,\n-                        },\n-                    ],\n-                },\n-            },\n-            // Scenario 4: RDF graph generation\n-            UserScenario {\n-                name: \"ontology_graph\".to_string(),\n-                description: \"User wants an RDF ontology for a specific domain\".to_string(),\n-                command: \"ai graph\".to_string(),\n-                args: vec![\n-                    \"--description\".to_string(),\n-                    \"E-commerce product catalog with categories and pricing\".to_string(),\n-                    \"--include-examples\".to_string(),\n-                    \"--max-tokens\".to_string(),\n-                    \"400\".to_string(),\n-                ],\n-                expected_behavior: ExpectedBehavior {\n-                    min_length: 100,\n-                    max_length: 2000,\n-                    required_patterns: vec![\"@prefix\".to_string(), \"owl:Class\".to_string()],\n-                    forbidden_patterns: vec![\"syntax error\".to_string()],\n-                    quality_criteria: vec![\n-                        QualityCriterion {\n-                            name: \"ontology_quality\".to_string(),\n-                            description: \"Well-structured ontology\".to_string(),\n-                            weight: 0.4,\n-                            validator: validate_ontology,\n-                        },\n-                        QualityCriterion {\n-                            name: \"examples\".to_string(),\n-                            description: \"Contains useful examples\".to_string(),\n-                            weight: 0.3,\n-                            validator: validate_examples,\n-                        },\n-                        QualityCriterion {\n-                            name: \"turtle_validity\".to_string(),\n-                            description: \"Valid Turtle syntax\".to_string(),\n-                            weight: 0.3,\n-                            validator: validate_turtle,\n-                        },\n-                    ],\n-                },\n-            },\n-        ]\n-    }\n-\n-    /// Run all validation scenarios\n-    pub fn run_all_scenarios(&self) -> Vec<QualityScore> {\n-        self.scenarios\n-            .iter()\n-            .map(|scenario| self.run_scenario(scenario))\n-            .collect()\n-    }\n-\n-    /// Run a single validation scenario\n-    pub fn run_scenario(&self, scenario: &UserScenario) -> QualityScore {\n-        // Execute command and capture output\n-        let output = self.execute_command(scenario);\n-\n-        // Score the output\n-        self.score_output(&output, scenario)\n-    }\n-\n-    /// Execute command and capture output\n-    fn execute_command(&self, scenario: &UserScenario) -> String {\n-        // This would actually run the command - placeholder for now\n-        format!(\"Output from {}\", scenario.command)\n-    }\n-\n-    /// Score output against expected behavior\n-    fn score_output(&self, output: &str, scenario: &UserScenario) -> QualityScore {\n-        let mut dimension_scores = HashMap::new();\n-        let mut total_weighted_score = 0.0;\n-        let mut total_weight = 0.0;\n-        let mut all_feedback = Vec::new();\n-\n-        // Score each quality criterion\n-        for criterion in &scenario.expected_behavior.quality_criteria {\n-            let (score, issues) = (criterion.validator)(output);\n-\n-            total_weighted_score += score * criterion.weight;\n-            total_weight += criterion.weight;\n-\n-            let suggestions = self.generate_suggestions(&criterion.name, score, &issues);\n-            all_feedback.extend(suggestions.clone());\n-\n-            dimension_scores.insert(\n-                criterion.name.clone(),\n-                DimensionScore {\n-                    score,\n-                    weight: criterion.weight,\n-                    description: criterion.description.clone(),\n-                    issues,\n-                    suggestions,\n-                },\n-            );\n-        }\n-\n-        // Calculate final score\n-        let total = if total_weight > 0.0 {\n-            total_weighted_score / total_weight\n-        } else {\n-            0.0\n-        };\n-\n-        QualityScore {\n-            total,\n-            dimensions: dimension_scores,\n-            feedback: all_feedback,\n-            metadata: TestMetadata {\n-                command: scenario.command.clone(),\n-                scenario: scenario.name.clone(),\n-                timestamp: chrono::Utc::now().to_rfc3339(),\n-                model: \"qwen3-coder:30b\".to_string(),\n-                execution_time_ms: 0,\n-            },\n-        }\n-    }\n-\n-    /// Generate improvement suggestions based on score\n-    fn generate_suggestions(&self, dimension: &str, score: f32, issues: &[String]) -> Vec<String> {\n-        let mut suggestions = Vec::new();\n-\n-        if score < 7.0 {\n-            match dimension {\n-                \"structure\" => suggestions\n-                    .push(\"Consider adding more semantic structure and proper nesting\".to_string()),\n-                \"completeness\" => suggestions\n-                    .push(\"Ensure all requested elements are included in the output\".to_string()),\n-                \"usability\" => {\n-                    suggestions.push(\"Add more examples and usage documentation\".to_string())\n-                }\n-                \"clarity\" => {\n-                    suggestions.push(\"Improve code comments and variable naming\".to_string())\n-                }\n-                \"correctness\" => {\n-                    suggestions.push(\"Review syntax and semantic correctness\".to_string())\n-                }\n-                \"efficiency\" => suggestions.push(\"Optimize for better performance\".to_string()),\n-                \"readability\" => {\n-                    suggestions.push(\"Improve formatting and organization\".to_string())\n-                }\n-                \"seo_quality\" => {\n-                    suggestions.push(\"Add meta tags, keywords, and descriptions\".to_string())\n-                }\n-                \"ontology_quality\" => {\n-                    suggestions.push(\"Add more relationships and properties\".to_string())\n-                }\n-                _ => suggestions.push(format!(\"Improve {} quality\", dimension)),\n-            }\n-        }\n-\n-        // Add issue-specific suggestions\n-        for issue in issues {\n-            suggestions.push(format!(\"Fix: {}\", issue));\n-        }\n-\n-        suggestions\n-    }\n-\n-    /// Generate comprehensive report\n-    pub fn generate_report(&self, scores: &[QualityScore]) -> String {\n-        let mut report = String::new();\n-\n-        report.push_str(\"# LLM Output Validation Report\\n\\n\");\n-        report.push_str(&format!(\n-            \"Generated: {}\\n\\n\",\n-            chrono::Utc::now().to_rfc3339()\n-        ));\n-\n-        // Overall statistics\n-        let avg_score: f32 = scores.iter().map(|s| s.total).sum::<f32>() / scores.len() as f32;\n-        report.push_str(&format!(\"## Overall Statistics\\n\\n\"));\n-        report.push_str(&format!(\"- **Average Score**: {:.2}/10\\n\", avg_score));\n-        report.push_str(&format!(\"- **Tests Run**: {}\\n\", scores.len()));\n-        report.push_str(&format!(\"- **Model**: qwen3-coder:30b\\n\\n\"));\n-\n-        // Individual test results\n-        report.push_str(\"## Individual Test Results\\n\\n\");\n-        for score in scores {\n-            report.push_str(&format!(\n-                \"### {} (Score: {:.2}/10)\\n\\n\",\n-                score.metadata.scenario, score.total\n-            ));\n-            report.push_str(&format!(\"**Command**: `{}`\\n\\n\", score.metadata.command));\n-\n-            // Dimension scores\n-            report.push_str(\"#### Dimension Scores:\\n\\n\");\n-            for (name, dim) in &score.dimensions {\n-                report.push_str(&format!(\n-                    \"- **{}** ({:.1}/10, weight {:.0}%): {}\\n\",\n-                    name,\n-                    dim.score,\n-                    dim.weight * 100.0,\n-                    dim.description\n-                ));\n-                if !dim.issues.is_empty() {\n-                    report.push_str(\"  - Issues:\\n\");\n-                    for issue in &dim.issues {\n-                        report.push_str(&format!(\"    - {}\\n\", issue));\n-                    }\n-                }\n-            }\n-\n-            // Feedback\n-            if !score.feedback.is_empty() {\n-                report.push_str(\"\\n#### Improvement Suggestions:\\n\\n\");\n-                for feedback in &score.feedback {\n-                    report.push_str(&format!(\"- {}\\n\", feedback));\n-                }\n-            }\n-\n-            report.push_str(\"\\n---\\n\\n\");\n-        }\n-\n-        report\n-    }\n-}\n-\n-// Validator functions\n-\n-fn validate_structure(output: &str) -> (f32, Vec<String>) {\n-    let mut score: f32 = 10.0;\n-    let mut issues = Vec::new();\n-\n-    if output.len() < 50 {\n-        score -= 5.0;\n-        issues.push(\"Output too short\".to_string());\n-    }\n-\n-    if !output.contains('\\n') {\n-        score -= 2.0;\n-        issues.push(\"No line breaks - poor formatting\".to_string());\n-    }\n-\n-    (score.max(0.0f32), issues)\n-}\n-\n-fn validate_completeness(output: &str) -> (f32, Vec<String>) {\n-    let mut score: f32 = 10.0;\n-    let mut issues = Vec::new();\n-\n-    if output.is_empty() {\n-        score = 0.0;\n-        issues.push(\"Empty output\".to_string());\n-    }\n-\n-    (score, issues)\n-}\n-\n-fn validate_usability(output: &str) -> (f32, Vec<String>) {\n-    let mut score: f32 = 10.0;\n-    let mut issues = Vec::new();\n-\n-    if output.contains(\"TODO\") || output.contains(\"FIXME\") {\n-        score -= 3.0;\n-        issues.push(\"Contains TODO/FIXME markers\".to_string());\n-    }\n-\n-    (score.max(0.0f32), issues)\n-}\n-\n-fn validate_clarity(_output: &str) -> (f32, Vec<String>) {\n-    let score: f32 = 8.0; // Base score\n-    let issues = Vec::new();\n-    (score, issues)\n-}\n-\n-fn validate_sparql_syntax(output: &str) -> (f32, Vec<String>) {\n-    let mut score: f32 = 10.0;\n-    let mut issues = Vec::new();\n-\n-    let required_keywords = [\"SELECT\", \"WHERE\"];\n-    for keyword in required_keywords {\n-        if !output.to_uppercase().contains(keyword) {\n-            score -= 5.0;\n-            issues.push(format!(\"Missing required keyword: {}\", keyword));\n-        }\n-    }\n-\n-    (score.max(0.0f32), issues)\n-}\n-\n-fn validate_query_efficiency(_output: &str) -> (f32, Vec<String>) {\n-    let score: f32 = 8.0;\n-    let issues = Vec::new();\n-    (score, issues)\n-}\n-\n-fn validate_readability(output: &str) -> (f32, Vec<String>) {\n-    let mut score: f32 = 10.0;\n-    let mut issues = Vec::new();\n-\n-    if output.lines().count() < 3 {\n-        score -= 2.0;\n-        issues.push(\"Query is not well formatted\".to_string());\n-    }\n-\n-    (score.max(0.0f32), issues)\n-}\n-\n-fn validate_seo(output: &str) -> (f32, Vec<String>) {\n-    let mut score: f32 = 10.0;\n-    let mut issues = Vec::new();\n-\n-    let seo_fields = [\"title\", \"description\", \"keywords\"];\n-    for field in seo_fields {\n-        if !output.to_lowercase().contains(field) {\n-            score -= 2.0;\n-            issues.push(format!(\"Missing SEO field: {}\", field));\n-        }\n-    }\n-\n-    (score.max(0.0f32), issues)\n-}\n-\n-fn validate_frontmatter_completeness(_output: &str) -> (f32, Vec<String>) {\n-    let score: f32 = 8.0;\n-    let issues = Vec::new();\n-    (score, issues)\n-}\n-\n-fn validate_yaml(output: &str) -> (f32, Vec<String>) {\n-    let mut score: f32 = 10.0;\n-    let mut issues = Vec::new();\n-\n-    if !output.contains(':') {\n-        score -= 5.0;\n-        issues.push(\"Not valid YAML format\".to_string());\n-    }\n-\n-    (score.max(0.0f32), issues)\n-}\n-\n-fn validate_ontology(output: &str) -> (f32, Vec<String>) {\n-    let mut score: f32 = 10.0;\n-    let mut issues = Vec::new();\n-\n-    if !output.contains(\"owl:Class\") && !output.contains(\"rdfs:Class\") {\n-        score -= 5.0;\n-        issues.push(\"Missing class definitions\".to_string());\n-    }\n-\n-    (score.max(0.0f32), issues)\n-}\n-\n-fn validate_examples(_output: &str) -> (f32, Vec<String>) {\n-    let score: f32 = 7.0;\n-    let issues = Vec::new();\n-    (score, issues)\n-}\n-\n-fn validate_turtle(output: &str) -> (f32, Vec<String>) {\n-    let mut score: f32 = 10.0;\n-    let mut issues = Vec::new();\n-\n-    if !output.contains(\"@prefix\") {\n-        score -= 5.0;\n-        issues.push(\"Missing @prefix declarations\".to_string());\n-    }\n-\n-    (score.max(0.0f32), issues)\n-}\n-\n-#[cfg(test)]\n-mod tests {\n-    use super::*;\n-\n-    #[test]\n-    fn test_framework_creation() {\n-        let framework = ValidationFramework::new();\n-        assert!(!framework.scenarios.is_empty());\n-    }\n-\n-    #[test]\n-    fn test_structure_validation() {\n-        let (score, issues) = validate_structure(\"# Test\\n\\nContent here\");\n-        assert!(score > 5.0);\n-        assert!(issues.is_empty());\n-    }\n-\n-    #[test]\n-    fn test_sparql_validation() {\n-        let (score, _) = validate_sparql_syntax(\"SELECT ?s WHERE { ?s ?p ?o }\");\n-        assert!(score > 8.0);\n-    }\n-}\n"
                }
            ],
            "date": 1760243825129,
            "name": "Commit-0",
            "content": "//! LLM Output Validation Framework\n//!\n//! This module provides comprehensive testing and scoring for LLM-generated content\n//! across all ggen AI commands. It simulates real user behavior and evaluates output\n//! quality on a 0-10 scale with detailed feedback.\n\nuse serde::{Deserialize, Serialize};\nuse std::collections::HashMap;\n\n/// Scoring dimensions for LLM output quality\n#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct QualityScore {\n    /// Overall score (0-10)\n    pub total: f32,\n    /// Individual dimension scores\n    pub dimensions: HashMap<String, DimensionScore>,\n    /// Actionable feedback for improvement\n    pub feedback: Vec<String>,\n    /// Test metadata\n    pub metadata: TestMetadata,\n}\n\n/// Individual scoring dimension\n#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct DimensionScore {\n    /// Score for this dimension (0-10)\n    pub score: f32,\n    /// Weight in overall score\n    pub weight: f32,\n    /// Description of what was evaluated\n    pub description: String,\n    /// Specific issues found\n    pub issues: Vec<String>,\n    /// Suggestions for improvement\n    pub suggestions: Vec<String>,\n}\n\n/// Test metadata\n#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct TestMetadata {\n    pub command: String,\n    pub scenario: String,\n    pub timestamp: String,\n    pub model: String,\n    pub execution_time_ms: u64,\n}\n\n/// User behavior simulation scenarios\n#[derive(Debug, Clone)]\npub struct UserScenario {\n    pub name: String,\n    pub description: String,\n    pub command: String,\n    pub args: Vec<String>,\n    pub expected_behavior: ExpectedBehavior,\n}\n\n/// Expected behavior for validation\n#[derive(Debug, Clone)]\npub struct ExpectedBehavior {\n    pub min_length: usize,\n    pub max_length: usize,\n    pub required_patterns: Vec<String>,\n    pub forbidden_patterns: Vec<String>,\n    pub quality_criteria: Vec<QualityCriterion>,\n}\n\n/// Quality criterion for evaluation\n#[derive(Debug, Clone)]\npub struct QualityCriterion {\n    pub name: String,\n    pub description: String,\n    pub weight: f32,\n    pub validator: fn(&str) -> (f32, Vec<String>),\n}\n\n/// Validation framework\npub struct ValidationFramework {\n    scenarios: Vec<UserScenario>,\n}\n\nimpl ValidationFramework {\n    /// Create new validation framework with predefined scenarios\n    pub fn new() -> Self {\n        Self {\n            scenarios: Self::create_user_scenarios(),\n        }\n    }\n\n    /// Create realistic user behavior scenarios\n    fn create_user_scenarios() -> Vec<UserScenario> {\n        vec![\n            // Scenario 1: Simple template generation\n            UserScenario {\n                name: \"simple_template\".to_string(),\n                description: \"User wants a basic hello world template\".to_string(),\n                command: \"ai generate\".to_string(),\n                args: vec![\n                    \"--description\".to_string(),\n                    \"Create a simple hello world web page with HTML and CSS\".to_string(),\n                    \"--max-tokens\".to_string(),\n                    \"500\".to_string(),\n                ],\n                expected_behavior: ExpectedBehavior {\n                    min_length: 100,\n                    max_length: 2000,\n                    required_patterns: vec![\"html\".to_string(), \"hello\".to_string()],\n                    forbidden_patterns: vec![\"error\".to_string(), \"undefined\".to_string()],\n                    quality_criteria: vec![\n                        QualityCriterion {\n                            name: \"structure\".to_string(),\n                            description: \"Has proper structure and formatting\".to_string(),\n                            weight: 0.3,\n                            validator: validate_structure,\n                        },\n                        QualityCriterion {\n                            name: \"completeness\".to_string(),\n                            description: \"Contains all requested elements\".to_string(),\n                            weight: 0.3,\n                            validator: validate_completeness,\n                        },\n                        QualityCriterion {\n                            name: \"usability\".to_string(),\n                            description: \"Code is ready to use without modification\".to_string(),\n                            weight: 0.2,\n                            validator: validate_usability,\n                        },\n                        QualityCriterion {\n                            name: \"clarity\".to_string(),\n                            description: \"Code is well-commented and clear\".to_string(),\n                            weight: 0.2,\n                            validator: validate_clarity,\n                        },\n                    ],\n                },\n            },\n            // Scenario 2: Complex SPARQL query\n            UserScenario {\n                name: \"complex_sparql\".to_string(),\n                description: \"User needs a SPARQL query for data analysis\".to_string(),\n                command: \"ai sparql\".to_string(),\n                args: vec![\n                    \"--description\".to_string(),\n                    \"Find all users with age > 18 who have made purchases in the last 30 days\"\n                        .to_string(),\n                    \"--max-tokens\".to_string(),\n                    \"300\".to_string(),\n                ],\n                expected_behavior: ExpectedBehavior {\n                    min_length: 50,\n                    max_length: 1000,\n                    required_patterns: vec![\n                        \"SELECT\".to_string(),\n                        \"WHERE\".to_string(),\n                        \"FILTER\".to_string(),\n                    ],\n                    forbidden_patterns: vec![\"syntax error\".to_string()],\n                    quality_criteria: vec![\n                        QualityCriterion {\n                            name: \"correctness\".to_string(),\n                            description: \"SPARQL syntax is valid\".to_string(),\n                            weight: 0.4,\n                            validator: validate_sparql_syntax,\n                        },\n                        QualityCriterion {\n                            name: \"efficiency\".to_string(),\n                            description: \"Query is optimized\".to_string(),\n                            weight: 0.3,\n                            validator: validate_query_efficiency,\n                        },\n                        QualityCriterion {\n                            name: \"readability\".to_string(),\n                            description: \"Query is formatted well\".to_string(),\n                            weight: 0.3,\n                            validator: validate_readability,\n                        },\n                    ],\n                },\n            },\n            // Scenario 3: Frontmatter generation\n            UserScenario {\n                name: \"blog_frontmatter\".to_string(),\n                description: \"User needs frontmatter for a blog post\".to_string(),\n                command: \"ai frontmatter\".to_string(),\n                args: vec![\n                    \"--description\".to_string(),\n                    \"Blog post about AI ethics with SEO optimization\".to_string(),\n                    \"--max-tokens\".to_string(),\n                    \"200\".to_string(),\n                ],\n                expected_behavior: ExpectedBehavior {\n                    min_length: 50,\n                    max_length: 800,\n                    required_patterns: vec![\"title\".to_string(), \"description\".to_string()],\n                    forbidden_patterns: vec![],\n                    quality_criteria: vec![\n                        QualityCriterion {\n                            name: \"seo_quality\".to_string(),\n                            description: \"Contains proper SEO metadata\".to_string(),\n                            weight: 0.4,\n                            validator: validate_seo,\n                        },\n                        QualityCriterion {\n                            name: \"completeness\".to_string(),\n                            description: \"All standard fields present\".to_string(),\n                            weight: 0.3,\n                            validator: validate_frontmatter_completeness,\n                        },\n                        QualityCriterion {\n                            name: \"validity\".to_string(),\n                            description: \"Valid YAML format\".to_string(),\n                            weight: 0.3,\n                            validator: validate_yaml,\n                        },\n                    ],\n                },\n            },\n            // Scenario 4: RDF graph generation\n            UserScenario {\n                name: \"ontology_graph\".to_string(),\n                description: \"User wants an RDF ontology for a specific domain\".to_string(),\n                command: \"ai graph\".to_string(),\n                args: vec![\n                    \"--description\".to_string(),\n                    \"E-commerce product catalog with categories and pricing\".to_string(),\n                    \"--include-examples\".to_string(),\n                    \"--max-tokens\".to_string(),\n                    \"400\".to_string(),\n                ],\n                expected_behavior: ExpectedBehavior {\n                    min_length: 100,\n                    max_length: 2000,\n                    required_patterns: vec![\"@prefix\".to_string(), \"owl:Class\".to_string()],\n                    forbidden_patterns: vec![\"syntax error\".to_string()],\n                    quality_criteria: vec![\n                        QualityCriterion {\n                            name: \"ontology_quality\".to_string(),\n                            description: \"Well-structured ontology\".to_string(),\n                            weight: 0.4,\n                            validator: validate_ontology,\n                        },\n                        QualityCriterion {\n                            name: \"examples\".to_string(),\n                            description: \"Contains useful examples\".to_string(),\n                            weight: 0.3,\n                            validator: validate_examples,\n                        },\n                        QualityCriterion {\n                            name: \"turtle_validity\".to_string(),\n                            description: \"Valid Turtle syntax\".to_string(),\n                            weight: 0.3,\n                            validator: validate_turtle,\n                        },\n                    ],\n                },\n            },\n        ]\n    }\n\n    /// Run all validation scenarios\n    pub fn run_all_scenarios(&self) -> Vec<QualityScore> {\n        self.scenarios\n            .iter()\n            .map(|scenario| self.run_scenario(scenario))\n            .collect()\n    }\n\n    /// Run a single validation scenario\n    pub fn run_scenario(&self, scenario: &UserScenario) -> QualityScore {\n        // Execute command and capture output\n        let output = self.execute_command(scenario);\n\n        // Score the output\n        self.score_output(&output, scenario)\n    }\n\n    /// Execute command and capture output\n    fn execute_command(&self, scenario: &UserScenario) -> String {\n        // This would actually run the command - placeholder for now\n        format!(\"Output from {}\", scenario.command)\n    }\n\n    /// Score output against expected behavior\n    fn score_output(&self, output: &str, scenario: &UserScenario) -> QualityScore {\n        let mut dimension_scores = HashMap::new();\n        let mut total_weighted_score = 0.0;\n        let mut total_weight = 0.0;\n        let mut all_feedback = Vec::new();\n\n        // Score each quality criterion\n        for criterion in &scenario.expected_behavior.quality_criteria {\n            let (score, issues) = (criterion.validator)(output);\n\n            total_weighted_score += score * criterion.weight;\n            total_weight += criterion.weight;\n\n            let suggestions = self.generate_suggestions(&criterion.name, score, &issues);\n            all_feedback.extend(suggestions.clone());\n\n            dimension_scores.insert(\n                criterion.name.clone(),\n                DimensionScore {\n                    score,\n                    weight: criterion.weight,\n                    description: criterion.description.clone(),\n                    issues,\n                    suggestions,\n                },\n            );\n        }\n\n        // Calculate final score\n        let total = if total_weight > 0.0 {\n            total_weighted_score / total_weight\n        } else {\n            0.0\n        };\n\n        QualityScore {\n            total,\n            dimensions: dimension_scores,\n            feedback: all_feedback,\n            metadata: TestMetadata {\n                command: scenario.command.clone(),\n                scenario: scenario.name.clone(),\n                timestamp: chrono::Utc::now().to_rfc3339(),\n                model: \"qwen3-coder:30b\".to_string(),\n                execution_time_ms: 0,\n            },\n        }\n    }\n\n    /// Generate improvement suggestions based on score\n    fn generate_suggestions(&self, dimension: &str, score: f32, issues: &[String]) -> Vec<String> {\n        let mut suggestions = Vec::new();\n\n        if score < 7.0 {\n            match dimension {\n                \"structure\" => suggestions\n                    .push(\"Consider adding more semantic structure and proper nesting\".to_string()),\n                \"completeness\" => suggestions\n                    .push(\"Ensure all requested elements are included in the output\".to_string()),\n                \"usability\" => {\n                    suggestions.push(\"Add more examples and usage documentation\".to_string())\n                }\n                \"clarity\" => {\n                    suggestions.push(\"Improve code comments and variable naming\".to_string())\n                }\n                \"correctness\" => {\n                    suggestions.push(\"Review syntax and semantic correctness\".to_string())\n                }\n                \"efficiency\" => suggestions.push(\"Optimize for better performance\".to_string()),\n                \"readability\" => {\n                    suggestions.push(\"Improve formatting and organization\".to_string())\n                }\n                \"seo_quality\" => {\n                    suggestions.push(\"Add meta tags, keywords, and descriptions\".to_string())\n                }\n                \"ontology_quality\" => {\n                    suggestions.push(\"Add more relationships and properties\".to_string())\n                }\n                _ => suggestions.push(format!(\"Improve {} quality\", dimension)),\n            }\n        }\n\n        // Add issue-specific suggestions\n        for issue in issues {\n            suggestions.push(format!(\"Fix: {}\", issue));\n        }\n\n        suggestions\n    }\n\n    /// Generate comprehensive report\n    pub fn generate_report(&self, scores: &[QualityScore]) -> String {\n        let mut report = String::new();\n\n        report.push_str(\"# LLM Output Validation Report\\n\\n\");\n        report.push_str(&format!(\n            \"Generated: {}\\n\\n\",\n            chrono::Utc::now().to_rfc3339()\n        ));\n\n        // Overall statistics\n        let avg_score: f32 = scores.iter().map(|s| s.total).sum::<f32>() / scores.len() as f32;\n        report.push_str(&format!(\"## Overall Statistics\\n\\n\"));\n        report.push_str(&format!(\"- **Average Score**: {:.2}/10\\n\", avg_score));\n        report.push_str(&format!(\"- **Tests Run**: {}\\n\", scores.len()));\n        report.push_str(&format!(\"- **Model**: qwen3-coder:30b\\n\\n\"));\n\n        // Individual test results\n        report.push_str(\"## Individual Test Results\\n\\n\");\n        for score in scores {\n            report.push_str(&format!(\n                \"### {} (Score: {:.2}/10)\\n\\n\",\n                score.metadata.scenario, score.total\n            ));\n            report.push_str(&format!(\"**Command**: `{}`\\n\\n\", score.metadata.command));\n\n            // Dimension scores\n            report.push_str(\"#### Dimension Scores:\\n\\n\");\n            for (name, dim) in &score.dimensions {\n                report.push_str(&format!(\n                    \"- **{}** ({:.1}/10, weight {:.0}%): {}\\n\",\n                    name,\n                    dim.score,\n                    dim.weight * 100.0,\n                    dim.description\n                ));\n                if !dim.issues.is_empty() {\n                    report.push_str(\"  - Issues:\\n\");\n                    for issue in &dim.issues {\n                        report.push_str(&format!(\"    - {}\\n\", issue));\n                    }\n                }\n            }\n\n            // Feedback\n            if !score.feedback.is_empty() {\n                report.push_str(\"\\n#### Improvement Suggestions:\\n\\n\");\n                for feedback in &score.feedback {\n                    report.push_str(&format!(\"- {}\\n\", feedback));\n                }\n            }\n\n            report.push_str(\"\\n---\\n\\n\");\n        }\n\n        report\n    }\n}\n\n// Validator functions\n\nfn validate_structure(output: &str) -> (f32, Vec<String>) {\n    let mut score: f32 = 10.0;\n    let mut issues = Vec::new();\n\n    if output.len() < 50 {\n        score -= 5.0;\n        issues.push(\"Output too short\".to_string());\n    }\n\n    if !output.contains('\\n') {\n        score -= 2.0;\n        issues.push(\"No line breaks - poor formatting\".to_string());\n    }\n\n    (score.max(0.0f32), issues)\n}\n\nfn validate_completeness(output: &str) -> (f32, Vec<String>) {\n    let mut score: f32 = 10.0;\n    let mut issues = Vec::new();\n\n    if output.is_empty() {\n        score = 0.0;\n        issues.push(\"Empty output\".to_string());\n    }\n\n    (score, issues)\n}\n\nfn validate_usability(output: &str) -> (f32, Vec<String>) {\n    let mut score: f32 = 10.0;\n    let mut issues = Vec::new();\n\n    if output.contains(\"TODO\") || output.contains(\"FIXME\") {\n        score -= 3.0;\n        issues.push(\"Contains TODO/FIXME markers\".to_string());\n    }\n\n    (score.max(0.0f32), issues)\n}\n\nfn validate_clarity(_output: &str) -> (f32, Vec<String>) {\n    let score: f32 = 8.0; // Base score\n    let issues = Vec::new();\n    (score, issues)\n}\n\nfn validate_sparql_syntax(output: &str) -> (f32, Vec<String>) {\n    let mut score: f32 = 10.0;\n    let mut issues = Vec::new();\n\n    let required_keywords = [\"SELECT\", \"WHERE\"];\n    for keyword in required_keywords {\n        if !output.to_uppercase().contains(keyword) {\n            score -= 5.0;\n            issues.push(format!(\"Missing required keyword: {}\", keyword));\n        }\n    }\n\n    (score.max(0.0f32), issues)\n}\n\nfn validate_query_efficiency(_output: &str) -> (f32, Vec<String>) {\n    let score: f32 = 8.0;\n    let issues = Vec::new();\n    (score, issues)\n}\n\nfn validate_readability(output: &str) -> (f32, Vec<String>) {\n    let mut score: f32 = 10.0;\n    let mut issues = Vec::new();\n\n    if output.lines().count() < 3 {\n        score -= 2.0;\n        issues.push(\"Query is not well formatted\".to_string());\n    }\n\n    (score.max(0.0f32), issues)\n}\n\nfn validate_seo(output: &str) -> (f32, Vec<String>) {\n    let mut score: f32 = 10.0;\n    let mut issues = Vec::new();\n\n    let seo_fields = [\"title\", \"description\", \"keywords\"];\n    for field in seo_fields {\n        if !output.to_lowercase().contains(field) {\n            score -= 2.0;\n            issues.push(format!(\"Missing SEO field: {}\", field));\n        }\n    }\n\n    (score.max(0.0f32), issues)\n}\n\nfn validate_frontmatter_completeness(_output: &str) -> (f32, Vec<String>) {\n    let score: f32 = 8.0;\n    let issues = Vec::new();\n    (score, issues)\n}\n\nfn validate_yaml(output: &str) -> (f32, Vec<String>) {\n    let mut score: f32 = 10.0;\n    let mut issues = Vec::new();\n\n    if !output.contains(':') {\n        score -= 5.0;\n        issues.push(\"Not valid YAML format\".to_string());\n    }\n\n    (score.max(0.0f32), issues)\n}\n\nfn validate_ontology(output: &str) -> (f32, Vec<String>) {\n    let mut score: f32 = 10.0;\n    let mut issues = Vec::new();\n\n    if !output.contains(\"owl:Class\") && !output.contains(\"rdfs:Class\") {\n        score -= 5.0;\n        issues.push(\"Missing class definitions\".to_string());\n    }\n\n    (score.max(0.0f32), issues)\n}\n\nfn validate_examples(_output: &str) -> (f32, Vec<String>) {\n    let score: f32 = 7.0;\n    let issues = Vec::new();\n    (score, issues)\n}\n\nfn validate_turtle(output: &str) -> (f32, Vec<String>) {\n    let mut score: f32 = 10.0;\n    let mut issues = Vec::new();\n\n    if !output.contains(\"@prefix\") {\n        score -= 5.0;\n        issues.push(\"Missing @prefix declarations\".to_string());\n    }\n\n    (score.max(0.0f32), issues)\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_framework_creation() {\n        let framework = ValidationFramework::new();\n        assert!(!framework.scenarios.is_empty());\n    }\n\n    #[test]\n    fn test_structure_validation() {\n        let (score, issues) = validate_structure(\"# Test\\n\\nContent here\");\n        assert!(score > 5.0);\n        assert!(issues.is_empty());\n    }\n\n    #[test]\n    fn test_sparql_validation() {\n        let (score, _) = validate_sparql_syntax(\"SELECT ?s WHERE { ?s ?p ?o }\");\n        assert!(score > 8.0);\n    }\n}\n"
        }
    ]
}