# SPDX-License-Identifier: LSL-1.0 # Copyright (c) 2026 Markus Maiwald # Stewardship: Self Sovereign Society Foundation # # This file is part of the Nexus Sovereign Core. # See legal/LICENSE_SOVEREIGN.md for license terms. ## variant_domains.nim ## Semantic domain definitions for NIP variant system ## Defines 9 orthogonal domains with typed constraints import std/tables import variant_types # ############################################################################# # Semantic Domain Definitions # ############################################################################# proc initSemanticDomains*(): Table[string, FlagDomain] = ## Initialize the 9 semantic domains with their constraints result = initTable[string, FlagDomain]() # 1. Init System Domain result["init"] = FlagDomain( name: "init", description: "Init system selection", flagType: ftChoice, exclusive: true, options: @["systemd", "dinit", "openrc", "runit", "s6"], default: "dinit", compilerFlagRules: initTable[string, CompilerFlagRule]() ) # 2. Runtime Features Domain result["runtime"] = FlagDomain( name: "runtime", description: "Core runtime features", flagType: ftSet, exclusive: false, options: @["ssl", "http3", "zstd", "ipv6", "doc", "dbus", "cuda", "rocm", "onnx", "tensorrt", "steam", "wine", "proton"], default: "", compilerFlagRules: initTable[string, CompilerFlagRule]() ) # 3. Graphics Domain result["graphics"] = FlagDomain( name: "graphics", description: "Display server and GPU API", flagType: ftChoice, exclusive: true, options: @["none", "X", "wayland", "vulkan", "opengl", "mesa"], default: "none", compilerFlagRules: initTable[string, CompilerFlagRule]() ) # 4. Audio Domain result["audio"] = FlagDomain( name: "audio", description: "Sound server selection", flagType: ftChoice, exclusive: true, options: @["none", "pipewire", "pulseaudio", "alsa", "jack"], default: "pipewire", compilerFlagRules: initTable[string, CompilerFlagRule]() ) # 5. Security Domain result["security"] = FlagDomain( name: "security", description: "Security hardening", flagType: ftSet, exclusive: false, options: @["pie", "relro", "hardened", "fortify", "stack-protector"], default: "", compilerFlagRules: initTable[string, CompilerFlagRule]() ) # 6. Optimization Domain result["optimization"] = FlagDomain( name: "optimization", description: "Build optimizations", flagType: ftSet, exclusive: false, options: @["lto", "pgo", "march-native", "debug", "strip"], default: "", compilerFlagRules: initTable[string, CompilerFlagRule]() ) # 7. Integration Domain result["integration"] = FlagDomain( name: "integration", description: "System interfaces", flagType: ftSet, exclusive: false, options: @["docker", "podman", "nipcells", "libvirt", "nexus-api", "nexus-security", "nexus-monitor"], default: "", compilerFlagRules: initTable[string, CompilerFlagRule]() ) # 8. Network Domain result["network"] = FlagDomain( name: "network", description: "Networking stack", flagType: ftSet, exclusive: false, options: @["ipv6", "wireguard", "zerotier", "mesh", "p2p", "ipfs"], default: "", compilerFlagRules: initTable[string, CompilerFlagRule]() ) # 9. Developer Domain result["developer"] = FlagDomain( name: "developer", description: "Development tooling", flagType: ftSet, exclusive: false, options: @["debugger", "profiler", "lsp", "repl", "hot-reload", "sanitizer"], default: "", compilerFlagRules: initTable[string, CompilerFlagRule]() ) # Global constant for semantic domains const SEMANTIC_DOMAINS* = initSemanticDomains() # ############################################################################# # Domain Query Functions # ############################################################################# proc getDomain*(name: string): FlagDomain = ## Get a domain by name, raises KeyError if not found result = SEMANTIC_DOMAINS[name] proc hasDomain*(name: string): bool = ## Check if a domain exists result = SEMANTIC_DOMAINS.hasKey(name) proc getAllDomainNames*(): seq[string] = ## Get all domain names result = @[] for name in SEMANTIC_DOMAINS.keys: result.add(name) proc isValidDomainValue*(domain: string, value: string): bool = ## Check if a value is valid for a domain if not hasDomain(domain): return false let domainDef = SEMANTIC_DOMAINS[domain] result = value in domainDef.options proc getDomainOptions*(domain: string): seq[string] = ## Get all valid options for a domain if not hasDomain(domain): return @[] result = SEMANTIC_DOMAINS[domain].options proc getDomainType*(domain: string): FlagType = ## Get the flag type for a domain if not hasDomain(domain): raise newException(KeyError, "Unknown domain: " & domain) result = SEMANTIC_DOMAINS[domain].flagType proc isExclusiveDomain*(domain: string): bool = ## Check if a domain is exclusive (only one value allowed) if not hasDomain(domain): return false result = SEMANTIC_DOMAINS[domain].exclusive # ############################################################################# # Legacy Category Migration # ############################################################################# proc initLegacyCategoryMap*(): Table[string, string] = ## Initialize mapping from legacy 16 categories to new 9 domains result = initTable[string, string]() # Eliminated categories → New domains result["gui"] = "graphics" result["gaming"] = "graphics" # vulkan, opengl → graphics; steam → runtime result["container"] = "integration" result["virtualization"] = "integration" result["mesh"] = "network" result["ai-ml"] = "runtime" # cuda, rocm → runtime result["nexus-fleet"] = "profile" # Becomes a profile, not a domain result["nexus-bootstrap"] = "build-mode" # Build-time, not runtime result["nexus-integration"] = "integration" result["bindings"] = "runtime" result["features"] = "runtime" # Preserved categories (direct mapping) result["init"] = "init" result["audio"] = "audio" result["optimization"] = "optimization" result["security"] = "security" # Global constant for legacy category mapping const LEGACY_CATEGORY_MAP* = initLegacyCategoryMap() # ############################################################################# # Legacy Flag Migration Functions # ############################################################################# proc mapLegacyFlagToDomain*(flagName: string, category: string = ""): string = ## Map a legacy USE flag to its corresponding domain ## If category is provided, use it for mapping ## Otherwise, try to infer from common flag names # If category is provided and exists in legacy map, use it if category.len > 0 and LEGACY_CATEGORY_MAP.hasKey(category): let mappedDomain = LEGACY_CATEGORY_MAP[category] # Skip special cases that aren't runtime domains if mappedDomain notin ["profile", "build-mode"]: return mappedDomain # Infer domain from common flag names case flagName # Init system flags of "systemd", "dinit", "openrc", "runit", "s6": return "init" # Graphics flags of "X", "wayland", "vulkan", "opengl", "mesa", "gtk", "qt": return "graphics" # Audio flags of "pipewire", "pulseaudio", "alsa", "jack": return "audio" # Security flags of "pie", "relro", "hardened", "fortify", "stack-protector": return "security" # Optimization flags of "lto", "pgo", "march-native", "debug", "strip": return "optimization" # Integration flags of "docker", "podman", "nipcells", "libvirt", "nexus-api", "nexus-security", "nexus-monitor": return "integration" # Network flags of "ipv6", "wireguard", "zerotier", "mesh", "p2p", "ipfs": return "network" # Developer flags of "debugger", "profiler", "lsp", "repl", "hot-reload", "sanitizer": return "developer" # Runtime flags (default for unknown) else: return "runtime" proc mapLegacyCategoryToDomain*(category: string): string = ## Map a legacy category name to a domain name ## Returns empty string if category should not be mapped to a domain if LEGACY_CATEGORY_MAP.hasKey(category): let mapped = LEGACY_CATEGORY_MAP[category] # Filter out special cases if mapped in ["profile", "build-mode"]: return "" return mapped # Unknown category defaults to runtime return "runtime" proc isLegacyCategory*(category: string): bool = ## Check if a category name is a legacy category result = LEGACY_CATEGORY_MAP.hasKey(category) proc getLegacyCategories*(): seq[string] = ## Get all legacy category names result = @[] for category in LEGACY_CATEGORY_MAP.keys: result.add(category)