283 lines
8.7 KiB
Nim
283 lines
8.7 KiB
Nim
# 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)
|