# Inference Configuration Module # Manages organization-specific inference rules for requirement composition # Load organization-specific inference rules export def load-inference-rules [ org_name?: string ] { let org = ($org_name | default ($env.PROVISIONING_ORG? | default "default")) let config_path = ($env.PROVISIONING? | default "" | path join "config" "inference-rules" $"($org).yaml") if ($config_path | path exists) { # Load the YAML file (open automatically parses YAML) let rules = (open $config_path) if (try { $rules.rules | is-not-empty } catch { false }) { $rules } else { get-default-inference-rules } } else { get-default-inference-rules } } # Get default inference rules export def get-default-inference-rules [] { { version: "1.0.0" organization: "default" rules: [ { name: "nodejs-to-caching" technology: ["nodejs", "express"] infers: "redis" confidence: 0.85 reason: "Node.js with Express typically needs caching layer" required: false } { name: "nodejs-to-nginx" technology: ["nodejs"] infers: "nginx" confidence: 0.70 reason: "Node.js applications benefit from reverse proxy" required: false } { name: "database-to-backup" technology: ["postgres", "mysql", "mongodb"] infers: "backup" confidence: 0.90 reason: "Databases need backup and recovery strategy" required: true } { name: "docker-to-orchestration" technology: ["docker"] infers: "kubernetes" confidence: 0.75 reason: "Containerized apps benefit from orchestration" required: false } { name: "python-to-wsgi" technology: ["python", "django", "flask"] infers: "gunicorn" confidence: 0.80 reason: "Python web apps need WSGI application server" required: false } { name: "database-isolation" technology: ["postgres"] infers: "monitoring" confidence: 0.75 reason: "Production databases need monitoring and alerting" required: true } ] } } # Validate inference rule export def validate-inference-rule [ rule: record ] { let required_fields = ["name" "technology" "infers" "confidence" "reason"] let has_all = ($required_fields | all {|f| try { ($rule | get $f) | is-not-empty } catch { false } }) { valid: $has_all errors: (if not $has_all { $required_fields | where {|f| try { ($rule | get $f) | is-empty } catch { true } } } else { [] }) } } # Apply inference rules to detection results export def apply-inference-rules [ detection: record rules: record ] { let detected_techs = ($detection.detections | each {|d| $d.technology } | each {|t| $t | str downcase }) let inferred_reqs = ($rules.rules | where {|r| ($r.technology | any {|t| ($t | str downcase) in $detected_techs }) }) { detection: $detection applied_rules: $inferred_reqs additional_requirements: $inferred_reqs } } # Save custom organization rules export def save-inference-rules [ org_name: string rules: record ] { let config_dir = ($env.PROVISIONING? | default "" | path join "config" "inference-rules") # Create directory if needed if not ($config_dir | path exists) { mkdir $config_dir } let config_path = ($config_dir | path join $"($org_name).yaml") try { $rules | to yaml | save $config_path { success: true message: $"Rules saved to ($config_path)" path: $config_path } } catch {|err| { success: false error: $err.msg path: $config_path } } } # List available inference rule configurations export def list-inference-configs [] { let config_dir = ($env.PROVISIONING? | default "" | path join "config" "inference-rules") if not ($config_dir | path exists) { [] } else { let files = (ls $config_dir | where {|f| ($f.name | str ends-with ".yaml") }) $files | each {|f| let basename = ($f.name | path basename | str replace -a ".yaml" "") { name: $basename path: $f.name modified: $f.modified } } } } # Create template for new organization rules export def create-rule-template [ org_name: string ] { { version: "1.0.0" organization: $org_name description: $"Inference rules for ($org_name)" rules: [ { name: "example-rule" technology: ["tech1" "tech2"] infers: "required-taskserv" confidence: 0.85 reason: "Description of why this inference is made" required: false } ] } } # Export rules as Rust integration (simplified version) export def export-rules-for-rust [ rules: record ] { # Generate Rust struct representations of the inference rules let rule_count = ($rules.rules | length) $"Generated Rust export for ($rule_count) rules from ($rules.organization | default "default")" }