feat: cluster test framework #545
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds VM test generation and execution wiring, a shared VM test profile, per-host unit tests, documentation, CI and local runners, plus ChangesVM Integration Test Framework
Per-host server.tests.units Definitions
importExternals Gating and API Key Null-Safety
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant flakeModule as flake/nixos/flake-module.nix
participant testsBuilder as tests/builder.nix
participant woodpecker as .woodpecker/test-vm.yaml
participant nixBuild as nix build
flakeModule->>testsBuilder: build nixosTestConfigurations
woodpecker->>nixBuild: run per-host VM builds
nixBuild-->>woodpecker: pass or FAILED per host
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Merge ProtectionsYour pull request matches the following merge protections and will not be merged until they are valid. 🔴 Enforce conventional commitWaiting for
This rule is failing.Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
🔴 Do not merge outdated PRsWaiting for
This rule is failing.Make sure PRs are almost up to date before merging
|
🧪 CI InsightsHere's what we observed from your CI run for 072e115. 🟢 All jobs passed!But CI Insights is watching 👀 |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
flake/ci/flake-module.nix (1)
12-29:⚠️ Potential issue | 🟠 Major
checks.clusternever consults the newserver.tests.enableflag.
clusterHostsis derived only fromgetHostsByType self, andtests/default.nix:17-19turns every entry in that list into a VM node. As written, flippingserver.tests.enableinmodules/nixos/server/tests.nixcannot change which hosts participate in the cluster test, so the new opt-in flag is ineffective for membership.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@flake/ci/flake-module.nix` around lines 12 - 29, The cluster test currently uses clusterHosts = (getHostsByType self).server or [] which ignores the new server.tests.enable flag; update the clusterHosts computation so it filters the hosts list to only include hosts whose server.tests.enable is true (i.e., evaluate each host's module/config and keep it only when server.tests.enable is truthy) before passing clusterHosts into checks.cluster (references: clusterHosts, getHostsByType, checks.cluster, server.tests.enable, tests/default.nix).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/src/modules/nixos/desktop.md`:
- Around line 7-8: The docs currently imply RGB and VFIO are enabled by default;
update the desktop.md wording to state these are opt-in features and are only
enabled when their config flag is set (they are gated with mkIf cfg.enable in
the rgb.nix and vfio.nix modules), and clarify how
modules/nixos/desktop/default.nix composes those modules rather than enabling
them globally; change the two spots called out to mention "opt-in via
cfg.enable" and mirror the suggested wording.
In `@modules/nixos/desktop/virtual-machine.nix`:
- Around line 92-96: The mounts option currently uses mkOption with type =
types.attrsOf types.anything which removes validation; update the description
for the mounts option (the mkOption named "mounts") to document the expected
attribute structure and provide a concrete example showing host-path keys
mapping to attrs including target and readonly (e.g. host path -> { target =
"/guest/path"; readonly = false; }) so users know the required fields and shape;
keep the existing type but make the description clear and copyable for users.
In `@modules/nixos/server/tests.nix`:
- Around line 10-11: The module is incorrectly inheriting type helpers from lib
(which has no .type); update the inherits to pull from lib.types so the NixOS
module type helpers are resolved: change the first inherit to reference
lib.types when bringing in type, mkOption and mkEnableOption, and change the
second inherit to reference lib.types for submodule, attrsOf, either, listOf,
str, bool, functionTo (or alternatively only import type once and then inherit
(type) ...), ensuring mkOption, mkEnableOption, submodule, attrsOf, either,
listOf, str, bool, and functionTo come from lib.types.
- Around line 17-38: The options declaration for server.tests.units currently
assigns a raw attrsOf (submodule ...) value instead of an option; wrap the whole
attrsOf (submodule ({ name, ... }: { ... })) expression in mkOption so
server.tests.units is an actual Nix option. Specifically, replace the bare units
= attrsOf (...) with units = mkOption (attrsOf (submodule ({ name, ... }: {
options = { ... } }))) (or equivalent mkOption form), keeping the same inner
options (name, testScript) to match other modules (metrics.nix, mcpo.nix,
virtual-machine.nix, dashboard.nix) that use mkOption for units.
In `@tests/lib.nix`:
- Around line 6-9: The helper runOnAllNodes is passing the literal string
"node.name" to the callback so callers receive a string instead of the node
object; change the interpolation so the callback is invoked with the node object
(not node.name) inside the for-loop/subtest, i.e. pass node into ${f(...)} so
callers can call methods like wait_for_unit on the actual node object; update
any related docs/tests to expect the node object argument and keep using
subtest(node.name) as the subtest label.
In `@tests/mkNode.nix`:
- Around line 7-11: The test node import currently uses only
modules/flake/apply/system.nix causing tests to build minimal VMs; update the
imports to build test nodes with the full production module stack by either
reusing the existing builder lib/builders/mkSystem.nix or by expanding the
imports to include the NixOS modules, device-type modules, host directory and
shared config modules (preserve existing attributes like allocations, hostName
and deviceType). Locate the imports block that references
modules/flake/apply/system.nix and replace it with a call to
lib/builders/mkSystem.nix (or mirror its module list) so test VMs are built the
same way as production.
---
Outside diff comments:
In `@flake/ci/flake-module.nix`:
- Around line 12-29: The cluster test currently uses clusterHosts =
(getHostsByType self).server or [] which ignores the new server.tests.enable
flag; update the clusterHosts computation so it filters the hosts list to only
include hosts whose server.tests.enable is true (i.e., evaluate each host's
module/config and keep it only when server.tests.enable is truthy) before
passing clusterHosts into checks.cluster (references: clusterHosts,
getHostsByType, checks.cluster, server.tests.enable, tests/default.nix).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4df9fa6f-3aca-4579-86f4-9a365402645c
📒 Files selected for processing (60)
docs/src/modules/nixos/desktop.mddocs/src/modules/nixos/services.mdflake/ci/flake-module.nixflake/default.nixhome/shared/applications/media.nixhome/shared/desktop/gnome/default.nixlib/builders/mkSystem.nixmodules/home-manager/services/mcpo.nixmodules/nixos/default.nixmodules/nixos/desktop/default.nixmodules/nixos/desktop/rgb.nixmodules/nixos/desktop/vfio.nixmodules/nixos/desktop/virtual-machine.nixmodules/nixos/encrypted-root.nixmodules/nixos/laptop/default.nixmodules/nixos/proxies.nixmodules/nixos/server/default.nixmodules/nixos/server/proxy/kanidm.nixmodules/nixos/server/tests.nixmodules/nixos/shared/core.nixmodules/nixos/shared/core/auto-upgrade.nixmodules/nixos/shared/core/boot/default.nixmodules/nixos/shared/core/boot/quietboot.nixmodules/nixos/shared/core/boot/secureboot.nixmodules/nixos/shared/core/boot/systemd-boot.nixmodules/nixos/shared/core/default.nixmodules/nixos/shared/core/hardware/backlight.nixmodules/nixos/shared/core/hardware/biometrics.nixmodules/nixos/shared/core/hardware/bluetooth.nixmodules/nixos/shared/core/hardware/cooling.nixmodules/nixos/shared/core/hardware/default.nixmodules/nixos/shared/core/hardware/display.nixmodules/nixos/shared/core/hardware/graphics.nixmodules/nixos/shared/core/hardware/openrgb.nixmodules/nixos/shared/core/hardware/storage/default.nixmodules/nixos/shared/core/hardware/storage/ephemeral.nixmodules/nixos/shared/core/hardware/storage/maintenance.nixmodules/nixos/shared/core/hardware/storage/partitions/btrfs.nixmodules/nixos/shared/core/hardware/storage/partitions/esp.nixmodules/nixos/shared/core/hardware/storage/partitions/luks.nixmodules/nixos/shared/core/hardware/storage/partitions/tmpfs.nixmodules/nixos/shared/core/host/default.nixmodules/nixos/shared/core/host/device.nixmodules/nixos/shared/core/host/persistence.nixmodules/nixos/shared/default.nixmodules/nixos/shared/features/display-manager.nixmodules/nixos/shared/features/hm-helper/1password.nixmodules/nixos/shared/features/hm-helper/default.nixmodules/nixos/shared/features/hm-helper/kde-connect.nixmodules/nixos/shared/features/hm-helper/mpv.nixmodules/nixos/shared/features/hm-helper/nautilus.nixmodules/nixos/shared/features/remote.nixmodules/nixos/shared/services/default.nixmodules/nixos/shared/services/huntress.nixmodules/nixos/shared/services/mcpo.nixmodules/nixos/shared/services/metrics.nixmodules/nixos/shared/services/tailscale.nixtests/default.nixtests/lib.nixtests/mkNode.nix
💤 Files with no reviewable changes (4)
- modules/nixos/default.nix
- modules/nixos/encrypted-root.nix
- modules/nixos/proxies.nix
- modules/nixos/shared/core.nix
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: Build nixosConfigurations.nixmi.config.system.build.toplevel on x86_64-linux
- GitHub Check: Build nixosConfigurations.nixarr.config.system.build.toplevel on x86_64-linux
- GitHub Check: Build nixosConfigurations.nixdev.config.system.build.toplevel on x86_64-linux
- GitHub Check: Build nixosConfigurations.nixcloud.config.system.build.toplevel on x86_64-linux
- GitHub Check: Build nixosConfigurations.nixio.config.system.build.toplevel on x86_64-linux
- GitHub Check: Build homeConfigurations.racci.activationPackage on x86_64-linux
- GitHub Check: Build nixosConfigurations.nixmon.config.system.build.toplevel on x86_64-linux
- GitHub Check: Build nixosConfigurations.nixserv.config.system.build.toplevel on x86_64-linux
- GitHub Check: Build nixosConfigurations.nixai.config.system.build.toplevel on x86_64-linux
- GitHub Check: Mergify Merge Protections
- GitHub Check: Summary
🧰 Additional context used
📓 Path-based instructions (15)
**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/building/SKILL.md)
Use
nix fmtto format Nix code and check syntax
**/*.nix: Runnix fmt <paths...>after making any changes to ensure consistent formatting
Use 2 spaces for indentation in Nix files
Use kebab-case for Nix file and directory names
Use camelCase for Nix attributes (e.g.,myOption,enableFeature)
Use camelCase for Nix option paths (e.g.,services.myService.enable)
Prefer minimal comments; code should be self-explanatory, using comments to explain why, not what
Prefer relative imports over absolute imports (e.g.,./modules/foo.nix)
Group imports at the top of the Nix file and use list format for multiple imports
When generating JSON, YAML, or other structured formats, define as Nix attribute sets and convert using builtins functions (e.g.,builtins.toJSON), rather than using inline string literals
Follow the standard module structure pattern withconfig,lib,pkgsdestructuring,letbindings for module configuration, andoptions/configsections
Useletbindings withinheritfor importing functions from libraries (e.g.,inherit (lib) mkIf mkEnableOption)Run
nix fmtto format code before submitting changes
**/*.nix: Usebuiltins.traceto add trace statements for seeing values during Nix evaluation, withbuiltins.toJSONfor complex attribute sets
Check for circular dependencies in imports or option definitions as the root cause of infinite recursion errors in Nix
Verify attribute names, imports, and option paths to resolve 'attribute missing' errors in Nix configurationsRun
nix fmton changed Nix files after modifying modules
**/*.nix: Declare secrets in Nix usingsops.secretswith the secret path as the key
Specify custom permissions for secrets usingowner,group, andmodeattributes in sops.secrets declarations
Usesops.templatesto combine multiple secrets into configuration files with placeholders
AddrestartUnitsto secret declarations to automatically restart services when secrets change
Use empty `k...
Files:
modules/nixos/shared/default.nixmodules/home-manager/services/mcpo.nixlib/builders/mkSystem.nixtests/lib.nixmodules/nixos/server/proxy/kanidm.nixmodules/nixos/desktop/default.nixmodules/nixos/desktop/virtual-machine.nixhome/shared/desktop/gnome/default.nixhome/shared/applications/media.nixmodules/nixos/server/default.nixflake/ci/flake-module.nixmodules/nixos/laptop/default.nixflake/default.nixtests/mkNode.nixmodules/nixos/server/tests.nixmodules/nixos/shared/core/default.nixtests/default.nix
modules/nixos/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/modules/SKILL.md)
Create NixOS modules at
modules/nixos/<category>/<name>.nixwith standard pattern including options definition, lib imports (mkEnableOption, mkOption, mkIf, types), config variable binding, and conditional config application using mkIf
Files:
modules/nixos/shared/default.nixmodules/nixos/server/proxy/kanidm.nixmodules/nixos/desktop/default.nixmodules/nixos/desktop/virtual-machine.nixmodules/nixos/server/default.nixmodules/nixos/laptop/default.nixmodules/nixos/server/tests.nixmodules/nixos/shared/core/default.nix
modules/nixos/*/default.nix
📄 CodeRabbit inference engine (.opencode/skills/modules/SKILL.md)
Register NixOS modules in parent
default.nixusing imports list pattern:_: { imports = [ ./module-a.nix ./module-b.nix ]; }
Files:
modules/nixos/shared/default.nixmodules/nixos/desktop/default.nixmodules/nixos/server/default.nixmodules/nixos/laptop/default.nix
modules/nixos/**
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Reusable NixOS module fragments should be placed in
modules/nixos/directory
Files:
modules/nixos/shared/default.nixmodules/nixos/server/proxy/kanidm.nixmodules/nixos/desktop/default.nixmodules/nixos/desktop/virtual-machine.nixmodules/nixos/server/default.nixmodules/nixos/laptop/default.nixmodules/nixos/server/tests.nixmodules/nixos/shared/core/default.nix
modules/home-manager/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/modules/SKILL.md)
modules/home-manager/**/*.nix: Create Home-Manager modules atmodules/home-manager/<category>/<name>.nixwith osConfig parameter support and conditional config application using mkIf
Usepurpose.<category>namespace for use-case modules in Home-Manager modules
Usecustom.<name>namespace for custom extensions in Home-Manager modules
Useuser.<name>namespace for user-specific options in Home-Manager modules
Files:
modules/home-manager/services/mcpo.nix
modules/home-manager/**
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Reusable Home-Manager module fragments should be placed in
modules/home-manager/directory
Files:
modules/home-manager/services/mcpo.nix
lib/builders/**
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Custom system and home builders should be implemented in
lib/builders/directory withmkSystem.nixandmkHome.nixas entry points
Files:
lib/builders/mkSystem.nix
modules/nixos/server/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/modules/SKILL.md)
Use
server.<name>namespace for server cluster options in NixOS modules
Files:
modules/nixos/server/proxy/kanidm.nixmodules/nixos/server/default.nixmodules/nixos/server/tests.nix
home/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/contributing/SKILL.md)
Test at least one affected home configuration before submitting changes
Files:
home/shared/desktop/gnome/default.nixhome/shared/applications/media.nix
home/shared/**
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Shared Home-Manager configurations across all users should be placed in
home/shared/directory
Files:
home/shared/desktop/gnome/default.nixhome/shared/applications/media.nix
home/shared/desktop/**
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Shared desktop environment configurations should be in
home/shared/desktop/
Files:
home/shared/desktop/gnome/default.nix
home/shared/applications/**
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Shared application-specific Home-Manager configurations should be in
home/shared/applications/
Files:
home/shared/applications/media.nix
flake/ci/**
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
CI-specific flake definitions and scripts should be located in the
flake/ci/directory
Files:
flake/ci/flake-module.nix
docs/src/**/*.md
📄 CodeRabbit inference engine (.opencode/skills/docs/SKILL.md)
docs/src/**/*.md: Create or update Markdown files indocs/srcfollowing the documentation workflow: analyze changes, identify impact on documentation files, draft content with underscore filenames, updatedocs/src/SUMMARY.md, and verify Nix code examples are valid
Keep documentation explanations concise and focus on why something is configured a certain way rather than just what the code does
Files:
docs/src/modules/nixos/services.mddocs/src/modules/nixos/desktop.md
docs/**
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Project documentation should be maintained in the
docs/directory
Files:
docs/src/modules/nixos/services.mddocs/src/modules/nixos/desktop.md
🧠 Learnings (85)
📓 Common learnings
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/users/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:41.504Z
Learning: Applies to home/*/features/**/*.nix : User's feature modules should be organized in a `features/` directory within the user directory (`home/<username>/features/`)
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to modules/nixos/** : Reusable NixOS module fragments should be placed in `modules/nixos/` directory
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/code-style/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:22.881Z
Learning: Applies to **/*.nix : Follow the standard module structure pattern with `config`, `lib`, `pkgs` destructuring, `let` bindings for module configuration, and `options`/`config` sections
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to hosts/shared/optional/** : Optional NixOS features (gaming, containers, etc.) should be organized in `hosts/shared/optional/`
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/nixos/**/*.nix : Create NixOS modules at `modules/nixos/<category>/<name>.nix` with standard pattern including options definition, lib imports (mkEnableOption, mkOption, mkIf, types), config variable binding, and conditional config application using mkIf
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to home/shared/features/** : Shared feature modules (CLI tools, features, etc.) should be in `home/shared/features/`
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/nixos/default.nix : Export module categories from top-level `modules/nixos/default.nix` as attribute set with structure: `{ boot = import ./boot; hardware = import ./hardware; services = import ./services; }`
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to modules/nixos/default.nix : NixOS modules should be exported through `modules/nixos/default.nix`
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to flake/nixos/** : NixOS flake modules should be organized in the `flake/nixos/` directory
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/nixos/server/**/*.nix : Use `server.<name>` namespace for server cluster options in NixOS modules
📚 Learning: 2026-03-01T12:25:06.603Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/nixos/*/default.nix : Register NixOS modules in parent `default.nix` using imports list pattern: `_: { imports = [ ./module-a.nix ./module-b.nix ]; }`
Applied to files:
modules/nixos/shared/default.nixlib/builders/mkSystem.nixmodules/nixos/desktop/default.nixmodules/nixos/server/default.nixmodules/nixos/laptop/default.nixmodules/nixos/shared/core/default.nix
📚 Learning: 2026-03-01T12:26:14.740Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to modules/nixos/default.nix : NixOS modules should be exported through `modules/nixos/default.nix`
Applied to files:
modules/nixos/shared/default.nixmodules/home-manager/services/mcpo.nixlib/builders/mkSystem.nixmodules/nixos/desktop/default.nixmodules/nixos/server/default.nixdocs/src/modules/nixos/services.mdmodules/nixos/laptop/default.nixtests/mkNode.nixmodules/nixos/shared/core/default.nixdocs/src/modules/nixos/desktop.mdtests/default.nix
📚 Learning: 2026-03-01T12:25:06.603Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/nixos/default.nix : Export module categories from top-level `modules/nixos/default.nix` as attribute set with structure: `{ boot = import ./boot; hardware = import ./hardware; services = import ./services; }`
Applied to files:
modules/nixos/shared/default.nixmodules/nixos/desktop/default.nixmodules/nixos/server/default.nixdocs/src/modules/nixos/services.mdmodules/nixos/laptop/default.nixtests/mkNode.nixmodules/nixos/server/tests.nixmodules/nixos/shared/core/default.nixdocs/src/modules/nixos/desktop.md
📚 Learning: 2026-03-01T12:25:06.603Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/home-manager/*/default.nix : Register Home-Manager modules in parent `default.nix` using imports list pattern
Applied to files:
modules/nixos/shared/default.nixmodules/home-manager/services/mcpo.nixlib/builders/mkSystem.nixmodules/nixos/desktop/default.nixmodules/nixos/server/default.nixdocs/src/modules/nixos/services.mdmodules/nixos/laptop/default.nixmodules/nixos/shared/core/default.nixdocs/src/modules/nixos/desktop.md
📚 Learning: 2026-03-01T12:24:22.881Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/code-style/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:22.881Z
Learning: Applies to **/*.nix : Prefer relative imports over absolute imports (e.g., `./modules/foo.nix`)
Applied to files:
modules/nixos/shared/default.nixmodules/home-manager/services/mcpo.nixlib/builders/mkSystem.nixmodules/nixos/desktop/default.nixmodules/nixos/server/default.nixmodules/nixos/laptop/default.nix
📚 Learning: 2026-03-01T12:26:14.740Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to modules/home-manager/default.nix : Home-Manager modules should be exported through `modules/home-manager/default.nix`
Applied to files:
modules/nixos/shared/default.nixmodules/home-manager/services/mcpo.nixlib/builders/mkSystem.nixmodules/nixos/desktop/default.nixdocs/src/modules/nixos/services.mdmodules/nixos/laptop/default.nixtests/mkNode.nixmodules/nixos/shared/core/default.nixdocs/src/modules/nixos/desktop.md
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Prefer relative imports (e.g., `./modules/foo.nix`) over absolute paths
Applied to files:
modules/nixos/shared/default.nixmodules/home-manager/services/mcpo.nixlib/builders/mkSystem.nixmodules/nixos/desktop/default.nixmodules/nixos/laptop/default.nix
📚 Learning: 2026-03-01T12:24:57.319Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/hosts/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:57.319Z
Learning: Applies to hosts/{server,desktop,laptop}/*/default.nix : Host `default.nix` files must import `${modulesPath}/virtualisation/proxmox-lxc.nix` for LXC containers or `./hardware.nix` for physical machines
Applied to files:
modules/nixos/shared/default.nixmodules/nixos/desktop/default.nixmodules/nixos/laptop/default.nixtests/mkNode.nixdocs/src/modules/nixos/desktop.mdtests/default.nix
📚 Learning: 2026-03-01T12:25:06.603Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/nixos/services/**/*.nix : Use `services.<name>` namespace for system services in NixOS modules
Applied to files:
modules/nixos/shared/default.nixmodules/home-manager/services/mcpo.nixdocs/src/modules/nixos/services.md
📚 Learning: 2026-03-01T12:26:51.425Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/ci-failure.md:0-0
Timestamp: 2026-03-01T12:26:51.425Z
Learning: Applies to **/*.nix : Check for infinite recursion by examining recent changes for circular imports between modules or option definitions that reference themselves
Applied to files:
modules/nixos/shared/default.nixlib/builders/mkSystem.nixmodules/nixos/server/default.nix
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Avoid hardcoded paths that should be configurable options
Applied to files:
modules/nixos/shared/default.nixmodules/nixos/desktop/virtual-machine.nixhome/shared/applications/media.nixmodules/nixos/server/default.nixmodules/nixos/shared/core/default.nix
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Group imports at the top of the file and use list format for multiple imports
Applied to files:
modules/nixos/shared/default.nixmodules/nixos/desktop/default.nixmodules/nixos/laptop/default.nix
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Ensure all used functions are properly inherited to avoid circular imports and hidden dependencies
Applied to files:
modules/nixos/shared/default.nixtests/lib.nixmodules/nixos/desktop/default.nixhome/shared/desktop/gnome/default.nixhome/shared/applications/media.nixmodules/nixos/server/default.nixmodules/nixos/laptop/default.nixtests/mkNode.nix
📚 Learning: 2026-03-01T12:26:01.611Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/packages/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:01.611Z
Learning: Applies to overlays/default.nix : Expose custom packages via overlays/default.nix by importing the pkgs directory with inputs, lib, and pkgs parameters
Applied to files:
modules/nixos/shared/default.nixmodules/nixos/desktop/default.nix
📚 Learning: 2026-03-01T12:24:22.881Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/code-style/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:22.881Z
Learning: Applies to **/*.nix : Group imports at the top of the Nix file and use list format for multiple imports
Applied to files:
modules/nixos/shared/default.nixmodules/nixos/desktop/default.nixmodules/nixos/laptop/default.nix
📚 Learning: 2026-03-01T12:24:22.881Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/code-style/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:22.881Z
Learning: Applies to **/*.nix : Follow the standard module structure pattern with `config`, `lib`, `pkgs` destructuring, `let` bindings for module configuration, and `options`/`config` sections
Applied to files:
modules/nixos/shared/default.nixmodules/nixos/server/default.nixdocs/src/modules/nixos/services.mdmodules/nixos/server/tests.nixmodules/nixos/shared/core/default.nix
📚 Learning: 2026-03-01T12:24:22.881Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/code-style/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:22.881Z
Learning: Applies to **/*.nix : Use camelCase for Nix option paths (e.g., `services.myService.enable`)
Applied to files:
modules/nixos/shared/default.nixdocs/src/modules/nixos/services.md
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Ensure all required options are defined before use in configuration blocks
Applied to files:
modules/nixos/shared/default.nixmodules/nixos/server/default.nixmodules/nixos/shared/core/default.nix
📚 Learning: 2026-03-01T12:26:41.504Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/users/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:41.504Z
Learning: Applies to home/*/hm-config.nix : Import shared user configurations from `home/shared/` directories in user configs: use `../shared/global/` for configs applied to all users, `../shared/applications/` for application configs, `../shared/desktop/` for desktop environment configs, and `../shared/features/cli/` for CLI tool configurations
Applied to files:
modules/home-manager/services/mcpo.nixlib/builders/mkSystem.nixmodules/nixos/desktop/default.nixmodules/nixos/laptop/default.nix
📚 Learning: 2026-03-01T12:24:22.881Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/code-style/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:22.881Z
Learning: Applies to **/*.nix : Use `let` bindings with `inherit` for importing functions from libraries (e.g., `inherit (lib) mkIf mkEnableOption`)
Applied to files:
modules/home-manager/services/mcpo.nixmodules/nixos/shared/core/default.nix
📚 Learning: 2026-03-01T12:26:01.611Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/packages/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:01.611Z
Learning: Applies to pkgs/*/default.nix : For multi-output packages, use a let binding to define multiple outputs and register them with inherit syntax in pkgs/default.nix
Applied to files:
modules/home-manager/services/mcpo.nix
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Always use `inherit` to bring functions and values into scope instead of manual assignment
Applied to files:
modules/home-manager/services/mcpo.nix
📚 Learning: 2026-03-01T12:24:57.319Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/hosts/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:57.319Z
Learning: Applies to hosts/{desktop,laptop}/*/hardware.nix : Physical hardware configurations should import appropriate modules from `inputs.nixos-hardware` (e.g., CPU, SSD, GPU modules) in `hardware.nix`
Applied to files:
modules/home-manager/services/mcpo.nixlib/builders/mkSystem.nixmodules/nixos/desktop/default.nixmodules/nixos/desktop/virtual-machine.nixflake/ci/flake-module.nixmodules/nixos/laptop/default.nixtests/mkNode.nixmodules/nixos/shared/core/default.nixdocs/src/modules/nixos/desktop.md
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Follow the standard NixOS module structure pattern with config, lib, pkgs parameters and proper `let`/`in` blocks
Applied to files:
modules/home-manager/services/mcpo.nixmodules/nixos/shared/core/default.nix
📚 Learning: 2026-03-01T12:25:06.603Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/nixos/host/**/*.nix : Use `host.<name>` namespace for host-specific options in NixOS modules
Applied to files:
modules/home-manager/services/mcpo.nixmodules/nixos/desktop/virtual-machine.nixdocs/src/modules/nixos/services.mdtests/mkNode.nixmodules/nixos/server/tests.nix
📚 Learning: 2026-03-01T12:26:14.740Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to lib/builders/** : Custom system and home builders should be implemented in `lib/builders/` directory with `mkSystem.nix` and `mkHome.nix` as entry points
Applied to files:
lib/builders/mkSystem.nix
📚 Learning: 2026-03-01T12:27:25.837Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/test.md:0-0
Timestamp: 2026-03-01T12:27:25.837Z
Learning: For changes affecting only hosts, build at least one affected host configuration using 'nix build .#nixosConfigurations.<hostname>.config.system.build.toplevel'
Applied to files:
lib/builders/mkSystem.nixflake/ci/flake-module.nix
📚 Learning: 2026-03-01T12:26:41.504Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/users/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:41.504Z
Learning: Applies to home/*/hm-config.nix : Create `hm-config.nix` in `home/<username>/` as the main Home-Manager entry point containing shared configuration across all hosts for that user
Applied to files:
lib/builders/mkSystem.nixdocs/src/modules/nixos/services.md
📚 Learning: 2026-03-01T12:25:06.603Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/home-manager/**/*.nix : Use `user.<name>` namespace for user-specific options in Home-Manager modules
Applied to files:
lib/builders/mkSystem.nixdocs/src/modules/nixos/services.md
📚 Learning: 2026-03-01T12:26:41.504Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/users/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:41.504Z
Learning: Applies to home/*/features/**/*.nix : User's feature modules should be organized in a `features/` directory within the user directory (`home/<username>/features/`)
Applied to files:
lib/builders/mkSystem.nixmodules/nixos/laptop/default.nix
📚 Learning: 2026-03-01T12:26:41.504Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/users/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:41.504Z
Learning: Applies to home/*/[!.]*@(hm-config|os-config|secrets).nix : Create host-specific configuration files named `<hostname>.nix` in the user directory (`home/<username>/<hostname>.nix`), containing Home-Manager configuration with user-specific git settings, imports of shared features, and host-specific customizations
Applied to files:
lib/builders/mkSystem.nixflake/default.nix
📚 Learning: 2026-03-01T12:26:25.327Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/secrets/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:25.327Z
Learning: Applies to **/*.nix : Declare secrets in Nix using `sops.secrets` with the secret path as the key
Applied to files:
lib/builders/mkSystem.nix
📚 Learning: 2026-03-01T12:24:57.319Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/hosts/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:57.319Z
Learning: Applies to hosts/{desktop,laptop}/*/hardware.nix : Hardware configurations must define filesystem mount points with device labels and filesystem types (e.g., `fileSystems./`)
Applied to files:
modules/nixos/desktop/virtual-machine.nix
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Verify option type definitions match their usage and configuration values
Applied to files:
modules/nixos/desktop/virtual-machine.nixflake/default.nix
📚 Learning: 2026-03-01T12:26:51.425Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/ci-failure.md:0-0
Timestamp: 2026-03-01T12:26:51.425Z
Learning: Applies to **/*.nix : Verify type mismatches by checking option type definitions and the value being provided in NixOS options
Applied to files:
modules/nixos/desktop/virtual-machine.nix
📚 Learning: 2026-03-01T12:24:38.213Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/debugging/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:38.213Z
Learning: Applies to **/*.nix : Verify attribute names, imports, and option paths to resolve 'attribute missing' errors in Nix configurations
Applied to files:
modules/nixos/desktop/virtual-machine.nixmodules/nixos/server/default.nixflake/default.nixtests/mkNode.nixmodules/nixos/shared/core/default.nix
📚 Learning: 2026-03-01T12:26:14.740Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to hosts/{desktop,laptop,server}/** : Per-machine NixOS configurations should be organized in `hosts/<type>/<hostname>/` where type is desktop, laptop, or server
Applied to files:
modules/nixos/desktop/virtual-machine.nixflake/ci/flake-module.nix
📚 Learning: 2026-03-01T12:26:14.740Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to hosts/{desktop,laptop,server}/*/default.nix : Host system configurations should follow the pattern `hosts/<type>/<hostname>/default.nix`
Applied to files:
modules/nixos/desktop/virtual-machine.nixflake/ci/flake-module.nixtests/mkNode.nixdocs/src/modules/nixos/desktop.mdtests/default.nix
📚 Learning: 2026-03-01T12:24:22.881Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/code-style/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:22.881Z
Learning: Applies to **/*.nix : Use camelCase for Nix attributes (e.g., `myOption`, `enableFeature`)
Applied to files:
modules/nixos/desktop/virtual-machine.nix
📚 Learning: 2026-03-01T12:24:29.910Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/contributing/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:29.910Z
Learning: Applies to **/*.nix : Run `nix fmt` to format code before submitting changes
Applied to files:
home/shared/desktop/gnome/default.nixhome/shared/applications/media.nix
📚 Learning: 2026-03-01T12:27:25.837Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/test.md:0-0
Timestamp: 2026-03-01T12:27:25.837Z
Learning: Applies to **/*.nix : Always ensure formatting is correct by running 'nix fmt' on changed files
Applied to files:
home/shared/desktop/gnome/default.nixhome/shared/applications/media.nix
📚 Learning: 2026-03-01T12:26:51.425Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/ci-failure.md:0-0
Timestamp: 2026-03-01T12:26:51.425Z
Learning: Applies to **/*.nix : Run `nix fmt <changed-files>` to fix Nix formatting failures in CI checks
Applied to files:
home/shared/desktop/gnome/default.nixhome/shared/applications/media.nix
📚 Learning: 2026-03-01T12:25:06.603Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to **/*.nix : Run `nix fmt` on changed Nix files after modifying modules
Applied to files:
home/shared/desktop/gnome/default.nixhome/shared/applications/media.nix
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Code MUST pass `nix fmt` formatting validation
Applied to files:
home/shared/desktop/gnome/default.nixhome/shared/applications/media.nixmodules/nixos/server/default.nix
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Remove unused let bindings
Applied to files:
home/shared/desktop/gnome/default.nixhome/shared/applications/media.nix
📚 Learning: 2026-03-01T12:24:22.881Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/code-style/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:22.881Z
Learning: Applies to **/*.nix : Run `nix fmt <paths...>` after making any changes to ensure consistent formatting
Applied to files:
home/shared/desktop/gnome/default.nix
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Use intermediate bindings instead of deeply nested attribute access for improved readability
Applied to files:
home/shared/desktop/gnome/default.nixhome/shared/applications/media.nixmodules/nixos/server/default.nix
📚 Learning: 2026-03-01T12:24:29.910Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/contributing/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:29.910Z
Learning: Applies to home/**/*.nix : Test at least one affected home configuration before submitting changes
Applied to files:
home/shared/desktop/gnome/default.nixhome/shared/applications/media.nixmodules/nixos/server/default.nixflake/ci/flake-module.nixflake/default.nixtests/mkNode.nixtests/default.nix
📚 Learning: 2026-03-01T12:25:06.603Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/nixos/server/**/*.nix : Use `server.<name>` namespace for server cluster options in NixOS modules
Applied to files:
modules/nixos/server/default.nixdocs/src/modules/nixos/services.mdtests/mkNode.nixmodules/nixos/server/tests.nixtests/default.nix
📚 Learning: 2026-03-01T12:26:31.937Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/testing/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:31.937Z
Learning: Run `nix build .#nixosConfigurations.<hostname>.config.system.build.toplevel` to test a host configuration
Applied to files:
modules/nixos/server/default.nixflake/ci/flake-module.nixtests/mkNode.nixtests/default.nix
📚 Learning: 2026-03-01T12:24:57.319Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/hosts/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:57.319Z
Learning: Applies to hosts/{server,desktop,laptop}/*/default.nix : Each host requires a `default.nix` file as the main configuration entry point
Applied to files:
modules/nixos/server/default.nixtests/mkNode.nixdocs/src/modules/nixos/desktop.mdtests/default.nix
📚 Learning: 2026-03-01T12:27:29.965Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-01T12:27:29.965Z
Learning: Applies to **/*.nix : All affected configurations MUST be tested before completing any task, using the test agent and testing skill to identify affected configurations
Applied to files:
modules/nixos/server/default.nixflake/ci/flake-module.nixtests/default.nix
📚 Learning: 2026-03-01T12:24:29.910Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/contributing/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:29.910Z
Learning: Applies to hosts/**/*.nix : Test at least one affected host configuration before submitting changes
Applied to files:
modules/nixos/server/default.nixflake/ci/flake-module.nixtests/default.nix
📚 Learning: 2026-03-01T12:26:14.740Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to flake.nix : Top-level flake definitions and inputs/outputs configuration should be placed in `flake.nix`
Applied to files:
flake/ci/flake-module.nixflake/default.nix
📚 Learning: 2026-03-01T12:27:25.837Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/test.md:0-0
Timestamp: 2026-03-01T12:27:25.837Z
Learning: For flake.nix or flake.lock changes, run a full flake check in addition to building representative configs
Applied to files:
flake/ci/flake-module.nixflake/default.nix
📚 Learning: 2026-03-01T12:24:29.910Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/contributing/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:29.910Z
Learning: Applies to {flake.nix,flake.lock} : Run `nix flake check` (with devenv-root override) before submitting changes
Applied to files:
flake/ci/flake-module.nixflake/default.nix
📚 Learning: 2026-03-01T12:26:14.740Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to flake/nixos/** : NixOS flake modules should be organized in the `flake/nixos/` directory
Applied to files:
flake/ci/flake-module.nix
📚 Learning: 2026-03-01T12:24:57.319Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/hosts/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:57.319Z
Learning: Applies to flake/nixos/flake-module.nix : For CUDA or ROCm hardware acceleration support, register the host in `flake/nixos/flake-module.nix` under the appropriate `accelerationHosts` category
Applied to files:
flake/ci/flake-module.nix
📚 Learning: 2026-03-01T12:26:51.425Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/ci-failure.md:0-0
Timestamp: 2026-03-01T12:26:51.425Z
Learning: Applies to flake.nix : Use `./flake/ci/detect-affected-outputs.nu nixosConfigurations --json` and `./flake/ci/detect-affected-outputs.nu homeConfigurations --json` to identify which outputs are affected by dirty files in CI
Applied to files:
flake/ci/flake-module.nixflake/default.nix
📚 Learning: 2026-03-01T12:24:57.319Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/hosts/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:57.319Z
Learning: Host auto-discovery scans `hosts/` for subdirectories, filters out `shared/` and `secrets.yaml`, and automatically registers each as a nixosConfiguration
Applied to files:
flake/ci/flake-module.nix
📚 Learning: 2026-03-01T12:26:51.425Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/ci-failure.md:0-0
Timestamp: 2026-03-01T12:26:51.425Z
Learning: Applies to **/*.nix : Use `nix eval .#nixosConfigurations.<host>.config.system.build.toplevel --apply 'x: "ok"'` to check if Nix expressions evaluate correctly
Applied to files:
flake/ci/flake-module.nixflake/default.nixtests/default.nix
📚 Learning: 2026-03-01T12:24:15.388Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/building/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:15.388Z
Learning: Build a host's NixOS system using `nix build .#nixosConfigurations.<host>.config.system.build.toplevel`
Applied to files:
flake/ci/flake-module.nixtests/mkNode.nix
📚 Learning: 2026-03-01T12:27:16.409Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/security.md:0-0
Timestamp: 2026-03-01T12:27:16.409Z
Learning: Applies to **/*.nix : Apply systemd hardening options (DynamicUser, ProtectSystem, ProtectHome, PrivateTmp, NoNewPrivileges, CapabilityBoundingSet, RestrictNamespaces, RestrictRealtime, RestrictSUIDSGID, MemoryDenyWriteExecute, LockPersonality) to service definitions
Applied to files:
docs/src/modules/nixos/services.md
📚 Learning: 2026-03-01T12:26:14.740Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to hosts/shared/optional/** : Optional NixOS features (gaming, containers, etc.) should be organized in `hosts/shared/optional/`
Applied to files:
docs/src/modules/nixos/services.mdmodules/nixos/laptop/default.nixmodules/nixos/shared/core/default.nixdocs/src/modules/nixos/desktop.md
📚 Learning: 2026-03-01T12:25:06.603Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/home-manager/**/*.nix : Create Home-Manager modules at `modules/home-manager/<category>/<name>.nix` with osConfig parameter support and conditional config application using mkIf
Applied to files:
docs/src/modules/nixos/services.md
📚 Learning: 2026-03-01T12:25:06.603Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/home-manager/**/*.nix : Use `custom.<name>` namespace for custom extensions in Home-Manager modules
Applied to files:
docs/src/modules/nixos/services.md
📚 Learning: 2026-03-01T12:25:06.603Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/nixos/**/*.nix : Create NixOS modules at `modules/nixos/<category>/<name>.nix` with standard pattern including options definition, lib imports (mkEnableOption, mkOption, mkIf, types), config variable binding, and conditional config application using mkIf
Applied to files:
docs/src/modules/nixos/services.mdtests/mkNode.nixmodules/nixos/server/tests.nixmodules/nixos/shared/core/default.nix
📚 Learning: 2026-03-01T12:26:51.425Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/ci-failure.md:0-0
Timestamp: 2026-03-01T12:26:51.425Z
Learning: Applies to flake.{nix,lock} : Verify `flake.lock` conflicts by checking if inputs were updated and ensuring compatibility between updated inputs
Applied to files:
flake/default.nix
📚 Learning: 2026-03-01T12:24:38.213Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/debugging/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:38.213Z
Learning: Use `nix flake check --no-build` to verify flake syntax validity without building
Applied to files:
flake/default.nix
📚 Learning: 2026-03-01T12:26:31.937Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/testing/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:31.937Z
Learning: Run `nix flake check --override-input devenv-root "file+file://$PWD/.devenv/root"` to perform a full flake check
Applied to files:
flake/default.nix
📚 Learning: 2026-03-01T12:24:15.388Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/building/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:15.388Z
Learning: Use `nix flake check` to evaluate all configurations and run linters
Applied to files:
flake/default.nix
📚 Learning: 2026-03-01T12:27:25.837Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/test.md:0-0
Timestamp: 2026-03-01T12:27:25.837Z
Learning: Use 'nix eval .#homeConfigurations --apply "builtins.attrNames"' to list available home configurations
Applied to files:
flake/default.nix
📚 Learning: 2026-03-01T12:27:25.837Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/test.md:0-0
Timestamp: 2026-03-01T12:27:25.837Z
Learning: Use 'nix eval .#nixosConfigurations --apply "builtins.attrNames"' to list available host configurations
Applied to files:
flake/default.nixtests/mkNode.nix
📚 Learning: 2026-03-01T12:26:51.425Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/ci-failure.md:0-0
Timestamp: 2026-03-01T12:26:51.425Z
Learning: Applies to **/*.nix : Use `nix eval .#nixosConfigurations.<host>.config.services --apply 'builtins.attrNames'` to diagnose 'attribute not found' errors by listing available attributes
Applied to files:
flake/default.nix
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Always use `mkIf` guards on config sections that are conditionally applied
Applied to files:
flake/default.nix
📚 Learning: 2026-03-01T12:26:51.425Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/ci-failure.md:0-0
Timestamp: 2026-03-01T12:26:51.425Z
Learning: Applies to **/*.nix : When a new module isn't being found, verify the imports list in the parent module, check that the file path is correct (use kebab-case), and ensure the module is syntactically valid
Applied to files:
tests/mkNode.nix
📚 Learning: 2026-03-01T12:24:57.319Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/hosts/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:57.319Z
Learning: Applies to hosts/server/*/default.nix : Server hosts must set `host.device.isHeadless = true` in their configuration
Applied to files:
tests/mkNode.nix
📚 Learning: 2026-03-01T12:26:14.740Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to modules/nixos/** : Reusable NixOS module fragments should be placed in `modules/nixos/` directory
Applied to files:
modules/nixos/server/tests.nix
📚 Learning: 2026-03-01T12:26:14.740Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to pkgs/default.nix : Custom packages should export their definitions through `pkgs/default.nix`
Applied to files:
modules/nixos/shared/core/default.nixtests/default.nix
📚 Learning: 2026-03-01T12:27:02.914Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/agent/nix-review.md:0-0
Timestamp: 2026-03-01T12:27:02.914Z
Learning: Applies to **/*.nix : Use `mkDefault`, `mkForce`, and `mkOverride` correctly to control option priority
Applied to files:
modules/nixos/shared/core/default.nixtests/default.nix
📚 Learning: 2026-03-01T12:25:06.603Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/modules/SKILL.md:0-0
Timestamp: 2026-03-01T12:25:06.603Z
Learning: Applies to modules/nixos/hardware/**/*.nix : Use `hardware.<name>` namespace for hardware configuration in NixOS modules
Applied to files:
docs/src/modules/nixos/desktop.md
📚 Learning: 2026-03-01T12:24:57.319Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/hosts/SKILL.md:0-0
Timestamp: 2026-03-01T12:24:57.319Z
Learning: Applies to hosts/{desktop,laptop}/*/hardware.nix : Physical host machines (desktops/laptops) must include a `hardware.nix` file with hardware-specific configuration
Applied to files:
docs/src/modules/nixos/desktop.md
📚 Learning: 2026-03-01T12:26:14.740Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/project-structure/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:14.740Z
Learning: Applies to home/shared/desktop/** : Shared desktop environment configurations should be in `home/shared/desktop/`
Applied to files:
docs/src/modules/nixos/desktop.md
📚 Learning: 2026-03-01T12:26:01.610Z
Learnt from: CR
Repo: DaRacci/nix-config PR: 0
File: .opencode/skills/packages/SKILL.md:0-0
Timestamp: 2026-03-01T12:26:01.610Z
Learning: Applies to pkgs/*/default.nix : Each package should have its own directory under pkgs/ with a default.nix file containing the package definition
Applied to files:
tests/default.nix
| imports = [ | ||
| (import "${self}/modules/flake/apply/system.nix" { | ||
| inherit allocations hostName; | ||
| deviceType = "server"; | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -e
echo '== tests/mkNode.nix =='
sed -n '1,80p' tests/mkNode.nix
echo
echo '== lib/builders/mkSystem.nix =='
sed -n '30,70p' lib/builders/mkSystem.nixRepository: DaRacci/nix-config
Length of output: 1518
Build each test node from the real host module stack.
The test node only imports modules/flake/apply/system.nix, whilst the production builder (lib/builders/mkSystem.nix) includes all nixos modules, device-type modules, the host directory, and shared configuration modules. The cluster test will pass with near-empty VMs, failing to validate actual server configurations.
Either include the full module stack or reuse lib/builders/mkSystem.nix to ensure test parity with production builds.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tests/mkNode.nix` around lines 7 - 11, The test node import currently uses
only modules/flake/apply/system.nix causing tests to build minimal VMs; update
the imports to build test nodes with the full production module stack by either
reusing the existing builder lib/builders/mkSystem.nix or by expanding the
imports to include the NixOS modules, device-type modules, host directory and
shared config modules (preserve existing attributes like allocations, hostName
and deviceType). Locate the imports block that references
modules/flake/apply/system.nix and replace it with a call to
lib/builders/mkSystem.nix (or mirror its module list) so test VMs are built the
same way as production.
072e115 to
2a6a397
Compare
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
modules/nixos/desktop/virtual-machine.nix (1)
74-74:⚠️ Potential issue | 🔴 Critical
mkDocis not a standardlibfunction — this will cause evaluation failure.The
mkDocfunction used here does not exist innixpkgs.lib. This will throw an "attribute 'mkDoc' missing" error during evaluation. Use a plain string instead.🐛 Proposed fix
- description = mkDoc "The percentage of maxMemory to reserve for the host."; + description = "The percentage of maxMemory to reserve for the host.";🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@modules/nixos/desktop/virtual-machine.nix` at line 74, The description attribute for the virtual machine option uses a non-existent mkDoc function which will break evaluation; replace the use of mkDoc in the description assignment (the line containing description = mkDoc "The percentage of maxMemory to reserve for the host."; ) with a plain string literal (e.g. description = "The percentage of maxMemory to reserve for the host.";), ensuring no mkDoc references remain in the virtual-machine.nix option definition.modules/nixos/shared/core/printing.nix (1)
16-21:⚠️ Potential issue | 🟠 MajorWrap the enable assignment with
lib.mkDefaultfor consistency with othercustom.coretoggles.The
custom.core.audio,custom.core.bluetooth, andcustom.core.networkoptions indefault.nixdefine their defaults at the option level (lines 34–53). However,custom.core.printing.enablelacks a default in its option definition and instead assigns its value in the config section (line 18) withoutmkDefault. This creates an inconsistency: if a host-level configuration setscustom.core.printing.enablewithout usingmkDefault, both the module and host assignment would be at priority 100, causing a merge conflict. Wrap the assignment inlib.mkDefaultto allow host-level overrides to take precedence and align with NixOS module conventions.Suggested fix
config = mkMerge [ { - custom.core.printing.enable = config.host.device.role != "server" && !config.host.device.isVirtual; + custom.core.printing.enable = lib.mkDefault ( + config.host.device.role != "server" && !config.host.device.isVirtual + ); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@modules/nixos/shared/core/printing.nix` around lines 16 - 21, The config-level assignment for custom.core.printing.enable should be wrapped with lib.mkDefault to match other custom.core toggles; update the config = mkMerge block where custom.core.printing.enable is set (currently using config.host.device.role != "server" && !config.host.device.isVirtual) to instead call lib.mkDefault(...) so host-level overrides win and avoid merge-priority conflicts with option-level defaults (see related symbols: custom.core.printing.enable, lib.mkDefault, config = mkMerge, cfg.enable).
♻️ Duplicate comments (2)
modules/nixos/server/tests.nix (2)
10-11:⚠️ Potential issue | 🔴 CriticalImport type helpers from
lib.types, notlib.type.Line 10 and Line 11 currently pull types from
lib.type, which will fail evaluation in standard NixOS modules.Proposed fix
let - inherit (lib) type mkOption mkEnableOption; - inherit (type) submodule attrsOf either listOf str bool functionTo; + inherit (lib) mkEnableOption mkOption; + inherit (lib.types) attrsOf bool either functionTo listOf str submodule; in {#!/bin/bash # Verify current type-helper imports and whether any custom lib.type alias exists. rg -n -C2 --type=nix '\binherit\s+\(lib\)\s+type\b|\blib\.type\b|\blib\.types\b'Based on learnings: Verify attribute names, imports, and option paths to resolve attribute-missing errors in Nix configurations.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@modules/nixos/server/tests.nix` around lines 10 - 11, The module is importing type helpers from lib.type which is incorrect; change the imports to use lib.types so the type helpers (mkOption, mkEnableOption, submodule, attrsOf, either, listOf, str, bool, functionTo) are pulled from lib.types instead of lib.type and update both inherit statements accordingly to reference lib.types.
17-38:⚠️ Potential issue | 🔴 CriticalWrap
server.tests.unitsinmkOption.Line 17 assigns a raw type under
options; this needs to be an option declaration to evaluate correctly in the module system.Proposed fix
- units = attrsOf (submodule ({ name, ... }: { - options = { - name = mkOption { - type = str; - default = name; - description = '' - The name to give to this unit test. - This is used to enter into a subtest within the testScript of the cluster test. - ''; - }; - - testScript = mkOption { - type = either str (functionTo str); - description = '' - Python code to be ran within the subtest for this unit. - - If this is a function with one argument of this nodes config. - If this is a function with two arguments, the second argument is the entire cluster configuration. - ''; - }; - }; - })); + units = mkOption { + type = attrsOf (submodule ({ name, ... }: { + options = { + name = mkOption { + type = str; + default = name; + description = '' + The name to give to this unit test. + This is used to enter into a subtest within the testScript of the cluster test. + ''; + }; + + testScript = mkOption { + type = either str (functionTo str); + description = '' + Python code to be ran within the subtest for this unit. + + If this is a function with one argument of this nodes config. + If this is a function with two arguments, the second argument is the entire cluster configuration. + ''; + }; + }; + })); + default = { }; + };#!/bin/bash # Verify how attrsOf/submodule options are declared in this repo and in this file. rg -n -C3 --type=nix 'attrsOf\s*\(submodule|units\s*=\s*mkOption|units\s*=\s*attrsOf'As per coding guidelines, follow the standard NixOS module structure pattern with proper
optionsdeclarations.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@modules/nixos/server/tests.nix` around lines 17 - 38, The block assigning server.tests.units uses attrsOf(submodule(...)) directly under options instead of declaring it as an option; wrap the entire units value in a mkOption so it becomes a proper NixOS option declaration. Specifically, change the declaration of server.tests.units (the attrsOf(submodule({...}) value that defines options name and testScript) to be returned from mkOption with appropriate type (e.g., attrsOf _ or an attributeset of submodules) and include its existing nested options (name, testScript) as the option's documentation/type; ensure references to attrsOf, submodule, and the nested options name and testScript remain intact while replacing the raw value with mkOption(...) so the module system evaluates it correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@flake/ci/flake-module.nix`:
- Line 28: The partition allocations accessor is incorrect: change the inherited
path from config.partitions.nixos.module.allocations to
config.partitions.nixos.allocations; locate the inherit statement that
references (config.partitions.nixos.module) allocations and update it to inherit
from (config.partitions.nixos) allocations so it matches how the flake module is
merged and aligns with other accessors like config.partitions.docs.extraInputs.
In `@modules/home-manager/services/mcpo.nix`:
- Line 11: The import in modules/home-manager/services/mcpo.nix currently uses
the `${self}`-style absolute path in the expression `(import
"${self}/modules/nixos/shared/services/mcpo.nix" {` — replace that with a
file-relative import (e.g., `./modules/nixos/shared/services/mcpo.nix`) to
follow repo conventions; update the import expression in the same file by
changing the path string to the relative path so the module is loaded relative
to modules/home-manager/services/mcpo.nix rather than via `${self}`.
In `@modules/nixos/server/tests.nix`:
- Around line 13-42: The server.tests options are declared but never used;
update the test harness (tests/default.nix) to read the evaluated host config's
server.tests.* and build a composite testScript passed to runNixOSTest: iterate
over server.tests.units, call each unit's testScript (handling both string and
function signatures—1-arg node config or 2-arg node+cluster config) to produce
the per-host subtests, and respect server.tests.enable to skip wiring when
disabled; ensure the evaluated host config is threaded into the harness so
testScript functions receive the proper node/cluster args before invoking
runNixOSTest.
In `@modules/nixos/shared/core/default.nix`:
- Around line 58-62: Update the custom.defaultGroups list to use the correct
NetworkManager group name and avoid adding non-existent PipeWire group: replace
any occurrence of "network" in custom.defaultGroups with "networkmanager", and
only append "pipewire" to custom.defaultGroups when services.pipewire.systemWide
is true (guard the addition with that condition); apply the same change for the
other occurrence of custom.defaultGroups later in the file (the second block
around lines referenced in the review).
In `@tests/default.nix`:
- Line 24: Fix the typo in the comment string "Wait for all nodes to each
multi-user.target" by changing "each" to "reach" so it reads "Wait for all nodes
to reach multi-user.target"; update the comment where that exact phrase appears
to correct the wording.
- Line 12: The import binding testLib in tests/default.nix is unused; remove the
unused import statement (the line defining testLib = import ./lib.nix;) so the
file no longer creates an unused symbol and to avoid lint warnings.
---
Outside diff comments:
In `@modules/nixos/desktop/virtual-machine.nix`:
- Line 74: The description attribute for the virtual machine option uses a
non-existent mkDoc function which will break evaluation; replace the use of
mkDoc in the description assignment (the line containing description = mkDoc
"The percentage of maxMemory to reserve for the host."; ) with a plain string
literal (e.g. description = "The percentage of maxMemory to reserve for the
host.";), ensuring no mkDoc references remain in the virtual-machine.nix option
definition.
In `@modules/nixos/shared/core/printing.nix`:
- Around line 16-21: The config-level assignment for custom.core.printing.enable
should be wrapped with lib.mkDefault to match other custom.core toggles; update
the config = mkMerge block where custom.core.printing.enable is set (currently
using config.host.device.role != "server" && !config.host.device.isVirtual) to
instead call lib.mkDefault(...) so host-level overrides win and avoid
merge-priority conflicts with option-level defaults (see related symbols:
custom.core.printing.enable, lib.mkDefault, config = mkMerge, cfg.enable).
---
Duplicate comments:
In `@modules/nixos/server/tests.nix`:
- Around line 10-11: The module is importing type helpers from lib.type which is
incorrect; change the imports to use lib.types so the type helpers (mkOption,
mkEnableOption, submodule, attrsOf, either, listOf, str, bool, functionTo) are
pulled from lib.types instead of lib.type and update both inherit statements
accordingly to reference lib.types.
- Around line 17-38: The block assigning server.tests.units uses
attrsOf(submodule(...)) directly under options instead of declaring it as an
option; wrap the entire units value in a mkOption so it becomes a proper NixOS
option declaration. Specifically, change the declaration of server.tests.units
(the attrsOf(submodule({...}) value that defines options name and testScript) to
be returned from mkOption with appropriate type (e.g., attrsOf _ or an
attributeset of submodules) and include its existing nested options (name,
testScript) as the option's documentation/type; ensure references to attrsOf,
submodule, and the nested options name and testScript remain intact while
replacing the raw value with mkOption(...) so the module system evaluates it
correctly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 56811165-b6e5-477d-a481-a22044ea4ca2
📒 Files selected for processing (58)
docs/src/modules/nixos/desktop.mddocs/src/modules/nixos/services.mdflake/ci/flake-module.nixflake/default.nixlib/builders/mkSystem.nixmodules/home-manager/services/mcpo.nixmodules/nixos/default.nixmodules/nixos/desktop/default.nixmodules/nixos/desktop/rgb.nixmodules/nixos/desktop/vfio.nixmodules/nixos/desktop/virtual-machine.nixmodules/nixos/encrypted-root.nixmodules/nixos/laptop/default.nixmodules/nixos/proxies.nixmodules/nixos/server/default.nixmodules/nixos/server/tests.nixmodules/nixos/shared/core.nixmodules/nixos/shared/core/auto-upgrade.nixmodules/nixos/shared/core/boot/default.nixmodules/nixos/shared/core/boot/quietboot.nixmodules/nixos/shared/core/boot/secureboot.nixmodules/nixos/shared/core/boot/systemd-boot.nixmodules/nixos/shared/core/default.nixmodules/nixos/shared/core/hardware/backlight.nixmodules/nixos/shared/core/hardware/biometrics.nixmodules/nixos/shared/core/hardware/bluetooth.nixmodules/nixos/shared/core/hardware/cooling.nixmodules/nixos/shared/core/hardware/default.nixmodules/nixos/shared/core/hardware/display.nixmodules/nixos/shared/core/hardware/graphics.nixmodules/nixos/shared/core/hardware/openrgb.nixmodules/nixos/shared/core/hardware/storage/default.nixmodules/nixos/shared/core/hardware/storage/ephemeral.nixmodules/nixos/shared/core/hardware/storage/maintenance.nixmodules/nixos/shared/core/hardware/storage/partitions/btrfs.nixmodules/nixos/shared/core/hardware/storage/partitions/esp.nixmodules/nixos/shared/core/hardware/storage/partitions/luks.nixmodules/nixos/shared/core/hardware/storage/partitions/tmpfs.nixmodules/nixos/shared/core/host/default.nixmodules/nixos/shared/core/host/device.nixmodules/nixos/shared/core/host/persistence.nixmodules/nixos/shared/core/printing.nixmodules/nixos/shared/default.nixmodules/nixos/shared/features/display-manager.nixmodules/nixos/shared/features/hm-helper/1password.nixmodules/nixos/shared/features/hm-helper/default.nixmodules/nixos/shared/features/hm-helper/kde-connect.nixmodules/nixos/shared/features/hm-helper/mpv.nixmodules/nixos/shared/features/hm-helper/nautilus.nixmodules/nixos/shared/features/remote.nixmodules/nixos/shared/services/default.nixmodules/nixos/shared/services/huntress.nixmodules/nixos/shared/services/mcpo.nixmodules/nixos/shared/services/metrics.nixmodules/nixos/shared/services/tailscale.nixtests/default.nixtests/lib.nixtests/mkNode.nix
💤 Files with no reviewable changes (4)
- modules/nixos/proxies.nix
- modules/nixos/default.nix
- modules/nixos/encrypted-root.nix
- modules/nixos/shared/core.nix
2a6a397 to
692fe91
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
modules/nixos/desktop/virtual-machine.nix (1)
74-74:⚠️ Potential issue | 🔴 CriticalReplace
mkDocwith plain string—mkDocis undefined.The code uses
mkDocon line 74, but this function is not defined in your custom lib or standard Nix lib. This will cause module evaluation to fail with an "undefined variable" error.Use a plain string instead:
Suggested fix
- description = mkDoc "The percentage of maxMemory to reserve for the host."; + description = "The percentage of maxMemory to reserve for the host.";If you need markdown formatting in descriptions, use
lib.mdDocinstead, but for plain text a simple string is sufficient.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@modules/nixos/desktop/virtual-machine.nix` at line 74, Replace the undefined mkDoc call used for the description attribute with a plain string (or lib.mdDoc if markdown is needed); specifically change the description = mkDoc "The percentage of maxMemory to reserve for the host."; to use a simple string value for the description property (or lib.mdDoc("...") if you want markdown), ensuring you update the description assignment in the virtual-machine module where description is set so evaluation no longer fails due to mkDoc being undefined.
♻️ Duplicate comments (6)
tests/lib.nix (1)
6-10:⚠️ Potential issue | 🟠 MajorPass the node object into the callback, not
node.name.The helper currently feeds a string expression to
f, so generated snippets can’t safely call node methods.Suggested fix
runOnAllNodes = f: '' for node in cluster.nodes: with subtest(node.name): - ${f "node.name"} + ${f "node"} '';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/lib.nix` around lines 6 - 10, The helper runOnAllNodes currently invokes the callback f with the string "node.name", preventing consumers from accessing node methods; change the invocation from ${f "node.name"} to ${f "node"} so the actual node object is passed (keep the surrounding for node in cluster.nodes and the with subtest(node.name) as-is), and update any callers of runOnAllNodes to expect a node object instead of a name string.tests/default.nix (1)
21-29:⚠️ Potential issue | 🟠 MajorWire
server.testsunits intotestScriptgeneration.This script is static and never reads
server.tests.enable/server.tests.units.*.testScript, so the newly declared framework remains inert in CI.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/default.nix` around lines 21 - 29, The testScript in default.nix is static and omits any server.tests configuration; update the generation of testScript (the value bound to testScript and the start_all()/cluster.nodes logic) to conditionally include server.tests when server.tests.enable is true by iterating server.tests.units and injecting each unit's testScript (e.g., server.tests.units.*.testScript) or calling its test routine into the combined testScript; ensure the produced script still calls start_all(), waits for multi-user.target on cluster.nodes, and then executes or sources each enabled unit's testScript so CI picks up server.tests units.modules/nixos/server/tests.nix (2)
17-38:⚠️ Potential issue | 🔴 CriticalDeclare
server.tests.unitswithmkOption.Inside
options, this is currently a raw type expression, not an option declaration. That prevents the option tree from evaluating correctly.Suggested fix
- units = attrsOf (submodule ({ name, ... }: { - options = { - name = mkOption { - type = str; - default = name; - description = '' - The name to give to this unit test. - This is used to enter into a subtest within the testScript of the cluster test. - ''; - }; - - testScript = mkOption { - type = either str (functionTo str); - description = '' - Python code to be ran within the subtest for this unit. - - If this is a function with one argument of this nodes config. - If this is a function with two arguments, the second argument is the entire cluster configuration. - ''; - }; - }; - })); + units = mkOption { + type = attrsOf (submodule ({ name, ... }: { + options = { + name = mkOption { + type = str; + default = name; + description = '' + The name to give to this unit test. + This is used to enter into a subtest within the testScript of the cluster test. + ''; + }; + + testScript = mkOption { + type = either str (functionTo str); + description = '' + Python code to be ran within the subtest for this unit. + + If this is a function with one argument of this nodes config. + If this is a function with two arguments, the second argument is the entire cluster configuration. + ''; + }; + }; + })); + default = { }; + };As per coding guidelines: Create NixOS modules with standard options definitions using
mkOption/mkEnableOption.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@modules/nixos/server/tests.nix` around lines 17 - 38, The top-level option server.tests.units is currently defined as a raw attrsOf(submodule(...)) expression instead of an mkOption declaration; wrap that expression in mkOption (e.g., set server.tests.units = mkOption { type = attrsOf (submodule ({ name, ... }: { options = { name = mkOption { ... }; testScript = mkOption { ... }; }; })); description = "..."; }); so the option tree evaluates correctly and follows the NixOS module pattern; keep the inner submodule options (name, testScript) as mkOption entries and add an appropriate description/defaults for server.tests.units.
10-11:⚠️ Potential issue | 🔴 CriticalImport type helpers from
lib.types, notlib.type.This currently resolves from a non-standard path and will break evaluation when type constructors are used.
Suggested fix
let - inherit (lib) type mkOption mkEnableOption; - inherit (type) submodule attrsOf either listOf str bool functionTo; + inherit (lib) mkOption mkEnableOption; + inherit (lib.types) submodule attrsOf either listOf str bool functionTo; in {Based on learnings: Verify attribute names, imports, and option paths to resolve 'attribute missing' errors in Nix configurations.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@modules/nixos/server/tests.nix` around lines 10 - 11, The import uses lib.type which is incorrect; change the inherits so the type constructors come from lib.types (e.g. reference mkOption and mkEnableOption from lib.types) and ensure the second inherit uses the correct symbol source for submodule, attrsOf, either, listOf, str, bool, and functionTo; update the inherit lines to import mkOption/mkEnableOption and the listed type helpers from lib.types so Nix evaluation uses the standard type constructors.tests/mkNode.nix (1)
7-12:⚠️ Potential issue | 🟠 MajorBuild test nodes from the full host module stack.
Right now the node definition only applies the flake-apply layer, so cluster checks can pass without exercising the actual server host modules.
Based on learnings: All affected configurations MUST be tested, and this requires node definitions that mirror real host configuration paths.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/mkNode.nix` around lines 7 - 12, The test node currently imports only the flake-apply layer ("${self}/modules/flake/apply/system.nix") so cluster checks bypass real host modules; change the import to load the full host module stack used in production (the real host module path that composes allocations and hostName) instead of the flake-apply shortcut, keeping the same inherited attributes (inherit allocations hostName) and deviceType = "server" so tests exercise the actual server host modules.modules/nixos/shared/core/default.nix (1)
58-62:⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse service-aligned group names and gate
pipewiremembership.Line 130 uses
"network", which does not match the usual NetworkManager access group, and Line 60 adds"pipewire"unconditionally. This can produce ineffective or invalid group assignments.Suggested fix
(mkIf cfg.audio.enable { - custom.defaultGroups = [ - "audio" - "pipewire" - "rtkit" - ]; + custom.defaultGroups = + [ + "audio" + "rtkit" + ] + ++ lib.optional config.services.pipewire.systemWide "pipewire"; @@ (mkIf cfg.network.enable { - custom.defaultGroups = [ "network" ]; + custom.defaultGroups = [ "networkmanager" ]; networking.networkmanager.enable = true; })#!/bin/bash # Read-only verification of relevant group usage and toggles. rg -n -C2 'custom\.defaultGroups\s*=\s*\[\s*"network"' --type nix rg -n -C2 '"pipewire"' --type nix rg -n -C2 'services\.pipewire\.systemWide\s*=\s*true' --type nix rg -n -C2 'users\.groups\.(network|networkmanager|pipewire)\b' --type nixAs per coding guidelines, "Verify attribute names, imports, and option paths to resolve 'attribute missing' errors in Nix configurations".
Also applies to: 129-131
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@modules/nixos/shared/core/default.nix` around lines 58 - 62, Update custom.defaultGroups to use service-aligned group names and make pipewire membership conditional: replace the hardcoded "network" with the Distribution/Service group used by NetworkManager (e.g., "networkmanager") and remove the unconditional "pipewire" entry in custom.defaultGroups; instead, add "pipewire" to defaultGroups only when services.pipewire.systemWide is true. Also verify that users.groups contains the corresponding group attributes (networkmanager and pipewire) so group names match existing definitions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.vscode/settings.json:
- Line 2: Remove the workspace-level setting that disables Git by deleting the
"git.enabled": false entry from .vscode/settings.json (or revert that file to
not include the key) and instead apply this preference in your personal VS Code
user settings if needed; look for the "git.enabled" key in the settings file and
remove or relocate it so the repository does not force-disable Source Control
for all users.
In `@modules/nixos/shared/core/hardware/backlight.nix`:
- Around line 44-46: Change the udev rule so i2c devices are assigned to a
dedicated group and restrictive mode: update services.udev.extraRules replacing
GROUP="users" with GROUP="i2c", MODE="0660" for the KERNEL=="i2c-[0-9]*" rule,
and ensure the group exists (e.g., add a users.groups.i2c declaration elsewhere
in the Nix config). This scopes access to the i2c group and enforces least
privilege for the KERNEL=="i2c-[0-9]*" devices.
---
Outside diff comments:
In `@modules/nixos/desktop/virtual-machine.nix`:
- Line 74: Replace the undefined mkDoc call used for the description attribute
with a plain string (or lib.mdDoc if markdown is needed); specifically change
the description = mkDoc "The percentage of maxMemory to reserve for the host.";
to use a simple string value for the description property (or lib.mdDoc("...")
if you want markdown), ensuring you update the description assignment in the
virtual-machine module where description is set so evaluation no longer fails
due to mkDoc being undefined.
---
Duplicate comments:
In `@modules/nixos/server/tests.nix`:
- Around line 17-38: The top-level option server.tests.units is currently
defined as a raw attrsOf(submodule(...)) expression instead of an mkOption
declaration; wrap that expression in mkOption (e.g., set server.tests.units =
mkOption { type = attrsOf (submodule ({ name, ... }: { options = { name =
mkOption { ... }; testScript = mkOption { ... }; }; })); description = "...";
}); so the option tree evaluates correctly and follows the NixOS module pattern;
keep the inner submodule options (name, testScript) as mkOption entries and add
an appropriate description/defaults for server.tests.units.
- Around line 10-11: The import uses lib.type which is incorrect; change the
inherits so the type constructors come from lib.types (e.g. reference mkOption
and mkEnableOption from lib.types) and ensure the second inherit uses the
correct symbol source for submodule, attrsOf, either, listOf, str, bool, and
functionTo; update the inherit lines to import mkOption/mkEnableOption and the
listed type helpers from lib.types so Nix evaluation uses the standard type
constructors.
In `@modules/nixos/shared/core/default.nix`:
- Around line 58-62: Update custom.defaultGroups to use service-aligned group
names and make pipewire membership conditional: replace the hardcoded "network"
with the Distribution/Service group used by NetworkManager (e.g.,
"networkmanager") and remove the unconditional "pipewire" entry in
custom.defaultGroups; instead, add "pipewire" to defaultGroups only when
services.pipewire.systemWide is true. Also verify that users.groups contains the
corresponding group attributes (networkmanager and pipewire) so group names
match existing definitions.
In `@tests/default.nix`:
- Around line 21-29: The testScript in default.nix is static and omits any
server.tests configuration; update the generation of testScript (the value bound
to testScript and the start_all()/cluster.nodes logic) to conditionally include
server.tests when server.tests.enable is true by iterating server.tests.units
and injecting each unit's testScript (e.g., server.tests.units.*.testScript) or
calling its test routine into the combined testScript; ensure the produced
script still calls start_all(), waits for multi-user.target on cluster.nodes,
and then executes or sources each enabled unit's testScript so CI picks up
server.tests units.
In `@tests/lib.nix`:
- Around line 6-10: The helper runOnAllNodes currently invokes the callback f
with the string "node.name", preventing consumers from accessing node methods;
change the invocation from ${f "node.name"} to ${f "node"} so the actual node
object is passed (keep the surrounding for node in cluster.nodes and the with
subtest(node.name) as-is), and update any callers of runOnAllNodes to expect a
node object instead of a name string.
In `@tests/mkNode.nix`:
- Around line 7-12: The test node currently imports only the flake-apply layer
("${self}/modules/flake/apply/system.nix") so cluster checks bypass real host
modules; change the import to load the full host module stack used in production
(the real host module path that composes allocations and hostName) instead of
the flake-apply shortcut, keeping the same inherited attributes (inherit
allocations hostName) and deviceType = "server" so tests exercise the actual
server host modules.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 5f064077-dd35-408a-abda-03433eadc7e6
⛔ Files ignored due to path filters (11)
openspec/changes/testing-framework-predeploy/.openspec.yamlis excluded by!openspec/**openspec/changes/testing-framework-predeploy/README.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/design.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/proposal.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/specs/server-vm-test-harness/spec.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/specs/service-aware-vm-tests/spec.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/specs/vm-test-documentation/spec.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/specs/vm-test-profile-overrides/spec.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/specs/vm-test-secret-generation/spec.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/specs/woodpecker-vm-test-gating/spec.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/tasks.mdis excluded by!openspec/**
📒 Files selected for processing (57)
.vscode/settings.jsonflake/ci/flake-module.nixflake/default.nixlib/builders/mkSystem.nixmodules/home-manager/services/mcpo.nixmodules/nixos/default.nixmodules/nixos/desktop/default.nixmodules/nixos/desktop/rgb.nixmodules/nixos/desktop/vfio.nixmodules/nixos/desktop/virtual-machine.nixmodules/nixos/encrypted-root.nixmodules/nixos/laptop/default.nixmodules/nixos/proxies.nixmodules/nixos/server/default.nixmodules/nixos/server/tests.nixmodules/nixos/shared/core.nixmodules/nixos/shared/core/auto-upgrade.nixmodules/nixos/shared/core/boot/default.nixmodules/nixos/shared/core/boot/quietboot.nixmodules/nixos/shared/core/boot/secureboot.nixmodules/nixos/shared/core/boot/systemd-boot.nixmodules/nixos/shared/core/default.nixmodules/nixos/shared/core/hardware/backlight.nixmodules/nixos/shared/core/hardware/biometrics.nixmodules/nixos/shared/core/hardware/bluetooth.nixmodules/nixos/shared/core/hardware/cooling.nixmodules/nixos/shared/core/hardware/default.nixmodules/nixos/shared/core/hardware/display.nixmodules/nixos/shared/core/hardware/graphics.nixmodules/nixos/shared/core/hardware/openrgb.nixmodules/nixos/shared/core/hardware/storage/default.nixmodules/nixos/shared/core/hardware/storage/ephemeral.nixmodules/nixos/shared/core/hardware/storage/maintenance.nixmodules/nixos/shared/core/hardware/storage/partitions/btrfs.nixmodules/nixos/shared/core/hardware/storage/partitions/esp.nixmodules/nixos/shared/core/hardware/storage/partitions/luks.nixmodules/nixos/shared/core/hardware/storage/partitions/tmpfs.nixmodules/nixos/shared/core/host/default.nixmodules/nixos/shared/core/host/device.nixmodules/nixos/shared/core/host/persistence.nixmodules/nixos/shared/core/printing.nixmodules/nixos/shared/default.nixmodules/nixos/shared/features/display-manager.nixmodules/nixos/shared/features/hm-helper/1password.nixmodules/nixos/shared/features/hm-helper/default.nixmodules/nixos/shared/features/hm-helper/kde-connect.nixmodules/nixos/shared/features/hm-helper/mpv.nixmodules/nixos/shared/features/hm-helper/nautilus.nixmodules/nixos/shared/features/remote.nixmodules/nixos/shared/services/default.nixmodules/nixos/shared/services/huntress.nixmodules/nixos/shared/services/mcpo.nixmodules/nixos/shared/services/metrics.nixmodules/nixos/shared/services/tailscale.nixtests/default.nixtests/lib.nixtests/mkNode.nix
💤 Files with no reviewable changes (4)
- modules/nixos/proxies.nix
- modules/nixos/encrypted-root.nix
- modules/nixos/default.nix
- modules/nixos/shared/core.nix
- Move mapAttrsToList from builtins to lib (Lix 2.94 compat) - Builder accepts testUnits param, iterates in testScript - Flake-module passes config.server.tests.units to builder - Inject scenario name from directory name
Scenario files define nodes + testScript but not name. Inject name = scenarioName so builder can set derivation name.
~48 unit tests, 7 multi-node scenarios, 2 infra + 1 security suites across 3 phases. Based on full fleet audit: 7 hosts, 40+ services. Audit found 15 missed services, 3 false positives, 11 brittle points.
Phase 1 (25 unit + 2 scenarios): per-host service tests + postgres/redis cross-host Phase 2 (22 unit + 6 scenarios + security): secondary services, monitoring, proxy, firewall Key: - Scenarios self-contain services, test real behavior (psql, redis-cli, prometheus scrape, cross-host HTTP) - Host-level unit tests verify service definitions exist (catches config breakage) - Caddy TLS skipped (root CA install fails in QEMU sandbox) - vm-test.nix overrides: postgres JIT off + trust auth, caddy deps stripped - mkNode.nix stubs server options to avoid cross-config recursion All 15 nixosTestConfigurations pass (7 hosts + 8 scenarios).
…prove test coverage
692fe91 to
d600b72
Compare
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 34424190 | Triggered | Generic Password | d600b72 | tests/profiles/vm-test.nix | View secret |
| 34424190 | Triggered | Generic Password | 7135633 | tests/profiles/vm-test.nix | View secret |
| 34424190 | Triggered | Generic Password | 7135633 | tests/profiles/vm-test.nix | View secret |
| 34424190 | Triggered | Generic Password | 011e1f6 | tests/profiles/vm-test.nix | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
There was a problem hiding this comment.
Actionable comments posted: 25
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@_run_tests.sh`:
- Line 7: The HOSTS array in _run_tests.sh is hardcoded and can drift from the
actual set of test hosts. Replace the static HOSTS definition with dynamic host
discovery, matching the approach used in .woodpecker/test-vm.yaml by evaluating
nixosTestConfigurations via nix eval so new hosts like nixarr, nixcloud, and
nixserv are picked up automatically. Keep the rest of the script logic unchanged
and ensure the dynamic source feeds the same HOSTS variable used by the test
loop.
In @.woodpecker/test-vm.yaml:
- Around line 25-32: The VM test loop in the Run VM tests step is swallowing
failures because `nix build` is followed by `|| echo "FAILED: $host"`, so the
script still exits successfully. Update the command block so failures from `nix
build ".#nixosTestConfigurations.$host"` are propagated and cause the step to
fail, using the `Run VM tests` job script and the `host` loop as the place to
fix it. Keep the per-host logging if needed, but ensure a non-zero exit from any
VM test build makes the pipeline fail.
In `@docs/src/development/vm_integration_tests.md`:
- Around line 187-190: The example command in vm_integration_tests.md uses
`--override-input` with `.`, which is not a valid flake input for setting
`testFilter` and should be removed or replaced. Update the section around the
`nix build` example to either keep only the local-edit command or show a command
that overrides a real named input, so the `postgres-connect` filter is
demonstrated correctly. Refer to the existing `nix build
.#nixosTestConfigurations.<host>` example and adjust that snippet accordingly.
In `@flake/nixos/flake-module.nix`:
- Around line 97-120: The scenario discovery block in the flake module should
only include directory entries from builtins.readDir so stray files like
README.md do not get imported as scenarios and break evaluation. Update the
scenario enumeration in the builder setup to filter by entry type before
constructing the listToAttrs mapping, using the existing scenariosDir/import
logic as the locator. Also guard the final // merge against silent name
collisions with server host names by detecting duplicate keys and failing
explicitly or separating the namespaces so auto-discovered scenarios cannot
overwrite host tests unnoticed.
In `@hosts/server/nixai/ai-agent.nix`:
- Around line 10-23: The unit test setup repeats the same LoadState check
boilerplate, so factor it into a shared helper instead of duplicating the
command in each `testScript`. Add a reusable function in `tests/lib.nix` such as
`mkLoadStateTest` that takes the node and unit name, builds the `systemctl show
... | grep -i loadstate` command, and returns the test script, then update
`server.tests.units` and the other matching call sites to use that helper
consistently.
- Around line 10-23: The unit tests for ai-agent-api and ai-agent-dashboard
currently use a grep on “loadstate” that will always pass and does not verify
the service actually loaded. Update the testScript commands in the
server.tests.units definitions to assert the expected loaded state explicitly,
using a case-insensitive match on the full LoadState value from systemctl show
(for example, the unique ai-agent-api.service and ai-agent-dashboard.service
checks should validate “LoadState=loaded” rather than just the key name). Apply
the same fix pattern consistently anywhere the same systemctl show | grep -i
loadstate check is repeated.
In `@hosts/server/nixarr/arr/downloader.nix`:
- Around line 88-100: The unit checks in server.tests.units for transmission and
sabnzbd are no-ops because `systemctl show ... | grep -i loadstate` always
succeeds. Update the testScript blocks to assert the actual `LoadState` value
returned by `systemctl show` for each service, using the existing transmission,
transmission-flood, and sabnzbd unit checks as the place to validate the
expected loaded state instead of just matching the property name.
In `@hosts/server/nixcloud/identity.nix`:
- Around line 216-220: The kanidm unit test is only checking that systemctl
outputs the LoadState field, so it cannot fail even when the service is missing
or inactive. Update the tests.units.kanidm testScript to assert the actual
expected LoadState value for kanidm.service rather than grepping for the key
name, using the existing nixcloud.succeed call so the test will fail when the
unit is masked, absent, or not loaded.
In `@hosts/server/nixcloud/immich.nix`:
- Around line 54-64: The unit tests for immich and immich-redis are using a
no-op `grep -i loadstate` check in their `testScript`, so the assertions never
verify the actual systemd state. Update both `tests.units.immich` and
`tests.units.immich-redis` in `immich.nix` to check the `LoadState` value
explicitly via `systemctl show` and compare it against the expected loaded
state, using the existing `immich-server.service` and `redis-immich.service`
identifiers.
In `@hosts/server/nixcloud/music.nix`:
- Around line 23-34: The unit tests for navidrome and music-assistant in
server.tests.units are currently using a no-op grep on the LoadState key, so
they never verify the actual service state. Update the testScript commands to
inspect the value returned by systemctl show for each service and assert the
expected loaded state using the existing navidrome.service and
music-assistant.service checks. Keep the fix localized to the server.tests.units
entries so both test cases validate real unit state instead of just matching the
key name.
In `@hosts/server/nixcloud/nextcloud.nix`:
- Around line 62-90: The unit tests in tests.units currently only check that
systemctl prints the LoadState field, which does not verify the service is
actually active or loaded. Update each testScript for nextcloud, elasticsearch,
clamav, imaginary, and notify-push to assert a meaningful LoadState value via
the existing nixcloud.succeed calls, using the corresponding service names
(phpfpm-nextcloud.service, elasticsearch.service, clamav-daemon.service,
imaginary.service, notify_push.service) so missing or failed units will fail the
tests.
In `@hosts/server/nixcloud/search.nix`:
- Around line 634-638: The searxng unit test is still using a no-op `grep -i
loadstate` check in `tests.units.searxng.testScript`, which does not
meaningfully assert service state. Update the `nixcloud.succeed(...)` command to
verify an actual expected property of `searxng.service` using `systemctl show`
and a concrete match, so the test fails when the service is not in the intended
state.
In `@hosts/server/nixdev/automation.nix`:
- Around line 100-107: The `tests.units.n8n` `testScript` is asserting only that
`systemctl show` prints the `LoadState` field, which is always true and can’t
detect a bad service state. Update the assertion in the `nixdev.succeed(...)`
call to check the actual value of `LoadState` for `n8n.service` instead of
grepping for the property name, so the test fails unless the unit is truly
loaded.
In `@hosts/server/nixdev/ci.nix`:
- Around line 25-30: The github-runner-nixos-runner-0.service test is only
checking that a LoadState line exists, so it can pass even when the unit is
broken. Update server.tests.units.github-runners in ci.nix to assert the actual
expected LoadState value using the testScript command instead of a generic grep,
so the check fails when the service does not load correctly.
In `@hosts/server/nixdev/coder.nix`:
- Around line 36-43: The coder unit test is only grepping for LoadState, so it
never verifies the service state. Update the testScript in the coder test to
assert the expected value from systemctl show for coder.service using a specific
LoadState check, following the same pattern used by the other unit test
assertions in this cohort.
In `@hosts/server/nixdev/default.nix`:
- Around line 26-33: The Docker unit test is asserting the presence of the
property name rather than validating its value, so it cannot detect a
failed-to-load docker.service. Update the testScript in
server.tests.units.docker to inspect the LoadState output from systemctl show
docker.service and assert that it equals the expected loaded state instead of
grepping for the key name. Use the existing docker testScript block to locate
the check and make the assertion value-based, not name-based.
In `@hosts/server/nixdev/registry.nix`:
- Around line 97-104: The current `docker-registry` unit test in `tests.units`
uses `systemctl show ... | grep -i loadstate`, which only matches the property
name and can pass even when the service load fails. Update the `testScript` to
assert the actual `LoadState` value from `docker-registry.service` via the
existing `nixdev.succeed` check, using `systemctl show` with a value comparison
so the test fails unless the service is properly loaded.
In `@hosts/server/nixdev/woodpecker.nix`:
- Around line 59-72: The `tests.units` checks for `woodpecker-server` and
`woodpecker-agent` are currently tautological because `systemctl show ... | grep
-i loadstate` matches the field name instead of verifying the service state.
Update both `testScript` blocks to assert the actual `LoadState` value reported
by `systemctl show` in a non-trivial way, so the `woodpecker-server` and
`woodpecker-agent` unit tests fail when the service is not loaded. Use the
existing `tests.units` entries and their `systemctl show` commands to locate the
assertions.
In `@hosts/server/nixio/adguard.nix`:
- Around line 223-228: The adguard unit test is using a tautological LoadState
check because `grep -i loadstate` matches the property name instead of the
service’s state. Update `server.tests.units.adguard` in the `testScript` to
assert the actual `systemctl show` value for `adguardhome.service` using the
correct property/value pattern, so the test verifies the service is loaded
rather than just finding the field name.
In `@hosts/server/nixio/default.nix`:
- Around line 96-103: The kernel-forwarding unit test is currently proving only
that sysctl can be written at runtime, not that the declared boot-time
configuration is applied. Update the testScript in
server.tests.units.kernel-forwarding to stop using the sysctl -w calls and only
verify the existing values with sysctl -n checks, so it validates the
boot.kernel.sysctl settings instead of re-setting them itself.
In `@hosts/server/nixmon/default.nix`:
- Around line 65-69: The node exporter test is checking the wrong systemd unit
name. Update the testScript in the node-exporter case to reference the unit used
by services.prometheus.exporters.node, specifically
prometheus-node-exporter.service, instead of node_exporter.service. Keep the
check in the same test block so it still verifies the exporter service state
correctly.
- Around line 34-76: The unit test scripts under server.tests.units all use the
no-op systemctl show ... | grep -i loadstate pattern, so they never assert the
service state value. Update each testScript for prometheus, loki, grafana,
alertmanager, uptime-kuma, node-exporter, and alloy to check the actual
LoadState value from systemctl show (using the same nixmon.succeed calls), and
make the assertion fail when the service is missing or not loaded.
In `@hosts/server/nixserv/default.nix`:
- Around line 50-54: The atticd-config test currently only calls systemctl show
atticd.service via nixserv.succeed, which can pass without proving anything and
duplicates the atticd coverage. Update atticd-config in default.nix to either
remove it or replace it with a real assertion that checks a specific unit/config
value from the atticd.service setup, using the existing testScript entry as the
location to make the test meaningful.
- Around line 44-48: The atticd testScript is using the same no-op grep pattern,
so update the check to assert a real expected service property in the
atticd.service validation. In the atticd test case inside the testScript block,
replace the current systemctl show | grep -i loadstate command with a meaningful
assertion on a specific value or state so the test fails when the service is not
configured correctly.
In `@modules/nixos/server/proxy/extensions/api-key-auth.nix`:
- Around line 85-111: The `config` callback in `getExtensionsForVhost` is
dereferencing `vh.requireApiKey.enable` without a null check, which can fail for
vhosts that don’t define `requireApiKey` when extensions are applied broadly.
Update this guard to match the other call sites by first checking that
`vh.requireApiKey` is present before reading `enable`, and keep the existing
API-key config generation logic under that combined condition.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 01879bb7-d995-48cf-b2d0-7822e9feed1d
📒 Files selected for processing (41)
.woodpecker/test-vm.yaml_run_tests.shdocs/src/SUMMARY.mddocs/src/development/vm_integration_tests.mdflake/default.nixflake/nixos/flake-module.nixhosts/server/nixai/ai-agent.nixhosts/server/nixai/voice.nixhosts/server/nixai/web.nixhosts/server/nixarr/arr/default.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixarr/default.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixcloud/homebox.nixhosts/server/nixcloud/identity.nixhosts/server/nixcloud/immich.nixhosts/server/nixcloud/music.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixcloud/search.nixhosts/server/nixdev/automation.nixhosts/server/nixdev/ci.nixhosts/server/nixdev/coder.nixhosts/server/nixdev/default.nixhosts/server/nixdev/registry.nixhosts/server/nixdev/woodpecker.nixhosts/server/nixio/adguard.nixhosts/server/nixio/dashboard.nixhosts/server/nixio/database.nixhosts/server/nixio/default.nixhosts/server/nixio/proxy.nixhosts/server/nixio/storage.nixhosts/server/nixmon/default.nixhosts/server/nixserv/default.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/host/persistence.nixmodules/nixos/core/nix.nixmodules/nixos/core/sops.nixmodules/nixos/core/stylix.nixmodules/nixos/server/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nix
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: generate-matrix
⚠️ CI failures not shown inline (3)
GitHub Check: GitGuardian Security Checks: 4 secrets uncovered!
Conclusion: failure
#### 4 secrets were uncovered from the scan of 12 commits in your pull request. ❌
Please have a look to GitGuardian findings and remediate in order to secure your code.
### 🔎 Detected hardcoded secrets in your pull request
- Pull request `#545`: `push-xvsqsqnwmrup` 👉 `master`
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
| -------------- | ------------------ | ------ | ------ | -------- | ---- |
| [34424190](https://dashboard.gitguardian.com/workspace/233667/incidents/34424190?occurrence=276310304) | Triggered | Generic Password | d600b72464642ac451674ba06cdd8931785af98e | tests/profiles/vm-test.nix | [View secret](https://github.com/DaRacci/nix-config/commit/d600b72464642ac451674ba06cdd8931785af98e#diff-404f8053b181e2e0a352c9a9a3da131cfadebac38692ebf53612420193caae7fR220) |
| [34424190](https://dashboard.gitguardian.com/workspace/233667/incidents/34424190?occurrence=276310306) | Triggered | Generic Password | 7135633da5c1d502f9403af61941b032af9f4e2e | tests/profiles/vm-test.nix | [View secret](https://github.com/DaRacci/nix-config/commit/7135633da5c1d502f9403af61941b032af9f4e2e#diff-404f8053b181e2e0a352c9a9a3da131cfadebac38692ebf53612420193caae7fR174) |
| [34424190](https://dashboard.gitguardian.com/workspace/233667/incidents/34424190?occurrence=276310308) | Triggered | Generic Password | 7135633da5c1d502f9403af61941b032af9f4e2e | tests/profiles/vm-test.nix | [View secret](https://github.com/DaRacci/nix-config/commit/7135633da5c1d502f9403af61941b032af9f4e2e#diff-404f8053b181e2e0a352c9a9a3da131cfadebac38692ebf53612420193caae7fR149) |
| [34424190](https://dashboard.gitguardian.com/workspace/233667/incidents/34424190?occurrence=276310311) | Triggered | Generic Password | 011e1f60ae7c76cbf8fd9511ba300fcf2d54c3fa | tests/profiles/vm-test.nix | [View secret](https://github.com/DaRacci/nix-config/commit/011e1f60ae7c76cbf8fd9511ba300fcf2d54c3fa#diff-404f8053b181e2e0a352c9a9a3da131cfadebac38692ebf53612420193caae7fR149) |
### 🛠 Guidelines to re...
Commit Status: ci/woodpecker/pr/check: ci/woodpecker/pr/check
Conclusion: failure
Pipeline failed
Commit Status: ci/woodpecker/pr/check-upstream-todos: ci/woodpecker/pr/check-upstream-todos
Conclusion: failure
Pipeline failed
🧰 Additional context used
📓 Path-based instructions (13)
docs/**/*
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Project documentation should be placed in the
docs/directory
Files:
docs/src/SUMMARY.mddocs/src/development/vm_integration_tests.md
docs/src/**/*.md
📄 CodeRabbit inference engine (.opencode/skills/docs/SKILL.md)
docs/src/**/*.md: Use underscore filenames (e.g.,my_new_feature.md) instead of hyphens for documentation files
Keep documentation prose focused on behavior, architecture, usage examples, and operational notes; let generated fragments provide exhaustive option reference
Files:
docs/src/SUMMARY.mddocs/src/development/vm_integration_tests.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Verify documentation accurately reflects new behavior in docs/ directory before proceeding to commit
Files:
docs/src/SUMMARY.mddocs/src/development/vm_integration_tests.md
**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/code-style-nix)
**/*.nix: Follow Nix code style conventions and best practices
Use consistent indentation and formatting in Nix configuration files
Follow established patterns for module organization in home-manager configurations
**/*.nix: Format code and check syntax usingnix fmt
Evaluate Nix expressions without building usingnix evalwith the target configuration path
Format specific Nix files or directories usingnix fmtfollowed by the file or directory path
Use--show-traceflag withnix buildornix evalcommands to diagnose evaluation errors
For infinite recursion errors in Nix builds, check for circular imports or conflicting option definitions
**/*.nix: Usebuiltins.traceto add trace statements and inspect values during Nix evaluation (format:builtins.trace "message: ${toString var}" var)
Usebuiltins.toJSONto convert complex Nix attribute sets to JSON for easier inspection during evaluation
Check for circular imports between modules and option definitions that depend on themselves to resolve infinite recursion errors
Verify attribute names are correct and imports are complete when debugging 'attribute not found' errors in Nix
Check option type definitions and ensure provided values match the expected type to resolve type mismatch errors
Read assertion messages and provide required configuration values when assertion failures occur in NixOS modules
**/*.nix: Store sensitive data insecrets.yamlencrypted with sops instead of hardcoding passwords, API keys, or tokens in plain text
Declare sops secrets with properowner,group, andmodeattributes; use restrictive modes like0400for secrets files
SetrestartUnitsorreloadUnitsfor sops secrets declarations so services that depend on secrets are restarted when secrets change
Useconfig.sops.placeholderin sops templates instead of directly interpolating secret paths in multi-secret templates
Do not pass secrets as environment variables in plain Nix; useenvironmentFileor...
Files:
hosts/server/nixai/web.nixhosts/server/nixio/dashboard.nixhosts/server/nixio/storage.nixhosts/server/nixio/default.nixhosts/server/nixdev/woodpecker.nixmodules/nixos/core/sops.nixhosts/server/nixcloud/music.nixhosts/server/nixserv/default.nixhosts/server/nixdev/automation.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixcloud/search.nixmodules/nixos/core/boot/secureboot.nixhosts/server/nixai/voice.nixmodules/nixos/core/stylix.nixhosts/server/nixarr/arr/default.nixmodules/nixos/server/default.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixcloud/home-assistant/connectivity.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixhosts/server/nixcloud/homebox.nixhosts/server/nixai/ai-agent.nixhosts/server/nixdev/ci.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixio/proxy.nixhosts/server/nixdev/coder.nixhosts/server/nixio/database.nixflake/nixos/flake-module.nixhosts/server/nixmon/default.nixhosts/server/nixdev/registry.nixhosts/server/nixcloud/immich.nixhosts/server/nixarr/default.nixhosts/server/nixio/adguard.nixmodules/nixos/core/nix.nixmodules/nixos/core/host/persistence.nixhosts/server/nixdev/default.nixflake/default.nixhosts/server/nixcloud/identity.nix
hosts/server/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Server machine-specific NixOS configs should be placed in
hosts/server/<machine>/
Files:
hosts/server/nixai/web.nixhosts/server/nixio/dashboard.nixhosts/server/nixio/storage.nixhosts/server/nixio/default.nixhosts/server/nixdev/woodpecker.nixhosts/server/nixcloud/music.nixhosts/server/nixserv/default.nixhosts/server/nixdev/automation.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixcloud/search.nixhosts/server/nixai/voice.nixhosts/server/nixarr/arr/default.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixcloud/homebox.nixhosts/server/nixai/ai-agent.nixhosts/server/nixdev/ci.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixio/proxy.nixhosts/server/nixdev/coder.nixhosts/server/nixio/database.nixhosts/server/nixmon/default.nixhosts/server/nixdev/registry.nixhosts/server/nixcloud/immich.nixhosts/server/nixarr/default.nixhosts/server/nixio/adguard.nixhosts/server/nixdev/default.nixhosts/server/nixcloud/identity.nix
hosts/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/modules/SKILL.md)
Enable NixOS modules in host configuration files, e.g. set
services.<name>.enable = true;.
Files:
hosts/server/nixai/web.nixhosts/server/nixio/dashboard.nixhosts/server/nixio/storage.nixhosts/server/nixio/default.nixhosts/server/nixdev/woodpecker.nixhosts/server/nixcloud/music.nixhosts/server/nixserv/default.nixhosts/server/nixdev/automation.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixcloud/search.nixhosts/server/nixai/voice.nixhosts/server/nixarr/arr/default.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixcloud/homebox.nixhosts/server/nixai/ai-agent.nixhosts/server/nixdev/ci.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixio/proxy.nixhosts/server/nixdev/coder.nixhosts/server/nixio/database.nixhosts/server/nixmon/default.nixhosts/server/nixdev/registry.nixhosts/server/nixcloud/immich.nixhosts/server/nixarr/default.nixhosts/server/nixio/adguard.nixhosts/server/nixdev/default.nixhosts/server/nixcloud/identity.nix
hosts/*/*/default.nix
📄 CodeRabbit inference engine (.opencode/skills/hosts/SKILL.md)
Each host must have a
default.nixfile inhosts/<type>/<hostname>/as the main config entry pointPer-machine NixOS configurations should be placed in
hosts/<type>/<hostname>/default.nix
Files:
hosts/server/nixio/default.nixhosts/server/nixserv/default.nixhosts/server/nixmon/default.nixhosts/server/nixarr/default.nixhosts/server/nixdev/default.nix
hosts/server/*/default.nix
📄 CodeRabbit inference engine (.opencode/skills/hosts/SKILL.md)
Server hosts in
default.nixshould sethost.device.isHeadless = trueto indicate they are headless systems
Files:
hosts/server/nixio/default.nixhosts/server/nixserv/default.nixhosts/server/nixmon/default.nixhosts/server/nixarr/default.nixhosts/server/nixdev/default.nix
modules/nixos/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Reusable NixOS module fragments should be placed in
modules/nixos/Create new NixOS modules under
modules/nixos/<category>/<name>.nix.
Files:
modules/nixos/core/sops.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/stylix.nixmodules/nixos/server/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/core/nix.nixmodules/nixos/core/host/persistence.nix
modules/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/modules/SKILL.md)
modules/**/*.nix: Use the standard Nix module pattern: accept{ config, lib, pkgs, ... }, definecfgfromconfig, and structure the file withoptionsplus aconfig = mkIf cfg.enable { ... }section.
Use the documented module namespaces appropriately:services.<name>,hardware.<name>,boot.<name>,host.<name>,server.<name>,core.<name>,purpose.<category>, anduser.<name>.
When extending a submodule declared in another module, declare the sameoptions.<path>with the same outer wrapper (for example,attrsOf (submodule ...)) so the inneroptionsmerge additively.
Do not use dynamicimportsinside a submodule that read fromconfig; this causes infinite recursion. Use staticimportsonly when they do not depend onconfig.
When behavior should be conditional inside an imported submodule, wrap the submodule'sconfiginmkIf; do not try to conditionally gate the option declaration itself.
When extendingsubmoduleorsubmoduleWith, keep the outer type wrapper identical across declarations so the inneroptionsattrsets can merge.
Files:
modules/nixos/core/sops.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/stylix.nixmodules/nixos/server/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/core/nix.nixmodules/nixos/core/host/persistence.nix
modules/nixos/**/default.nix
📄 CodeRabbit inference engine (.opencode/skills/modules/SKILL.md)
Register NixOS modules in the parent
default.nixvia animports = [ ... ];list.
Files:
modules/nixos/server/default.nix
flake/nixos/flake-module.nix
📄 CodeRabbit inference engine (.opencode/skills/hosts/SKILL.md)
For hosts requiring CUDA or ROCm acceleration support, add the host name to the corresponding array in
flake/nixos/flake-module.nixunderaccelerationHosts
Files:
flake/nixos/flake-module.nix
flake/nixos/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
NixOS flake module definitions should be organized in
flake/nixos/
Files:
flake/nixos/flake-module.nix
🧠 Learnings (10)
📚 Learning: 2026-04-13T14:02:32.760Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 546
File: hosts/server/nixdev/default.nix:18-18
Timestamp: 2026-04-13T14:02:32.760Z
Learning: When configuring NixOS Docker via `virtualisation.docker.daemon.settings`, it is valid to set `storage-driver = "overlayfs"` (do not flag it as an invalid Docker storage-driver). Use `overlayfs` specifically for Docker Engine 29+ and/or when the containerd snapshotter integration is enabled (`virtualisation.docker.features.containerd-snapshotter = true`). Treat this as the containerd snapshotter name for OverlayFS, distinct from the legacy `overlay2` classic Docker storage driver.
Applied to files:
hosts/server/nixai/web.nixhosts/server/nixio/dashboard.nixhosts/server/nixio/storage.nixhosts/server/nixio/default.nixhosts/server/nixdev/woodpecker.nixmodules/nixos/core/sops.nixhosts/server/nixcloud/music.nixhosts/server/nixserv/default.nixhosts/server/nixdev/automation.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixcloud/search.nixmodules/nixos/core/boot/secureboot.nixhosts/server/nixai/voice.nixmodules/nixos/core/stylix.nixhosts/server/nixarr/arr/default.nixmodules/nixos/server/default.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixcloud/home-assistant/connectivity.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixhosts/server/nixcloud/homebox.nixhosts/server/nixai/ai-agent.nixhosts/server/nixdev/ci.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixio/proxy.nixhosts/server/nixdev/coder.nixhosts/server/nixio/database.nixflake/nixos/flake-module.nixhosts/server/nixmon/default.nixhosts/server/nixdev/registry.nixhosts/server/nixcloud/immich.nixhosts/server/nixarr/default.nixhosts/server/nixio/adguard.nixmodules/nixos/core/nix.nixmodules/nixos/core/host/persistence.nixhosts/server/nixdev/default.nixflake/default.nixhosts/server/nixcloud/identity.nix
📚 Learning: 2026-05-01T10:02:55.261Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 544
File: modules/nixos/core/sops.nix:49-53
Timestamp: 2026-05-01T10:02:55.261Z
Learning: In this nix-config repo, when declaring `sops.secrets` in Nix files, avoid explicitly setting `owner = "root"` and/or `group = "root"` if the intended ownership is root. `sops-nix` defaults `sops.secrets` to `root:root`, so adding these fields explicitly is redundant boilerplate.
Applied to files:
hosts/server/nixai/web.nixhosts/server/nixio/dashboard.nixhosts/server/nixio/storage.nixhosts/server/nixio/default.nixhosts/server/nixdev/woodpecker.nixmodules/nixos/core/sops.nixhosts/server/nixcloud/music.nixhosts/server/nixserv/default.nixhosts/server/nixdev/automation.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixcloud/search.nixmodules/nixos/core/boot/secureboot.nixhosts/server/nixai/voice.nixmodules/nixos/core/stylix.nixhosts/server/nixarr/arr/default.nixmodules/nixos/server/default.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixcloud/home-assistant/connectivity.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixhosts/server/nixcloud/homebox.nixhosts/server/nixai/ai-agent.nixhosts/server/nixdev/ci.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixio/proxy.nixhosts/server/nixdev/coder.nixhosts/server/nixio/database.nixflake/nixos/flake-module.nixhosts/server/nixmon/default.nixhosts/server/nixdev/registry.nixhosts/server/nixcloud/immich.nixhosts/server/nixarr/default.nixhosts/server/nixio/adguard.nixmodules/nixos/core/nix.nixmodules/nixos/core/host/persistence.nixhosts/server/nixdev/default.nixflake/default.nixhosts/server/nixcloud/identity.nix
📚 Learning: 2026-05-01T14:14:49.691Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 544
File: modules/nixos/core/gaming.nix:119-119
Timestamp: 2026-05-01T14:14:49.691Z
Learning: When configuring the NixOS `wivrn` module option `services.wivrn.config.json.application`, pass the raw package/derivation (e.g., `pkgs.wayvr`) rather than converting it to a string executable path (e.g., `lib.getExe pkgs.wayvr`). The upstream module expects a list of derivations/packages (it internally `toList`s the value, asserts the first element is a derivation, and then resolves the executable internally). Code review should not recommend changing `pkgs.wayvr` to `lib.getExe pkgs.wayvr` for this option.
Applied to files:
hosts/server/nixai/web.nixhosts/server/nixio/dashboard.nixhosts/server/nixio/storage.nixhosts/server/nixio/default.nixhosts/server/nixdev/woodpecker.nixmodules/nixos/core/sops.nixhosts/server/nixcloud/music.nixhosts/server/nixserv/default.nixhosts/server/nixdev/automation.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixcloud/search.nixmodules/nixos/core/boot/secureboot.nixhosts/server/nixai/voice.nixmodules/nixos/core/stylix.nixhosts/server/nixarr/arr/default.nixmodules/nixos/server/default.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixcloud/home-assistant/connectivity.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixhosts/server/nixcloud/homebox.nixhosts/server/nixai/ai-agent.nixhosts/server/nixdev/ci.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixio/proxy.nixhosts/server/nixdev/coder.nixhosts/server/nixio/database.nixflake/nixos/flake-module.nixhosts/server/nixmon/default.nixhosts/server/nixdev/registry.nixhosts/server/nixcloud/immich.nixhosts/server/nixarr/default.nixhosts/server/nixio/adguard.nixmodules/nixos/core/nix.nixmodules/nixos/core/host/persistence.nixhosts/server/nixdev/default.nixflake/default.nixhosts/server/nixcloud/identity.nix
📚 Learning: 2026-05-20T13:12:46.610Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 546
File: docs/site.nix:127-127
Timestamp: 2026-05-20T13:12:46.610Z
Learning: In DaRacci/nix-config, treating `passthru.discovery = false` as a known repo-wide convention to exclude a derivation from automated flake discovery/package CI. Do not require or flag an inline explanatory comment specifically for the absence of a comment when `passthru.discovery = false` is set.
Applied to files:
hosts/server/nixai/web.nixhosts/server/nixio/dashboard.nixhosts/server/nixio/storage.nixhosts/server/nixio/default.nixhosts/server/nixdev/woodpecker.nixmodules/nixos/core/sops.nixhosts/server/nixcloud/music.nixhosts/server/nixserv/default.nixhosts/server/nixdev/automation.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixcloud/search.nixmodules/nixos/core/boot/secureboot.nixhosts/server/nixai/voice.nixmodules/nixos/core/stylix.nixhosts/server/nixarr/arr/default.nixmodules/nixos/server/default.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixcloud/home-assistant/connectivity.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixhosts/server/nixcloud/homebox.nixhosts/server/nixai/ai-agent.nixhosts/server/nixdev/ci.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixio/proxy.nixhosts/server/nixdev/coder.nixhosts/server/nixio/database.nixflake/nixos/flake-module.nixhosts/server/nixmon/default.nixhosts/server/nixdev/registry.nixhosts/server/nixcloud/immich.nixhosts/server/nixarr/default.nixhosts/server/nixio/adguard.nixmodules/nixos/core/nix.nixmodules/nixos/core/host/persistence.nixhosts/server/nixdev/default.nixflake/default.nixhosts/server/nixcloud/identity.nix
📚 Learning: 2026-06-28T05:00:06.970Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 599
File: hosts/server/nixai/mnemosyne.nix:6-11
Timestamp: 2026-06-28T05:00:06.970Z
Learning: In this repo’s Nix host configuration, for `sops.secrets.<name>` declarations managed by `sops-nix`, avoid explicitly setting `mode = "0400"` when you are not overriding `sops-nix`’s default secret permissions. `sops-nix` already defaults decrypted secret files to root ownership with mode `0400`, so an explicit `mode = "0400"` is typically redundant. Only set `mode` when you truly need non-default permissions (or you have config that changes the module defaults).
Applied to files:
hosts/server/nixai/web.nixhosts/server/nixio/dashboard.nixhosts/server/nixio/storage.nixhosts/server/nixio/default.nixhosts/server/nixdev/woodpecker.nixhosts/server/nixcloud/music.nixhosts/server/nixserv/default.nixhosts/server/nixdev/automation.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixcloud/search.nixhosts/server/nixai/voice.nixhosts/server/nixarr/arr/default.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixcloud/homebox.nixhosts/server/nixai/ai-agent.nixhosts/server/nixdev/ci.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixio/proxy.nixhosts/server/nixdev/coder.nixhosts/server/nixio/database.nixhosts/server/nixmon/default.nixhosts/server/nixdev/registry.nixhosts/server/nixcloud/immich.nixhosts/server/nixarr/default.nixhosts/server/nixio/adguard.nixhosts/server/nixdev/default.nixhosts/server/nixcloud/identity.nix
📚 Learning: 2026-05-01T09:11:22.009Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 544
File: modules/nixos/core/gaming.nix:65-65
Timestamp: 2026-05-01T09:11:22.009Z
Learning: In Nix code, do not flag shell-variable literals like "$XDG_RUNTIME_DIR" used inside Steam’s `extraEnv` (e.g., `pkgs.steam.override { extraEnv = { ... }; }`, including `modules/nixos/core/gaming.nix`). The Steam wrapper script expands these shell variables at runtime, so they should be treated as intended unexpanded literals rather than an interpolation/quoting mistake.
Applied to files:
modules/nixos/core/sops.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/stylix.nixmodules/nixos/server/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/core/nix.nixmodules/nixos/core/host/persistence.nix
📚 Learning: 2026-05-01T14:35:32.037Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 544
File: modules/nixos/core/remote.nix:153-179
Timestamp: 2026-05-01T14:35:32.037Z
Learning: In this repo’s NixOS module code (e.g., shell scripts produced via `writeShellApplication` inside `modules/nixos/**`), do not treat missing `XDG_STATE_HOME` fallbacks (like `${XDG_STATE_HOME:-$HOME/.local/state}`) as an error in the embedded shell script. On NixOS user sessions, `XDG_STATE_HOME` is reliably set via PAM/systemd, so flagging its absence as potentially unset is overly defensive for these generated scripts.
Applied to files:
modules/nixos/core/sops.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/stylix.nixmodules/nixos/server/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/core/nix.nixmodules/nixos/core/host/persistence.nix
📚 Learning: 2026-06-20T14:33:25.328Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 590
File: modules/nixos/server/monitoring/collector/tempo.nix:71-72
Timestamp: 2026-06-20T14:33:25.328Z
Learning: When reviewing DaRacci/nix-config NixOS modules that use sops-nix, do not flag `sops.secrets` entries as missing `owner`, `group`, `mode`, or `restartUnits` if the secret declarations are only placeholder sources for `sops.templates`:
- The secret value is referenced exclusively via `config.sops.placeholder.<NAME>` inside a `sops.templates` definition (i.e., no other code reads the decrypted secret from the raw secret path).
- The rendered `sops.templates` output is what is used by systemd via a `systemd.services.*.serviceConfig.EnvironmentFile` (the template is the effective boundary).
In this pattern, the template’s own `restartUnits` are the relevant access-control/restart boundary; the raw `sops.secrets` files are only decrypted in-memory by sops-nix (run as root) to render the template. Therefore, empty-attrset `sops.secrets.<NAME> = { };` declarations should not be treated as missing permissions/restart hooks when they are only feeding a `sops.templates` placeholder.
Applied to files:
modules/nixos/core/sops.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/stylix.nixmodules/nixos/server/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/core/nix.nixmodules/nixos/core/host/persistence.nix
📚 Learning: 2026-05-01T09:57:09.578Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 544
File: modules/nixos/services/ai-agent.nix:15-15
Timestamp: 2026-05-01T09:57:09.578Z
Learning: In this repo’s Nix modules, `inputs.services-zeroclaw` is a flake input that resolves to an attrset containing a `_file` attribute, and Nix coerces that attrset to a file path via `_file`. When importing/using it as a path in `imports` (e.g., `modules/nixos/services/ai-agent.nix`), use the string interpolation form "${inputs.services-zeroclaw}". Do not change it to `inputs.services-zeroclaw` (raw attrset form) in `imports`, because it will not work correctly.
Applied to files:
modules/nixos/core/sops.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/stylix.nixmodules/nixos/server/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/core/nix.nixmodules/nixos/core/host/persistence.nix
📚 Learning: 2026-03-18T23:46:49.905Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 546
File: .woodpecker/lix.yaml:15-15
Timestamp: 2026-03-18T23:46:49.905Z
Learning: In nix-config repository (.woodpecker/*.yaml), image references intentionally omit explicit tags or digests (e.g., registry.racci.dev/lix-woodpecker without :tag). Do not flag or suggest adding explicit tags or digests to these image references; treat such omissions as intentional and maintain consistency across the CI config.
Applied to files:
.woodpecker/test-vm.yaml
🪛 LanguageTool
docs/src/development/vm_integration_tests.md
[uncategorized] ~207-~207: Loose punctuation mark.
Context: ...run. ### Requirements - /dev/kvm: QEMU tests require KVM acceleration. Wi...
(UNLIKELY_OPENING_PUNCTUATION)
🪛 markdownlint-cli2 (0.22.1)
docs/src/SUMMARY.md
[warning] 1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
docs/src/development/vm_integration_tests.md
[warning] 13-13: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
[warning] 233-233: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
🔇 Additional comments (34)
modules/nixos/server/default.nix (2)
193-196: LGTM!Also applies to: 143-154, 230-243
74-80: 🎯 Functional CorrectnessNo change needed
getAllAttrsFuncalready routes throughfilterEmpty, sonullresults are removed before callers see the list.> Likely an incorrect or invalid review comment.flake/default.nix (1)
49-52: LGTM!flake/nixos/flake-module.nix (3)
28-28: LGTM!Also applies to: 63-70, 82-96
74-78: 📐 Maintainability & Code QualityNo issue here —
allocationson line 44 is the partition’s option definition, andconfig.partitions.nixos.module.allocationsreads the evaluated partition output, so this isn’t a self-reference.> Likely an incorrect or invalid review comment.
78-78: 🎯 Functional Correctness
x86_64-linuxmatches the current host setup. No server host overridessystemornixpkgs.hostPlatform, so this test builder pin isn’t introducing a mismatch.> Likely an incorrect or invalid review comment._run_tests.sh (1)
1-41: LGTM!docs/src/SUMMARY.md (1)
19-19: LGTM!docs/src/development/vm_integration_tests.md (3)
13-20: 📐 Maintainability & Code Quality | ⚡ Quick winAdd a language identifier to the fenced code block.
Static analysis (MD040) flags this fence as missing a language tag.
📝 Proposed fix
-``` +```text flake.nix ├── nixosConfigurations/ # Production host configs (nixio, nixai, ...) └── nixosTestConfigurations/ # VM test derivations ├── nixio # Auto-discovered per-host test ├── nixai # Auto-discovered per-host test └── proxy-routing # Explicit scenario test</details> <!-- cr-comment:v1:92d2f65611389465ea059517 --> _Source: Linters/SAST tools_ --- `231-236`: _📐 Maintainability & Code Quality_ | _⚡ Quick win_ **Surround fenced code block with blank lines.** Static analysis (MD031) flags this fence for missing surrounding blank lines inside the numbered list item. <!-- cr-comment:v1:13f789d347de719049e8de86 --> _Source: Linters/SAST tools_ --- `1-372`: LGTM! <!-- cr-comment:v1:59d5e4a43eee9ad790f9aaad --> </blockquote></details> <details> <summary>.woodpecker/test-vm.yaml (1)</summary><blockquote> `1-24`: LGTM! <!-- cr-comment:v1:e5ff72a4d621faedb525cb87 --> </blockquote></details> <details> <summary>hosts/server/nixai/voice.nix (1)</summary><blockquote> `19-32`: _🎯 Functional Correctness_ | _⚡ Quick win_ **Same `grep -i loadstate` correctness issue as ai-agent.nix.** `grep -i loadstate` matches `LoadState=not-found` equally well, so this never actually validates the units loaded successfully. Same fix applies: match `loadstate=loaded` explicitly. <!-- cr-comment:v1:7e21eed4f7ce5c29e01d7561 --> </blockquote></details> <details> <summary>hosts/server/nixai/web.nix (1)</summary><blockquote> `43-48`: _🎯 Functional Correctness_ | _⚡ Quick win_ **Same `grep -i loadstate` correctness issue as ai-agent.nix.** This assertion will pass even if `open-webui.service` fails to load; the grep matches the key name regardless of value. <!-- cr-comment:v1:df564e34b1c67d92463fc11a --> </blockquote></details> <details> <summary>hosts/server/nixarr/arr/default.nix (1)</summary><blockquote> `29-34`: _🎯 Functional Correctness_ | _⚡ Quick win_ **Same `grep -i loadstate` correctness issue as ai-agent.nix.** Same problem — `grep -i loadstate` doesn't verify the unit actually loaded (`loaded` vs `not-found`/`masked`). <!-- cr-comment:v1:f37060fdd0a4bdaee84246d9 --> </blockquote></details> <details> <summary>hosts/server/nixio/dashboard.nix (1)</summary><blockquote> `61-66`: _🎯 Functional Correctness_ | _⚡ Quick win_ **Same `grep -i loadstate` correctness issue as ai-agent.nix.** <!-- cr-comment:v1:79af61b41aa3813fc2207071 --> </blockquote></details> <details> <summary>hosts/server/nixio/database.nix (3)</summary><blockquote> `82-101`: _🎯 Functional Correctness_ | _⚡ Quick win_ **Same `grep -i loadstate` correctness issue as ai-agent.nix.** Applies to `pgadmin`, `postgres-exporter`, `redis-exporter`, and `postgresql-backup` here. <!-- cr-comment:v1:1cd1828dc8ade447fbedff7e --> --- `70-80`: LGTM! <!-- cr-comment:v1:8822adf55a081b15db2b73a6 --> --- `41-48`: _🎯 Functional Correctness_ **These attrs are safe to drop here.** The merged secret set only feeds `sops.secrets`, and the in-tree test secret generator keys off `attrNames`, not these value fields. > Likely an incorrect or invalid review comment. <!-- cr-comment:v1:68c1c4c6cf08c07e78372f67 --> </blockquote></details> <details> <summary>hosts/server/nixio/default.nix (1)</summary><blockquote> `90-94`: LGTM! <!-- cr-comment:v1:d9982d7f98ac35594607c7b6 --> </blockquote></details> <details> <summary>hosts/server/nixarr/default.nix (1)</summary><blockquote> `80-134`: _🎯 Functional Correctness_ **Same no-op `loadstate` grep pattern as flagged in `hosts/server/nixarr/arr/downloader.nix`.** All nine unit tests here (jellyfin, seerr, samba, wireguard, sonarr, radarr, lidarr, prowlarr, bazarr) share the same flaw: `grep -i loadstate` matches unconditionally regardless of the actual `LoadState` value, so the check never fails. <!-- cr-comment:v1:e8e267c815b56a191607fafb --> </blockquote></details> <details> <summary>hosts/server/nixcloud/home-assistant/connectivity.nix (1)</summary><blockquote> `134-157`: _🎯 Functional Correctness_ **Same no-op `loadstate` grep pattern as flagged in `hosts/server/nixarr/arr/downloader.nix`.** All four unit tests (mosquitto, esphome, zigbee2mqtt, matter-server) share the same flaw. <!-- cr-comment:v1:6c32e8f6943477eade2f5a7c --> </blockquote></details> <details> <summary>hosts/server/nixcloud/home-assistant/default.nix (1)</summary><blockquote> `94-106`: _🎯 Functional Correctness_ **Same no-op `loadstate` grep pattern as flagged in `hosts/server/nixarr/arr/downloader.nix`.** Both unit tests (home-assistant, avahi) share the same flaw. <!-- cr-comment:v1:f7fa9afa94f110eeef45afc0 --> </blockquote></details> <details> <summary>hosts/server/nixcloud/homebox.nix (1)</summary><blockquote> `31-35`: _🎯 Functional Correctness_ **Same no-op `loadstate` grep pattern as flagged in `hosts/server/nixarr/arr/downloader.nix`.** <!-- cr-comment:v1:26c2e015ac2bfa71f20b79cc --> </blockquote></details> <details> <summary>hosts/server/nixio/proxy.nix (1)</summary><blockquote> `132-148`: _🎯 Functional Correctness_ **Same no-op `loadstate` grep pattern as flagged in `hosts/server/nixarr/arr/downloader.nix`.** All three unit tests (caddy, upgrade-status, hacompanion) share the same flaw. <!-- cr-comment:v1:68bbfb15517edf56ce2e6683 --> </blockquote></details> <details> <summary>hosts/server/nixio/storage.nix (1)</summary><blockquote> `55-79`: _🎯 Functional Correctness_ **Same no-op `loadstate` grep pattern as flagged in `hosts/server/nixarr/arr/downloader.nix`.** All four unit tests (minio, seaweedfs-master, seaweedfs-volume, seaweedfs-filer) share the same flaw. <!-- cr-comment:v1:4eb13e26664e04c6962a78d4 --> </blockquote></details> <details> <summary>hosts/server/nixdev/coder.nix (1)</summary><blockquote> `62-62`: LGTM! <!-- cr-comment:v1:24ba040def30653820a850fd --> </blockquote></details> <details> <summary>hosts/server/nixio/adguard.nix (1)</summary><blockquote> `183-183`: LGTM! <!-- cr-comment:v1:9382916b689dc9fbc9bce7f5 --> </blockquote></details> <details> <summary>modules/nixos/core/nix.nix (1)</summary><blockquote> `7-19`: LGTM! Also applies to: 38-41, 73-76, 86-86 <!-- cr-comment:v1:91d49b7d56f0824f7d67afa0 --> </blockquote></details> <details> <summary>modules/nixos/core/boot/secureboot.nix (1)</summary><blockquote> `19-19`: LGTM! Also applies to: 25-41 <!-- cr-comment:v1:e76fb6e431ce3940b5aaac4a --> </blockquote></details> <details> <summary>modules/nixos/core/host/persistence.nix (1)</summary><blockquote> `215-215`: LGTM! Also applies to: 217-273 <!-- cr-comment:v1:212612c588fe512ca16feb11 --> </blockquote></details> <details> <summary>modules/nixos/core/sops.nix (1)</summary><blockquote> `28-28`: LGTM! Also applies to: 43-62 <!-- cr-comment:v1:ef05b7a1b451ded242cc7799 --> </blockquote></details> <details> <summary>modules/nixos/core/stylix.nix (1)</summary><blockquote> `27-27`: LGTM! Also applies to: 29-39 <!-- cr-comment:v1:4d4fb64d4924bb8923085950 --> </blockquote></details> <details> <summary>modules/nixos/server/proxy/extensions/api-key-auth.nix (1)</summary><blockquote> `35-47`: LGTM! <!-- cr-comment:v1:d93203fd9b2c8551d4cddefc --> </blockquote></details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
|
@coderabbitai full review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 32
♻️ Duplicate comments (1)
tests/lib.nix (1)
6-10: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
runOnAllNodesstill passes the string"node.name", not the node object — same bug flagged previously.A prior review on this file identified this exact issue and was marked "Addressed in commits 78c9dd9 to 2a6a397", but the code shown still interpolates the literal string
"node.name"into the callback. Any caller doingf = node: "${node}.wait_for_unit(...)"would produce invalid Python likenode.name.wait_for_unit(...). If this was meant to be fixed, the fix doesn't appear to be present in this version of the file.🔧 Suggested fix
/* - Run a python function on all nodes in the cluster. - The function takes one argument, a function with one argument which is the node's name. + Run a Python snippet on all nodes in the cluster. + The callback receives the Python node variable. */ runOnAllNodes = f: '' for node in cluster.nodes: with subtest(node.name): - ${f "node.name"} + ${f "node"} '';🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/lib.nix` around lines 6 - 10, `runOnAllNodes` is still passing the literal string "node.name" into the callback instead of the actual node object. Update the `runOnAllNodes` helper in `tests/lib.nix` so the interpolated argument uses the loop variable itself inside the generated Python snippet, not a quoted string, and verify callers like `f = node: "${node}.wait_for_unit(...)"` receive a real node reference.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@_run_tests.sh`:
- Line 7: The HOSTS array in _run_tests.sh is hardcoded and can drift from the
actual NixOS test targets. Update the script to discover hosts dynamically using
the same approach as .woodpecker/test-vm.yaml and the docs, via nix eval on
.#nixosTestConfigurations with builtins.attrNames. Make sure the main
host-selection logic in _run_tests.sh consumes that generated list so newly
added hosts like nixarr, nixcloud, and nixserv are picked up automatically.
In @.woodpecker/test-vm.yaml:
- Around line 28-32: The VM test loop in the test step runs each host serially,
so it will become a CI bottleneck as the host list grows. Update the logic
around the host iteration in the test script to use a parallelized or
dynamically generated execution strategy instead of a single shell loop in one
agent, while keeping the current `nix eval .#nixosTestConfigurations` host
discovery and `nix build` per-host behavior intact.
- Around line 28-32: The “Run VM tests” loop is swallowing failures because the
`nix build` error is followed by a successful `echo`, so the shell step always
exits 0. Update the VM test commands in `.woodpecker/test-vm.yaml` to let `nix
build` failures propagate from the loop instead of masking them, and ensure the
step exits non-zero when any host build fails. Use the existing `nix build
".#nixosTestConfigurations.$host"` loop and the `echo "::group::VM test: $host"`
/ `echo "::endgroup::"` structure as the location to fix this behavior.
- Around line 1-5: The PR-only KVM job currently builds every server and
scenario host via nixosTestConfigurations, which does not scale as the repo
grows. Update the test-vm pipeline to run only affected hosts by filtering
against the PR’s changed files (for example, comparing changes under
hosts/server/** and scenario directories) before expanding the build set. Keep
the logic anchored around the test-vm job and the nixosTestConfigurations
consumer so the affected-host selection happens before VM builds are scheduled.
In `@docs/src/development/vm_integration_tests.md`:
- Around line 231-236: The Markdown list item in the documentation section is
missing a blank line before the fenced bash block, triggering MD031. Update the
content around the existing `nixosTestConfigurations` guidance so the fenced
code block is separated by a blank line from the preceding list item text,
keeping the same wording and placement of the `nix build
.#nixosTestConfigurations.<name>` example.
- Around line 13-20: The fenced block in the VM integration tests docs is
missing a language identifier, which triggers markdownlint. Update the code
fence in the relevant documentation snippet to include an explicit language tag
using the existing fenced block around the flake.nix tree so the markdown linter
recognizes it.
In `@flake/nixos/flake-module.nix`:
- Around line 80-96: The `nixosTestConfigurations` generation in the
`serverHosts` pipeline ignores `server.tests.enable`, so every host gets a test
entry even when it opted out. Update the `builtins.map`/`builtins.listToAttrs`
flow in this flake module to consult
`self.nixosConfigurations.${hostName}.config.server.tests.enable` before calling
`builder`, and skip or filter out hosts where that flag is false. Use the
existing `serverHosts`, `hostName`, and `builder` symbols to keep the check
localized to the test-entry construction.
- Around line 102-117: `builtins.readDir` in the scenario discovery logic is
including non-directory entries, so only directories should be treated as
scenarios. Update the `scenarioName` source in the `builtins.listToAttrs` block
inside the scenario loader to filter `builtins.readDir scenariosDir` by entries
whose type is directory before calling `import
"${scenariosDir}/${scenarioName}/test.nix"`. Keep the fix localized to this
scenario enumeration code so only real scenario folders are mapped.
- Around line 106-111: The scenario-mode builder call is missing the required
inputs argument, causing evaluation to fail in every discovered scenario. Update
the scenario branch in the flake-module logic where builder is invoked so it
passes inputs through alongside self, pkgs, and lib. Use the builder call in the
scenarioName mapping to locate the change and ensure tests/builder.nix receives
inputs consistently.
In `@hosts/server/nixai/ai-agent.nix`:
- Around line 10-23: The unit tests for ai-agent-api and ai-agent-dashboard only
grep for the LoadState field, so they can pass even when the service is missing.
Update each testScript to assert the exact loaded state from systemctl show by
matching LoadState=loaded instead of just searching for the key, using the
ai-agent-api and ai-agent-dashboard unit checks as the targets to fix.
In `@hosts/server/nixai/voice.nix`:
- Around line 19-32: The unit tests for wyoming-piper and wyoming-whisper are
only checking that systemctl show prints the LoadState field name, not that the
service is actually loaded. Update the testScript checks in tests.units for
wyoming-piper and wyoming-whisper to assert the LoadState value is loaded (using
the existing service names wyoming-piper.service and
wyoming-faster-whisper.service) so the tests fail unless the units are truly
loaded.
In `@hosts/server/nixarr/arr/downloader.nix`:
- Around line 88-100: The unit checks in server.tests.units are currently
ineffective because grepping for LoadState never proves the service exists.
Update the transmission and sabnzbd testScript assertions to validate the actual
LoadState value returned by systemctl show for the relevant unit names, using
the existing nixarr.succeed calls so the tests fail when a unit is missing or
not loaded.
In `@hosts/server/nixarr/default.nix`:
- Around line 80-134: The unit tests in tests.units are using a grep on
systemctl show output that matches the LoadState property name instead of
verifying the service state. Update each testScript to assert the actual value
of LoadState for the relevant service units in nixarr, and consider
de-duplicating the repeated
jellyfin/seerr/samba/wg/sonarr/radarr/lidarr/prowlarr/bazarr blocks with a small
helper or genAttrs in default.nix so the same fixed check is applied
consistently.
In `@hosts/server/nixcloud/home-assistant/connectivity.nix`:
- Around line 134-158: The unit tests for mosquitto, esphome, zigbee2mqtt, and
matter-server are using an ineffective `systemctl show ... | grep -i loadstate`
check that only matches the property name, not the actual service state. Update
each `testScript` in `server.tests.units` to assert on the `LoadState` value
instead, using `systemctl show <unit> --property=LoadState --value` and checking
that it matches `loaded`; keep the existing unit names and `testScript` blocks
so the change is localized and easy to verify.
In `@hosts/server/nixcloud/home-assistant/default.nix`:
- Around line 94-106: The unit tests in server.tests.units for home-assistant
and avahi are using an ineffective systemctl show | grep -i loadstate check that
can never fail on a missing or unloaded unit. Update the testScript assertions
to verify the actual LoadState value from systemctl show (using the existing
nixcloud.succeed checks) so each test fails when the service is not loaded; use
the home-assistant and avahi test blocks as the places to fix.
In `@hosts/server/nixcloud/homebox.nix`:
- Around line 31-36: The current homebox unit test uses an ineffective systemctl
status check that can pass even when the service fails to load. Update the
testScript in homebox to assert the service actually loads successfully by
checking a stronger signal from systemctl show or an equivalent loaded/active
state condition, using the homebox.service target in the existing test block.
In `@hosts/server/nixcloud/identity.nix`:
- Around line 215-220: The current unit test in tests.units.kanidm is
ineffective because systemctl show always emits LoadState, so grepping for
loadstate will pass even when kanidm.service is missing or broken. Update the
testScript to assert the actual expected state of the kanidm.service unit using
a more specific check on systemctl show output, and apply the same fix anywhere
the same grep pattern is reused across the host test files.
In `@hosts/server/nixdev/automation.nix`:
- Around line 100-107: The unit test in the n8n testScript uses a weak assertion
because `systemctl show` always emits the `LoadState=` key, so the current grep
can succeed even when the service is not loaded. Update the assertion to check
the actual `LoadState` value returned by `systemctl show` instead of matching
the key name, and apply the same fix anywhere this pattern is repeated in the
automation tests.
In `@hosts/server/nixdev/ci.nix`:
- Around line 25-30: The github-runners test in
server.tests.units.github-runners uses a weak loadstate check that only matches
the property name, so it never verifies the actual unit state. Update the
testScript to assert the real output of systemctl show for the
github-runner-nixos-runner-0.service unit, using the load state value itself
rather than a grep on the key, so the test fails when the service is not
properly loaded.
In `@hosts/server/nixdev/coder.nix`:
- Around line 36-43: The current tests.units.coder.testScript still relies on a
weak loadstate check, so replace it with a stronger assertion that verifies
coder.service is actually running and healthy via systemctl show or status
fields such as ActiveState/SubState. Update the coder unit test in tests.units
to use the service’s real runtime state instead of only grep’ing for loadstate.
In `@hosts/server/nixdev/default.nix`:
- Around line 26-33: The docker unit test in server.tests.units still uses a
weak loadstate-only check, so tighten the assertion in the docker testScript to
verify the service is actually active/running rather than just loaded. Update
the systemctl grep command in this docker block to assert on the operational
state, using the existing docker.service test as the reference point so it
matches the stronger check used elsewhere.
In `@hosts/server/nixdev/registry.nix`:
- Around line 97-104: The docker-registry unit test in tests.units uses a weak
loadstate check, so update the testScript for docker-registry to assert the
service is actually running instead of only loaded. Use a stronger
systemctl-based check such as querying the service state/active status in a way
that fails unless docker-registry.service is started successfully.
In `@hosts/server/nixdev/woodpecker.nix`:
- Around line 59-72: The unit tests for woodpecker-server and woodpecker-agent
only check LoadState, which is too weak and can pass even when the services are
not actually healthy. Update the testScript assertions in the tests.units block
to validate the services are really started and operational, using the same
stronger checks as the automation.nix fix, and reference the woodpecker-server
and woodpecker-agent service names so the tests verify actual service state
rather than just being loaded.
In `@hosts/server/nixio/adguard.nix`:
- Around line 223-228: The adguard unit test in server.tests.units.adguard uses
a weak systemctl show loadstate check, which is too shallow for validating the
service. Update the testScript to assert a stronger condition on
adguardhome.service, such as verifying the service is active/running or
otherwise confirming the expected runtime state, using the existing
nixio.succeed test block.
In `@hosts/server/nixio/default.nix`:
- Around line 90-94: The baseline-io test in server.tests.units.baseline-io
currently only checks that journalctl runs, not that the boot was healthy.
Update the testScript to assert on the actual log content by querying journalctl
for recent entries and failing if any -p err (or worse) messages are present, so
the test verifies a clean boot instead of just command availability.
- Around line 96-102: The kernel-forwarding unit test is tautological because it
sets the forwarding sysctls before asserting them. Update
server.tests.units.kernel-forwarding in the nixio/default.nix testScript to only
verify the configured state via sysctl reads, and remove the sysctl -w calls so
the test checks the host’s existing NixOS configuration rather than forcing
net.ipv4.ip_forward and net.ipv6.conf.all.forwarding to 1 first.
In `@hosts/server/nixio/proxy.nix`:
- Around line 132-149: The unit tests for caddy, upgrade-status, and hacompanion
are only checking for loadstate with a case-insensitive grep, which is too weak
and matches the same ineffective pattern as the other host tests. Update each
testScript in server.tests.units to assert the service is actually
active/running using the appropriate systemctl property or a more specific
status check, and keep the assertions aligned with the existing caddy,
upgrade-status, and hacompanion service names so the test verifies real service
health.
In `@hosts/server/nixio/storage.nix`:
- Around line 55-79: The unit tests for minio and the seaweedfs services are
using the same ineffective systemctl check, so the assertion is not validating
the service state meaningfully. Update the testScript entries in
server.tests.units for minio, seaweedfs-master, seaweedfs-volume, and
seaweedfs-filer to use a stronger service status assertion in place of the
current systemctl show ... | grep -i loadstate pattern, matching the approach
used to fix the same issue elsewhere. Keep the existing test names and
structure, but change the command inside each testScript so it actually verifies
the intended service is loaded/active.
In `@hosts/server/nixserv/default.nix`:
- Around line 50-54: The atticd-config test currently only runs systemctl show
atticd.service, which always exits successfully and does not verify anything
meaningful. Update the testScript in atticd-config to assert on specific output
from atticd.service, using the existing nixserv.succeed helper plus a
grep/assertion for expected service properties so the test fails when the unit
is masked, missing, or misconfigured.
In `@modules/nixos/server/tests.nix`:
- Around line 37-45: The testScript option currently advertises functionTo str
support, but the builder still treats unit.testScript as a plain string, so
function values will fail during evaluation. Either remove the functionTo str
branch from the testScript option in tests.nix, or update the builder logic in
tests/builder.nix to detect function-form scripts and invoke them before
interpolating. Use the existing testScript option and builder interpolation path
as the main places to fix.
In `@run-test.sh`:
- Around line 2-4: The test script currently writes build output to a
predictable shared path, which can be clobbered by concurrent runs and is
unsafe. Update run-test.sh to create a unique temporary log file with mktemp,
use that path in the nix build redirect, and keep the file reference in a
variable so the rest of the script can read it consistently.
In `@tests/builder.nix`:
- Around line 34-40: The multi-line Nix strings used by baselineAssertions and
unit.testScript are being interpolated directly inside with subtest() blocks,
which can break Python indentation after the first line. Move these helpers so
each one is a self-contained Python block with its own indentation, then invoke
them flush-left from the host and scenario branches instead of wrapping the
interpolated text inside with subtest():. Apply the same pattern anywhere
unit.testScript is embedded so all assertions stay inside the intended scope.
---
Duplicate comments:
In `@tests/lib.nix`:
- Around line 6-10: `runOnAllNodes` is still passing the literal string
"node.name" into the callback instead of the actual node object. Update the
`runOnAllNodes` helper in `tests/lib.nix` so the interpolated argument uses the
loop variable itself inside the generated Python snippet, not a quoted string,
and verify callers like `f = node: "${node}.wait_for_unit(...)"` receive a real
node reference.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 2bac686a-9cb4-46ce-b466-e3889ab9bdff
⛔ Files ignored due to path filters (21)
openspec/changes/archive/2026-06-23-server-cluster-monitoring/proposal.mdis excluded by!openspec/**openspec/changes/comprehensive-server-tests/.openspec.yamlis excluded by!openspec/**openspec/changes/comprehensive-server-tests/design.mdis excluded by!openspec/**openspec/changes/comprehensive-server-tests/proposal.mdis excluded by!openspec/**openspec/changes/comprehensive-server-tests/specs/database.mdis excluded by!openspec/**openspec/changes/comprehensive-server-tests/specs/network.mdis excluded by!openspec/**openspec/changes/comprehensive-server-tests/specs/proxy.mdis excluded by!openspec/**openspec/changes/comprehensive-server-tests/specs/security.mdis excluded by!openspec/**openspec/changes/comprehensive-server-tests/specs/storage.mdis excluded by!openspec/**openspec/changes/comprehensive-server-tests/tasks.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/.openspec.yamlis excluded by!openspec/**openspec/changes/testing-framework-predeploy/README.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/design.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/proposal.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/specs/server-vm-test-harness/spec.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/specs/service-aware-vm-tests/spec.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/specs/vm-test-documentation/spec.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/specs/vm-test-profile-overrides/spec.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/specs/vm-test-secret-generation/spec.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/specs/woodpecker-vm-test-gating/spec.mdis excluded by!openspec/**openspec/changes/testing-framework-predeploy/tasks.mdis excluded by!openspec/**
📒 Files selected for processing (55)
.woodpecker/test-vm.yaml_run_tests.shdocs/src/SUMMARY.mddocs/src/development/vm_integration_tests.mdflake/default.nixflake/nixos/flake-module.nixhosts/server/nixai/ai-agent.nixhosts/server/nixai/voice.nixhosts/server/nixai/web.nixhosts/server/nixarr/arr/default.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixarr/default.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixcloud/homebox.nixhosts/server/nixcloud/identity.nixhosts/server/nixcloud/immich.nixhosts/server/nixcloud/music.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixcloud/search.nixhosts/server/nixdev/automation.nixhosts/server/nixdev/ci.nixhosts/server/nixdev/coder.nixhosts/server/nixdev/default.nixhosts/server/nixdev/registry.nixhosts/server/nixdev/woodpecker.nixhosts/server/nixio/adguard.nixhosts/server/nixio/dashboard.nixhosts/server/nixio/database.nixhosts/server/nixio/default.nixhosts/server/nixio/proxy.nixhosts/server/nixio/storage.nixhosts/server/nixmon/default.nixhosts/server/nixserv/default.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/host/persistence.nixmodules/nixos/core/nix.nixmodules/nixos/core/sops.nixmodules/nixos/core/stylix.nixmodules/nixos/server/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/server/storage/seaweedfs.nixmodules/nixos/server/tests.nixmodules/nixos/services/ai-agent.nixrun-test.shtests/builder.nixtests/lib.nixtests/mkNode.nixtests/profiles/dummy.yamltests/profiles/vm-test.nixtests/scenarios/database-backup-chain/test.nixtests/scenarios/firewall-port-audit/test.nixtests/scenarios/io-guardian/test.nixtests/scenarios/proxy-routing/test.nixtests/scenarios/redis-remote-connect/test.nix
📜 Review details
⚠️ CI failures not shown inline (4)
GitHub Actions: Build and test flake outputs / 1_generate-matrix.txt: feat: cluster test framework
Conclusion: failure
##[group]Run workflow/nix-shell-action@v4.0.0
with:
flakes: nixpkgs#jq,nixpkgs#nushell
script: SCRIPT_ARGS="--json"
if [[ -n "692fe91125d3630dfe4e3a6c6872a45728687c2f" ]]; then
SCRIPT_ARGS+=" --range 692fe91125d3630dfe4e3a6c6872a45728687c2f..e34b5188ef8201a065d95ea58e8d59c1003cecbd"
else
SCRIPT_ARGS+=" $(find . -type f | sed 's|^\./||' | grep -v '^\.git/' | tr '\n' ' ')"
fi
CHANGED_HOSTS=$(./flake/ci/detect-affected-outputs.nu nixosConfigurations $SCRIPT_ARGS | jq 'to_entries | map("nixosConfigurations." + .key + ".config.system.build.toplevel")' )
CHANGED_USERS=$(./flake/ci/detect-affected-outputs.nu homeConfigurations $SCRIPT_ARGS | jq 'to_entries | map("homeConfigurations." + .key + ".activationPackage")' )
EXTRA_SPACE='["nixmi"]'
NO_BUILD='["nixmi"]'
{
echo 'matrix<<EOF'
jq -n --argjson hosts "$CHANGED_HOSTS" --argjson users "$CHANGED_USERS" \
--argjson rule_extra_space "$EXTRA_SPACE" \
--argjson rule_no_build "$NO_BUILD" '
($hosts + $users) | map({
attr: .,
system: "x86_64-linux",
extraSpace: IN($rule_extra_space[]; (. | split(".")[1])),
noBuild: IN($rule_no_build[]; (. | split(".")[1]))
})' 2>/dev/null || echo "[]"
echo EOF
} >> "$GITHUB_OUTPUT"
interpreter: bash
packages: bash
flakes-from-devshell: false
##[endgroup]
fetching path input 'path:/nix/store/3a2vdn5i7vd2wl654xs8nb52jf1v6cbh-source'
fetching path input 'path:/nix/store/3a2vdn5i7vd2wl654xs8nb52jf1v6cbh-source'
these 2 paths will be fetched (13.06 MiB download, 58.01 MiB unpacked):
/nix/store/ncw52xsl5hgplh8csybbp9fli64iw1aq-jq-1.8.1-man
/nix/store/h6y0fybw66qx4d784nh515m4s8160ian-nushell-0.113.0
copying path '/nix/store/ncw52xsl5hgplh8csybbp9fli64iw1aq-jq-1.8.1-man' from 'https://cache.nixos.org'...
copying path '/nix/store/h6y0fybw66qx4d784nh515m4s8160ian-nushell-0.113.0' from 'https://cache.nixos.org'...
fetching path input 'path:/nix/store/3a2vdn5i7vd2wl654xs8nb52jf1v6cbh-source'
fetching git input 'git+file:///run...
Commit Status: ci/woodpecker/pr/check: ci/woodpecker/pr/check
Conclusion: failure
Pipeline failed
Commit Status: ci/woodpecker/pr/check-upstream-todos: ci/woodpecker/pr/check-upstream-todos
Conclusion: failure
Pipeline failed
Commit Status: ci/woodpecker/pr/flake-checker: ci/woodpecker/pr/flake-checker
Conclusion: failure
Pipeline failed
🧰 Additional context used
📓 Path-based instructions (13)
docs/**/*
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Project documentation should be placed in the
docs/directory
Files:
docs/src/SUMMARY.mddocs/src/development/vm_integration_tests.md
docs/src/**/*.md
📄 CodeRabbit inference engine (.opencode/skills/docs/SKILL.md)
docs/src/**/*.md: Use underscore filenames (e.g.,my_new_feature.md) instead of hyphens for documentation files
Keep documentation prose focused on behavior, architecture, usage examples, and operational notes; let generated fragments provide exhaustive option reference
Files:
docs/src/SUMMARY.mddocs/src/development/vm_integration_tests.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Verify documentation accurately reflects new behavior in docs/ directory before proceeding to commit
Files:
docs/src/SUMMARY.mddocs/src/development/vm_integration_tests.md
**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/code-style-nix)
**/*.nix: Follow Nix code style conventions and best practices
Use consistent indentation and formatting in Nix configuration files
Follow established patterns for module organization in home-manager configurations
**/*.nix: Format code and check syntax usingnix fmt
Evaluate Nix expressions without building usingnix evalwith the target configuration path
Format specific Nix files or directories usingnix fmtfollowed by the file or directory path
Use--show-traceflag withnix buildornix evalcommands to diagnose evaluation errors
For infinite recursion errors in Nix builds, check for circular imports or conflicting option definitions
**/*.nix: Usebuiltins.traceto add trace statements and inspect values during Nix evaluation (format:builtins.trace "message: ${toString var}" var)
Usebuiltins.toJSONto convert complex Nix attribute sets to JSON for easier inspection during evaluation
Check for circular imports between modules and option definitions that depend on themselves to resolve infinite recursion errors
Verify attribute names are correct and imports are complete when debugging 'attribute not found' errors in Nix
Check option type definitions and ensure provided values match the expected type to resolve type mismatch errors
Read assertion messages and provide required configuration values when assertion failures occur in NixOS modules
**/*.nix: Store sensitive data insecrets.yamlencrypted with sops instead of hardcoding passwords, API keys, or tokens in plain text
Declare sops secrets with properowner,group, andmodeattributes; use restrictive modes like0400for secrets files
SetrestartUnitsorreloadUnitsfor sops secrets declarations so services that depend on secrets are restarted when secrets change
Useconfig.sops.placeholderin sops templates instead of directly interpolating secret paths in multi-secret templates
Do not pass secrets as environment variables in plain Nix; useenvironmentFileor...
Files:
hosts/server/nixdev/woodpecker.nixhosts/server/nixio/default.nixtests/scenarios/proxy-routing/test.nixtests/lib.nixtests/scenarios/firewall-port-audit/test.nixhosts/server/nixdev/coder.nixhosts/server/nixarr/default.nixtests/scenarios/database-backup-chain/test.nixhosts/server/nixcloud/immich.nixhosts/server/nixcloud/search.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixdev/ci.nixhosts/server/nixio/proxy.nixhosts/server/nixcloud/identity.nixhosts/server/nixio/adguard.nixhosts/server/nixmon/default.nixhosts/server/nixcloud/homebox.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixdev/automation.nixhosts/server/nixio/dashboard.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixai/web.nixhosts/server/nixcloud/music.nixhosts/server/nixarr/arr/default.nixmodules/nixos/server/storage/seaweedfs.nixmodules/nixos/server/default.nixhosts/server/nixdev/default.nixhosts/server/nixio/storage.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixai/voice.nixhosts/server/nixdev/registry.nixmodules/nixos/core/boot/secureboot.nixflake/nixos/flake-module.nixtests/builder.nixhosts/server/nixio/database.nixtests/scenarios/redis-remote-connect/test.nixmodules/nixos/core/stylix.nixflake/default.nixhosts/server/nixai/ai-agent.nixtests/mkNode.nixhosts/server/nixserv/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixtests/profiles/vm-test.nixmodules/nixos/core/sops.nixmodules/nixos/core/host/persistence.nixmodules/nixos/server/tests.nixmodules/nixos/core/nix.nixmodules/nixos/services/ai-agent.nixtests/scenarios/io-guardian/test.nix
hosts/server/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Server machine-specific NixOS configs should be placed in
hosts/server/<machine>/
Files:
hosts/server/nixdev/woodpecker.nixhosts/server/nixio/default.nixhosts/server/nixdev/coder.nixhosts/server/nixarr/default.nixhosts/server/nixcloud/immich.nixhosts/server/nixcloud/search.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixdev/ci.nixhosts/server/nixio/proxy.nixhosts/server/nixcloud/identity.nixhosts/server/nixio/adguard.nixhosts/server/nixmon/default.nixhosts/server/nixcloud/homebox.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixdev/automation.nixhosts/server/nixio/dashboard.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixai/web.nixhosts/server/nixcloud/music.nixhosts/server/nixarr/arr/default.nixhosts/server/nixdev/default.nixhosts/server/nixio/storage.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixai/voice.nixhosts/server/nixdev/registry.nixhosts/server/nixio/database.nixhosts/server/nixai/ai-agent.nixhosts/server/nixserv/default.nix
hosts/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/modules/SKILL.md)
Enable NixOS modules in host configuration files, e.g. set
services.<name>.enable = true;.
Files:
hosts/server/nixdev/woodpecker.nixhosts/server/nixio/default.nixhosts/server/nixdev/coder.nixhosts/server/nixarr/default.nixhosts/server/nixcloud/immich.nixhosts/server/nixcloud/search.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixdev/ci.nixhosts/server/nixio/proxy.nixhosts/server/nixcloud/identity.nixhosts/server/nixio/adguard.nixhosts/server/nixmon/default.nixhosts/server/nixcloud/homebox.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixdev/automation.nixhosts/server/nixio/dashboard.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixai/web.nixhosts/server/nixcloud/music.nixhosts/server/nixarr/arr/default.nixhosts/server/nixdev/default.nixhosts/server/nixio/storage.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixai/voice.nixhosts/server/nixdev/registry.nixhosts/server/nixio/database.nixhosts/server/nixai/ai-agent.nixhosts/server/nixserv/default.nix
hosts/*/*/default.nix
📄 CodeRabbit inference engine (.opencode/skills/hosts/SKILL.md)
Each host must have a
default.nixfile inhosts/<type>/<hostname>/as the main config entry pointPer-machine NixOS configurations should be placed in
hosts/<type>/<hostname>/default.nix
Files:
hosts/server/nixio/default.nixhosts/server/nixarr/default.nixhosts/server/nixmon/default.nixhosts/server/nixdev/default.nixhosts/server/nixserv/default.nix
hosts/server/*/default.nix
📄 CodeRabbit inference engine (.opencode/skills/hosts/SKILL.md)
Server hosts in
default.nixshould sethost.device.isHeadless = trueto indicate they are headless systems
Files:
hosts/server/nixio/default.nixhosts/server/nixarr/default.nixhosts/server/nixmon/default.nixhosts/server/nixdev/default.nixhosts/server/nixserv/default.nix
modules/nixos/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
Reusable NixOS module fragments should be placed in
modules/nixos/Create new NixOS modules under
modules/nixos/<category>/<name>.nix.
Files:
modules/nixos/server/storage/seaweedfs.nixmodules/nixos/server/default.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/stylix.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/core/sops.nixmodules/nixos/core/host/persistence.nixmodules/nixos/server/tests.nixmodules/nixos/core/nix.nixmodules/nixos/services/ai-agent.nix
modules/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/modules/SKILL.md)
modules/**/*.nix: Use the standard Nix module pattern: accept{ config, lib, pkgs, ... }, definecfgfromconfig, and structure the file withoptionsplus aconfig = mkIf cfg.enable { ... }section.
Use the documented module namespaces appropriately:services.<name>,hardware.<name>,boot.<name>,host.<name>,server.<name>,core.<name>,purpose.<category>, anduser.<name>.
When extending a submodule declared in another module, declare the sameoptions.<path>with the same outer wrapper (for example,attrsOf (submodule ...)) so the inneroptionsmerge additively.
Do not use dynamicimportsinside a submodule that read fromconfig; this causes infinite recursion. Use staticimportsonly when they do not depend onconfig.
When behavior should be conditional inside an imported submodule, wrap the submodule'sconfiginmkIf; do not try to conditionally gate the option declaration itself.
When extendingsubmoduleorsubmoduleWith, keep the outer type wrapper identical across declarations so the inneroptionsattrsets can merge.
Files:
modules/nixos/server/storage/seaweedfs.nixmodules/nixos/server/default.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/stylix.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/core/sops.nixmodules/nixos/core/host/persistence.nixmodules/nixos/server/tests.nixmodules/nixos/core/nix.nixmodules/nixos/services/ai-agent.nix
modules/nixos/**/default.nix
📄 CodeRabbit inference engine (.opencode/skills/modules/SKILL.md)
Register NixOS modules in the parent
default.nixvia animports = [ ... ];list.
Files:
modules/nixos/server/default.nix
flake/nixos/flake-module.nix
📄 CodeRabbit inference engine (.opencode/skills/hosts/SKILL.md)
For hosts requiring CUDA or ROCm acceleration support, add the host name to the corresponding array in
flake/nixos/flake-module.nixunderaccelerationHosts
Files:
flake/nixos/flake-module.nix
flake/nixos/**/*.nix
📄 CodeRabbit inference engine (.opencode/skills/project-structure/SKILL.md)
NixOS flake module definitions should be organized in
flake/nixos/
Files:
flake/nixos/flake-module.nix
🧠 Learnings (12)
📚 Learning: 2026-04-13T14:02:32.760Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 546
File: hosts/server/nixdev/default.nix:18-18
Timestamp: 2026-04-13T14:02:32.760Z
Learning: When configuring NixOS Docker via `virtualisation.docker.daemon.settings`, it is valid to set `storage-driver = "overlayfs"` (do not flag it as an invalid Docker storage-driver). Use `overlayfs` specifically for Docker Engine 29+ and/or when the containerd snapshotter integration is enabled (`virtualisation.docker.features.containerd-snapshotter = true`). Treat this as the containerd snapshotter name for OverlayFS, distinct from the legacy `overlay2` classic Docker storage driver.
Applied to files:
hosts/server/nixdev/woodpecker.nixhosts/server/nixio/default.nixtests/scenarios/proxy-routing/test.nixtests/lib.nixtests/scenarios/firewall-port-audit/test.nixhosts/server/nixdev/coder.nixhosts/server/nixarr/default.nixtests/scenarios/database-backup-chain/test.nixhosts/server/nixcloud/immich.nixhosts/server/nixcloud/search.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixdev/ci.nixhosts/server/nixio/proxy.nixhosts/server/nixcloud/identity.nixhosts/server/nixio/adguard.nixhosts/server/nixmon/default.nixhosts/server/nixcloud/homebox.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixdev/automation.nixhosts/server/nixio/dashboard.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixai/web.nixhosts/server/nixcloud/music.nixhosts/server/nixarr/arr/default.nixmodules/nixos/server/storage/seaweedfs.nixmodules/nixos/server/default.nixhosts/server/nixdev/default.nixhosts/server/nixio/storage.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixai/voice.nixhosts/server/nixdev/registry.nixmodules/nixos/core/boot/secureboot.nixflake/nixos/flake-module.nixtests/builder.nixhosts/server/nixio/database.nixtests/scenarios/redis-remote-connect/test.nixmodules/nixos/core/stylix.nixflake/default.nixhosts/server/nixai/ai-agent.nixtests/mkNode.nixhosts/server/nixserv/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixtests/profiles/vm-test.nixmodules/nixos/core/sops.nixmodules/nixos/core/host/persistence.nixmodules/nixos/server/tests.nixmodules/nixos/core/nix.nixmodules/nixos/services/ai-agent.nixtests/scenarios/io-guardian/test.nix
📚 Learning: 2026-05-01T10:02:55.261Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 544
File: modules/nixos/core/sops.nix:49-53
Timestamp: 2026-05-01T10:02:55.261Z
Learning: In this nix-config repo, when declaring `sops.secrets` in Nix files, avoid explicitly setting `owner = "root"` and/or `group = "root"` if the intended ownership is root. `sops-nix` defaults `sops.secrets` to `root:root`, so adding these fields explicitly is redundant boilerplate.
Applied to files:
hosts/server/nixdev/woodpecker.nixhosts/server/nixio/default.nixtests/scenarios/proxy-routing/test.nixtests/lib.nixtests/scenarios/firewall-port-audit/test.nixhosts/server/nixdev/coder.nixhosts/server/nixarr/default.nixtests/scenarios/database-backup-chain/test.nixhosts/server/nixcloud/immich.nixhosts/server/nixcloud/search.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixdev/ci.nixhosts/server/nixio/proxy.nixhosts/server/nixcloud/identity.nixhosts/server/nixio/adguard.nixhosts/server/nixmon/default.nixhosts/server/nixcloud/homebox.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixdev/automation.nixhosts/server/nixio/dashboard.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixai/web.nixhosts/server/nixcloud/music.nixhosts/server/nixarr/arr/default.nixmodules/nixos/server/storage/seaweedfs.nixmodules/nixos/server/default.nixhosts/server/nixdev/default.nixhosts/server/nixio/storage.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixai/voice.nixhosts/server/nixdev/registry.nixmodules/nixos/core/boot/secureboot.nixflake/nixos/flake-module.nixtests/builder.nixhosts/server/nixio/database.nixtests/scenarios/redis-remote-connect/test.nixmodules/nixos/core/stylix.nixflake/default.nixhosts/server/nixai/ai-agent.nixtests/mkNode.nixhosts/server/nixserv/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixtests/profiles/vm-test.nixmodules/nixos/core/sops.nixmodules/nixos/core/host/persistence.nixmodules/nixos/server/tests.nixmodules/nixos/core/nix.nixmodules/nixos/services/ai-agent.nixtests/scenarios/io-guardian/test.nix
📚 Learning: 2026-05-01T14:14:49.691Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 544
File: modules/nixos/core/gaming.nix:119-119
Timestamp: 2026-05-01T14:14:49.691Z
Learning: When configuring the NixOS `wivrn` module option `services.wivrn.config.json.application`, pass the raw package/derivation (e.g., `pkgs.wayvr`) rather than converting it to a string executable path (e.g., `lib.getExe pkgs.wayvr`). The upstream module expects a list of derivations/packages (it internally `toList`s the value, asserts the first element is a derivation, and then resolves the executable internally). Code review should not recommend changing `pkgs.wayvr` to `lib.getExe pkgs.wayvr` for this option.
Applied to files:
hosts/server/nixdev/woodpecker.nixhosts/server/nixio/default.nixtests/scenarios/proxy-routing/test.nixtests/lib.nixtests/scenarios/firewall-port-audit/test.nixhosts/server/nixdev/coder.nixhosts/server/nixarr/default.nixtests/scenarios/database-backup-chain/test.nixhosts/server/nixcloud/immich.nixhosts/server/nixcloud/search.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixdev/ci.nixhosts/server/nixio/proxy.nixhosts/server/nixcloud/identity.nixhosts/server/nixio/adguard.nixhosts/server/nixmon/default.nixhosts/server/nixcloud/homebox.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixdev/automation.nixhosts/server/nixio/dashboard.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixai/web.nixhosts/server/nixcloud/music.nixhosts/server/nixarr/arr/default.nixmodules/nixos/server/storage/seaweedfs.nixmodules/nixos/server/default.nixhosts/server/nixdev/default.nixhosts/server/nixio/storage.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixai/voice.nixhosts/server/nixdev/registry.nixmodules/nixos/core/boot/secureboot.nixflake/nixos/flake-module.nixtests/builder.nixhosts/server/nixio/database.nixtests/scenarios/redis-remote-connect/test.nixmodules/nixos/core/stylix.nixflake/default.nixhosts/server/nixai/ai-agent.nixtests/mkNode.nixhosts/server/nixserv/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixtests/profiles/vm-test.nixmodules/nixos/core/sops.nixmodules/nixos/core/host/persistence.nixmodules/nixos/server/tests.nixmodules/nixos/core/nix.nixmodules/nixos/services/ai-agent.nixtests/scenarios/io-guardian/test.nix
📚 Learning: 2026-05-20T13:12:46.610Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 546
File: docs/site.nix:127-127
Timestamp: 2026-05-20T13:12:46.610Z
Learning: In DaRacci/nix-config, treating `passthru.discovery = false` as a known repo-wide convention to exclude a derivation from automated flake discovery/package CI. Do not require or flag an inline explanatory comment specifically for the absence of a comment when `passthru.discovery = false` is set.
Applied to files:
hosts/server/nixdev/woodpecker.nixhosts/server/nixio/default.nixtests/scenarios/proxy-routing/test.nixtests/lib.nixtests/scenarios/firewall-port-audit/test.nixhosts/server/nixdev/coder.nixhosts/server/nixarr/default.nixtests/scenarios/database-backup-chain/test.nixhosts/server/nixcloud/immich.nixhosts/server/nixcloud/search.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixdev/ci.nixhosts/server/nixio/proxy.nixhosts/server/nixcloud/identity.nixhosts/server/nixio/adguard.nixhosts/server/nixmon/default.nixhosts/server/nixcloud/homebox.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixdev/automation.nixhosts/server/nixio/dashboard.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixai/web.nixhosts/server/nixcloud/music.nixhosts/server/nixarr/arr/default.nixmodules/nixos/server/storage/seaweedfs.nixmodules/nixos/server/default.nixhosts/server/nixdev/default.nixhosts/server/nixio/storage.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixai/voice.nixhosts/server/nixdev/registry.nixmodules/nixos/core/boot/secureboot.nixflake/nixos/flake-module.nixtests/builder.nixhosts/server/nixio/database.nixtests/scenarios/redis-remote-connect/test.nixmodules/nixos/core/stylix.nixflake/default.nixhosts/server/nixai/ai-agent.nixtests/mkNode.nixhosts/server/nixserv/default.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixtests/profiles/vm-test.nixmodules/nixos/core/sops.nixmodules/nixos/core/host/persistence.nixmodules/nixos/server/tests.nixmodules/nixos/core/nix.nixmodules/nixos/services/ai-agent.nixtests/scenarios/io-guardian/test.nix
📚 Learning: 2026-06-28T05:00:06.970Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 599
File: hosts/server/nixai/mnemosyne.nix:6-11
Timestamp: 2026-06-28T05:00:06.970Z
Learning: In this repo’s Nix host configuration, for `sops.secrets.<name>` declarations managed by `sops-nix`, avoid explicitly setting `mode = "0400"` when you are not overriding `sops-nix`’s default secret permissions. `sops-nix` already defaults decrypted secret files to root ownership with mode `0400`, so an explicit `mode = "0400"` is typically redundant. Only set `mode` when you truly need non-default permissions (or you have config that changes the module defaults).
Applied to files:
hosts/server/nixdev/woodpecker.nixhosts/server/nixio/default.nixhosts/server/nixdev/coder.nixhosts/server/nixarr/default.nixhosts/server/nixcloud/immich.nixhosts/server/nixcloud/search.nixhosts/server/nixcloud/home-assistant/default.nixhosts/server/nixdev/ci.nixhosts/server/nixio/proxy.nixhosts/server/nixcloud/identity.nixhosts/server/nixio/adguard.nixhosts/server/nixmon/default.nixhosts/server/nixcloud/homebox.nixhosts/server/nixarr/arr/downloader.nixhosts/server/nixdev/automation.nixhosts/server/nixio/dashboard.nixhosts/server/nixcloud/home-assistant/connectivity.nixhosts/server/nixai/web.nixhosts/server/nixcloud/music.nixhosts/server/nixarr/arr/default.nixhosts/server/nixdev/default.nixhosts/server/nixio/storage.nixhosts/server/nixcloud/nextcloud.nixhosts/server/nixai/voice.nixhosts/server/nixdev/registry.nixhosts/server/nixio/database.nixhosts/server/nixai/ai-agent.nixhosts/server/nixserv/default.nix
📚 Learning: 2026-05-01T09:11:22.009Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 544
File: modules/nixos/core/gaming.nix:65-65
Timestamp: 2026-05-01T09:11:22.009Z
Learning: In Nix code, do not flag shell-variable literals like "$XDG_RUNTIME_DIR" used inside Steam’s `extraEnv` (e.g., `pkgs.steam.override { extraEnv = { ... }; }`, including `modules/nixos/core/gaming.nix`). The Steam wrapper script expands these shell variables at runtime, so they should be treated as intended unexpanded literals rather than an interpolation/quoting mistake.
Applied to files:
modules/nixos/server/storage/seaweedfs.nixmodules/nixos/server/default.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/stylix.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/core/sops.nixmodules/nixos/core/host/persistence.nixmodules/nixos/server/tests.nixmodules/nixos/core/nix.nixmodules/nixos/services/ai-agent.nix
📚 Learning: 2026-05-01T14:35:32.037Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 544
File: modules/nixos/core/remote.nix:153-179
Timestamp: 2026-05-01T14:35:32.037Z
Learning: In this repo’s NixOS module code (e.g., shell scripts produced via `writeShellApplication` inside `modules/nixos/**`), do not treat missing `XDG_STATE_HOME` fallbacks (like `${XDG_STATE_HOME:-$HOME/.local/state}`) as an error in the embedded shell script. On NixOS user sessions, `XDG_STATE_HOME` is reliably set via PAM/systemd, so flagging its absence as potentially unset is overly defensive for these generated scripts.
Applied to files:
modules/nixos/server/storage/seaweedfs.nixmodules/nixos/server/default.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/stylix.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/core/sops.nixmodules/nixos/core/host/persistence.nixmodules/nixos/server/tests.nixmodules/nixos/core/nix.nixmodules/nixos/services/ai-agent.nix
📚 Learning: 2026-06-20T14:33:25.328Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 590
File: modules/nixos/server/monitoring/collector/tempo.nix:71-72
Timestamp: 2026-06-20T14:33:25.328Z
Learning: When reviewing DaRacci/nix-config NixOS modules that use sops-nix, do not flag `sops.secrets` entries as missing `owner`, `group`, `mode`, or `restartUnits` if the secret declarations are only placeholder sources for `sops.templates`:
- The secret value is referenced exclusively via `config.sops.placeholder.<NAME>` inside a `sops.templates` definition (i.e., no other code reads the decrypted secret from the raw secret path).
- The rendered `sops.templates` output is what is used by systemd via a `systemd.services.*.serviceConfig.EnvironmentFile` (the template is the effective boundary).
In this pattern, the template’s own `restartUnits` are the relevant access-control/restart boundary; the raw `sops.secrets` files are only decrypted in-memory by sops-nix (run as root) to render the template. Therefore, empty-attrset `sops.secrets.<NAME> = { };` declarations should not be treated as missing permissions/restart hooks when they are only feeding a `sops.templates` placeholder.
Applied to files:
modules/nixos/server/storage/seaweedfs.nixmodules/nixos/server/default.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/stylix.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/core/sops.nixmodules/nixos/core/host/persistence.nixmodules/nixos/server/tests.nixmodules/nixos/core/nix.nixmodules/nixos/services/ai-agent.nix
📚 Learning: 2026-05-01T09:57:09.578Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 544
File: modules/nixos/services/ai-agent.nix:15-15
Timestamp: 2026-05-01T09:57:09.578Z
Learning: In this repo’s Nix modules, `inputs.services-zeroclaw` is a flake input that resolves to an attrset containing a `_file` attribute, and Nix coerces that attrset to a file path via `_file`. When importing/using it as a path in `imports` (e.g., `modules/nixos/services/ai-agent.nix`), use the string interpolation form "${inputs.services-zeroclaw}". Do not change it to `inputs.services-zeroclaw` (raw attrset form) in `imports`, because it will not work correctly.
Applied to files:
modules/nixos/server/storage/seaweedfs.nixmodules/nixos/server/default.nixmodules/nixos/core/boot/secureboot.nixmodules/nixos/core/stylix.nixmodules/nixos/server/proxy/extensions/api-key-auth.nixmodules/nixos/core/sops.nixmodules/nixos/core/host/persistence.nixmodules/nixos/server/tests.nixmodules/nixos/core/nix.nixmodules/nixos/services/ai-agent.nix
📚 Learning: 2026-05-02T15:02:17.285Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 542
File: modules/nixos/server/storage/seaweedfs.nix:362-366
Timestamp: 2026-05-02T15:02:17.285Z
Learning: When reviewing SeaweedFS configuration in Nix files, treat SeaweedFS CLI address flags like `-master`, `-admin`, etc. as valid when they use SeaweedFS’s documented address syntax `<host>:<httpPort>.<grpcPort>`. For example, `-admin=admin.seaweedfs.racci.dev:443.10443` means HTTP port `443` and gRPC port `10443`. Do not mark these as malformed addresses. Only flag the value if it does not match the `<host>:<number>.<number>` shape (e.g., missing the dot separator or non-numeric ports).
Applied to files:
modules/nixos/server/storage/seaweedfs.nix
📚 Learning: 2026-05-02T15:02:17.285Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 542
File: modules/nixos/server/storage/seaweedfs.nix:362-366
Timestamp: 2026-05-02T15:02:17.285Z
Learning: In SeaweedFS Nix/CLI configuration, address arguments for flags like `-master` and `-admin` use SeaweedFS’s documented format `<host>:<httpPort>.<grpcPort>`. This is valid and should not be treated as a malformed address. For example, `-admin=admin.seaweedfs.racci.dev:443.10443` sets HTTP port `443` and gRPC port `10443` in a single argument—so reviews should not flag the `:<httpPort>.<grpcPort>` segment as invalid syntax.
Applied to files:
modules/nixos/server/storage/seaweedfs.nix
📚 Learning: 2026-03-18T23:46:49.905Z
Learnt from: DaRacci
Repo: DaRacci/nix-config PR: 546
File: .woodpecker/lix.yaml:15-15
Timestamp: 2026-03-18T23:46:49.905Z
Learning: In nix-config repository (.woodpecker/*.yaml), image references intentionally omit explicit tags or digests (e.g., registry.racci.dev/lix-woodpecker without :tag). Do not flag or suggest adding explicit tags or digests to these image references; treat such omissions as intentional and maintain consistency across the CI config.
Applied to files:
.woodpecker/test-vm.yaml
🪛 ast-grep (0.44.0)
run-test.sh
[warning] 2-2: Writing to or reading from a hardcoded, predictable path under /tmp is vulnerable to symlink and TOCTOU attacks: a local attacker can pre-create the file (or a symlink pointing elsewhere) and hijack or corrupt the contents. Generate a unique, unpredictable temporary file with mktemp instead, e.g. tmpfile="$(mktemp)" (or mktemp -d for directories) and reference "$tmpfile".
Context: /tmp/test-result.log
Note: [CWE-377] Insecure Temporary File.
(predictable-tmp-file-bash)
[warning] 4-4: Writing to or reading from a hardcoded, predictable path under /tmp is vulnerable to symlink and TOCTOU attacks: a local attacker can pre-create the file (or a symlink pointing elsewhere) and hijack or corrupt the contents. Generate a unique, unpredictable temporary file with mktemp instead, e.g. tmpfile="$(mktemp)" (or mktemp -d for directories) and reference "$tmpfile".
Context: /tmp/test-result.log
Note: [CWE-377] Insecure Temporary File.
(predictable-tmp-file-bash)
🪛 LanguageTool
docs/src/development/vm_integration_tests.md
[uncategorized] ~207-~207: Loose punctuation mark.
Context: ...run. ### Requirements - /dev/kvm: QEMU tests require KVM acceleration. Wi...
(UNLIKELY_OPENING_PUNCTUATION)
🪛 markdownlint-cli2 (0.22.1)
docs/src/development/vm_integration_tests.md
[warning] 13-13: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
[warning] 233-233: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
| # PR-only, KVM. | ||
| # Build nixosTestConfigurations.* for all server hosts. | ||
| # TODO: affected-host build (PR-changed only). | ||
| # | ||
| # Independent of check.yaml. |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🔵 Trivial
TODO acknowledges full-host builds; currently every PR builds all server + scenario hosts.
Per the flake/nixos/flake-module.nix snippet, nixosTestConfigurations enumerates every server host plus every scenario directory, so this pipeline will grow linearly (VM builds are expensive) as hosts/scenarios are added. Want help sketching an affected-host filter (e.g., diffing hosts/server/** against the PR's changed files) to close the TODO?
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.woodpecker/test-vm.yaml around lines 1 - 5, The PR-only KVM job currently
builds every server and scenario host via nixosTestConfigurations, which does
not scale as the repo grows. Update the test-vm pipeline to run only affected
hosts by filtering against the PR’s changed files (for example, comparing
changes under hosts/server/** and scenario directories) before expanding the
build set. Keep the logic anchored around the test-vm job and the
nixosTestConfigurations consumer so the affected-host selection happens before
VM builds are scheduled.
| for host in $(nix eval .#nixosTestConfigurations --apply 'builtins.attrNames' --json | jq -r '.[]'); do | ||
| echo "::group::VM test: $host" | ||
| nix build ".#nixosTestConfigurations.$host" --no-link -L || echo "FAILED: $host" | ||
| echo "::endgroup::" | ||
| done |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🔵 Trivial
Sequential per-host loop won't scale as hosts/scenarios grow.
All builds run serially in a single shell loop on one agent, so total CI time grows linearly with the host count. Native Woodpecker matrix builds require statically-known values at parse time, which doesn't fit the dynamically discovered host list here (nix eval .#nixosTestConfigurations), so this isn't a drop-in fix — but worth considering a generated/dynamic pipeline step or splitting into parallel agent runs if VM build times become a bottleneck.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.woodpecker/test-vm.yaml around lines 28 - 32, The VM test loop in the test
step runs each host serially, so it will become a CI bottleneck as the host list
grows. Update the logic around the host iteration in the test script to use a
parallelized or dynamically generated execution strategy instead of a single
shell loop in one agent, while keeping the current `nix eval
.#nixosTestConfigurations` host discovery and `nix build` per-host behavior
intact.
🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win
Per-host build failures are swallowed — the step always reports success.
Woodpecker runs step commands as a single /bin/sh -e script, and a step's overall exit status is what determines pipeline pass/fail. Here, nix build ... || echo "FAILED: $host" suppresses the non-zero exit from -e, and the loop's last command (echo "::endgroup::") always returns 0. Consequently, this "Run VM tests" step will report success even if every host build fails, defeating the purpose of gating PRs on VM test results.
🐛 Proposed fix to propagate failures
- name: Run VM tests
image: registry.racci.dev/lix-woodpecker:latest
commands: |
+ status=0
for host in $(nix eval .#nixosTestConfigurations --apply 'builtins.attrNames' --json | jq -r '.[]'); do
echo "::group::VM test: $host"
- nix build ".#nixosTestConfigurations.$host" --no-link -L || echo "FAILED: $host"
+ if ! nix build ".#nixosTestConfigurations.$host" --no-link -L; then
+ echo "FAILED: $host"
+ status=1
+ fi
echo "::endgroup::"
done
+ exit $status📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| for host in $(nix eval .#nixosTestConfigurations --apply 'builtins.attrNames' --json | jq -r '.[]'); do | |
| echo "::group::VM test: $host" | |
| nix build ".#nixosTestConfigurations.$host" --no-link -L || echo "FAILED: $host" | |
| echo "::endgroup::" | |
| done | |
| status=0 | |
| for host in $(nix eval .#nixosTestConfigurations --apply 'builtins.attrNames' --json | jq -r '.[]'); do | |
| echo "::group::VM test: $host" | |
| if ! nix build ".#nixosTestConfigurations.$host" --no-link -L; then | |
| echo "FAILED: $host" | |
| status=1 | |
| fi | |
| echo "::endgroup::" | |
| done | |
| exit $status |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.woodpecker/test-vm.yaml around lines 28 - 32, The “Run VM tests” loop is
swallowing failures because the `nix build` error is followed by a successful
`echo`, so the shell step always exits 0. Update the VM test commands in
`.woodpecker/test-vm.yaml` to let `nix build` failures propagate from the loop
instead of masking them, and ensure the step exits non-zero when any host build
fails. Use the existing `nix build ".#nixosTestConfigurations.$host"` loop and
the `echo "::group::VM test: $host"` / `echo "::endgroup::"` structure as the
location to fix this behavior.
| baselineAssertions = nodeName: '' | ||
| ${nodeName}.wait_for_unit("multi-user.target") | ||
| ${nodeName}.wait_for_unit("sshd.service") | ||
| ${nodeName}.succeed("journalctl --no-pager -n 1") | ||
| out = ${nodeName}.succeed("systemctl list-units --state=failed --no-legend --no-pager") | ||
| assert out.strip() == "", f"Failed units found on ${nodeName}: {out}" | ||
| ''; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win
Nested multi-line string interpolation will desync Python indentation inside with subtest(): blocks.
baselineAssertions (and unit.testScript at line 78) are multi-line Nix strings interpolated directly under a with subtest(...): line (e.g. lines 72‑73, 76‑78, 107‑109). Nix indented-string dedenting is computed from the literal source text before substitution — only the first line of the interpolated value inherits the surrounding indentation; every subsequent line keeps whatever (shallower) indentation was baked into the interpolated string itself. The generated Python will end up with the first assertion indented under with, but the remaining wait_for_unit/succeed/assert lines flush left — this is either an IndentationError or, worse, statements silently running outside the with subtest() scope.
This affects both the host branch (lines 69‑80) and the scenario branch (lines 102‑114), plus any multi-line unit.testScript.
🐛 Suggested fix — make each helper a self-contained block
- baselineAssertions = nodeName: ''
- ${nodeName}.wait_for_unit("multi-user.target")
- ${nodeName}.wait_for_unit("sshd.service")
- ${nodeName}.succeed("journalctl --no-pager -n 1")
- out = ${nodeName}.succeed("systemctl list-units --state=failed --no-legend --no-pager")
- assert out.strip() == "", f"Failed units found on ${nodeName}: {out}"
- '';
+ baselineAssertions = nodeName: ''
+ with subtest("${nodeName} baseline"):
+ ${nodeName}.wait_for_unit("multi-user.target")
+ ${nodeName}.wait_for_unit("sshd.service")
+ ${nodeName}.succeed("journalctl --no-pager -n 1")
+ out = ${nodeName}.succeed("systemctl list-units --state=failed --no-legend --no-pager")
+ assert out.strip() == "", f"Failed units found on ${nodeName}: {out}"
+ '';Then call it flush-left without an outer with subtest(): wrapper:
- with subtest("${hostName} baseline"):
- ${baselineAssertions hostName}
+ ${baselineAssertions hostName}Apply the same pattern to the scenario branch and to how unit.testScript is wrapped.
Also applies to: 69-114
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/builder.nix` around lines 34 - 40, The multi-line Nix strings used by
baselineAssertions and unit.testScript are being interpolated directly inside
with subtest() blocks, which can break Python indentation after the first line.
Move these helpers so each one is a self-contained Python block with its own
indentation, then invoke them flush-left from the host and scenario branches
instead of wrapping the interpolated text inside with subtest():. Apply the same
pattern anywhere unit.testScript is embedded so all assertions stay inside the
intended scope.
| inherit (config.partitions.nixos.module) allocations; | ||
|
|
||
| # Build per-system pkgs — need a pkgs instance for the builder | ||
| pkgs = lib.builders.mkPkgs { system = "x86_64-linux"; }; |
There was a problem hiding this comment.
This shouldnt hard code the architecture.
| server.tests.units = { | ||
| prometheus = { | ||
| testScript = '' | ||
| nixmon.succeed("systemctl show prometheus.service | grep -i loadstate") | ||
| ''; | ||
| }; | ||
|
|
||
| loki = { | ||
| testScript = '' | ||
| nixmon.succeed("systemctl show loki.service | grep -i loadstate") | ||
| ''; | ||
| }; | ||
|
|
||
| grafana = { | ||
| testScript = '' | ||
| nixmon.succeed("systemctl show grafana.service | grep -i loadstate") | ||
| ''; | ||
| }; | ||
|
|
||
| alertmanager = { | ||
| testScript = '' | ||
| nixmon.succeed("systemctl show alertmanager.service | grep -i loadstate") | ||
| ''; | ||
| }; | ||
|
|
||
| uptime-kuma = { | ||
| testScript = '' | ||
| nixmon.succeed("systemctl show uptime-kuma.service | grep -i loadstate") | ||
| ''; | ||
| }; | ||
|
|
||
| node-exporter = { | ||
| testScript = '' | ||
| nixmon.succeed("systemctl show node_exporter.service | grep -i loadstate") | ||
| ''; | ||
| }; | ||
|
|
||
| alloy = { | ||
| testScript = '' | ||
| nixmon.succeed("systemctl show alloy.service | grep -i loadstate") | ||
| ''; | ||
| }; | ||
| }; | ||
|
|
There was a problem hiding this comment.
Useless test, needs replacing with real tests.
|
|
||
| server.tests.units = { | ||
| minio = { | ||
| testScript = '' | ||
| nixio.succeed("systemctl show minio.service | grep -i loadstate") | ||
| ''; | ||
| }; | ||
|
|
||
| seaweedfs-master = { | ||
| testScript = '' | ||
| nixio.succeed("systemctl show seaweedfs-master.service | grep -i loadstate") | ||
| ''; | ||
| }; | ||
|
|
||
| seaweedfs-volume = { | ||
| testScript = '' | ||
| nixio.succeed("systemctl show seaweedfs-volume.service | grep -i loadstate") | ||
| ''; | ||
| }; | ||
|
|
||
| seaweedfs-filer = { | ||
| testScript = '' | ||
| nixio.succeed("systemctl show seaweedfs-filer.service | grep -i loadstate") | ||
| ''; | ||
| }; | ||
| }; |
There was a problem hiding this comment.
Useless test, needs replacing with real tests.
| )) | ||
| (builtins.mapAttrs ( | ||
| _: value: | ||
| (removeAttrs value [ "sopsFileHash" ]) |
There was a problem hiding this comment.
Why was this a required change ?
| { | ||
| options = { | ||
| server.tests = { | ||
| enable = mkEnableOption "Enable testing of this machine in the cluster tests"; |
There was a problem hiding this comment.
| enable = mkEnableOption "Enable testing of this machine in the cluster tests"; | |
| enable = mkEnableOption "testing of this machine in the cluster tests"; |
Would read "Weather to enable Enable testing..." otherwise.
| name = mkOption { | ||
| type = str; | ||
| default = name; | ||
| description = '' | ||
| The name to give to this unit test. | ||
| This is used to enter into a subtest within the testScript of the cluster test. | ||
| ''; | ||
| }; |
There was a problem hiding this comment.
This should be a internal readOnly field.
Based off #544