nix-module-system — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited nix-module-system (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Practical knowledge about lib.evalModules that's hard to find in official docs.
Sources:
When the same module is included multiple times (e.g., via imports from different places), evalModules deduplicates by identity:
Path-based modules: Deduplicated by path string
modules = [ ./foo.nix ./foo.nix ]; # Same path → evaluated onceFunction/attrset modules: Deduplicated by key attribute
# Without key: each inclusion is separate (can cause "defined multiple times" errors)
modules = [ myModule myModule ]; # Evaluated twice!
# With key: deduplicated
myModule = {
key = "my-unique-module-id";
imports = [ actualModule ];
};
modules = [ myModule myModule ]; # Evaluated onceUse key when you wrap modules dynamically and need deduplication across import chains.
_module.args vs specialArgsBoth inject arguments into module functions, but differ in timing:
evalModules {
specialArgs = { foo = "available during option declaration"; };
modules = [{
_module.args = { bar = "only available in config, not options"; };
}];
}specialArgs | _module.args | |
|---|---|---|
Available in options = { ... } | ✓ | ✗ |
Available in config = { ... } | ✓ | ✓ |
Can reference config | ✗ | ✓ |
Rule of thumb: Use specialArgs for things needed to declare options (like lib), use _module.args for runtime values (like pkgs).
_module.checkDisable "unknown option" errors:
{ _module.check = false; }Useful when modules set options that might not exist (e.g., optional integrations).
_module.freeformTypeAllow arbitrary attributes in config without declaring options:
{
_module.freeformType = lib.types.attrsOf lib.types.anything;
# Now any attribute is allowed without explicit options
whatever.you.want = "works";
}mkDefault / mkForce / mkOverrideControl which definition wins when multiple modules set the same option:
# Priority scale: lower number wins
lib.mkOverride 1000 "default priority" # Same as mkDefault
lib.mkOverride 100 "normal priority" # Default when no mk* used
lib.mkOverride 50 "force priority" # Same as mkForce
# Shorthands
lib.mkDefault x # mkOverride 1000 - easily overridden
lib.mkForce x # mkOverride 50 - overrides most thingsmkMergeCombine multiple config fragments:
config = lib.mkMerge [
{ services.foo.enable = true; }
(lib.mkIf condition { services.foo.port = 8080; })
];mkIf (it's not just if)lib.mkIf is not the same as Nix's if:
# Nix if: evaluated immediately, fails if option doesn't exist
config = if condition then { foo = 1; } else { };
# lib.mkIf: deferred, only evaluated if condition is true
config = lib.mkIf condition { foo = 1; };mkIf prevents "infinite recursion" errors when the condition depends on other config values.
mkBefore / mkAfter / mkOrderFor list-type options, control ordering:
{
environment.systemPackages = lib.mkBefore [ earlyPkg ]; # Prepend
environment.systemPackages = lib.mkAfter [ latePkg ]; # Append
environment.systemPackages = lib.mkOrder 500 [ midPkg ]; # Explicit order
}Remove a module from evaluation:
{
disabledModules = [
"services/web-servers/nginx.nix" # Path relative to modules root
someImportedModule # Direct reference
];
}Useful for replacing NixOS modules with custom implementations.
See references/troubleshooting.md for detailed error explanations.
Quick fixes:
key attribute or use lib.mkForce/lib.mkMergelib.mkIf instead of if, or check for circular dependencies_module.check = false for optional deps~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.