test(modules): Check eval is identical to nixpkgs

We want these modules to be importable by people, as a set, even if they
don't want to use all of the options or import all of the dependencies

This test makes sure of 2 things
- Our modules can be evaluated on the default configuration with only
  stuff that is permitted in our README
- Without some configuration, our modules do not change the outputted
  system toplevel

This can be used as a rough proxy for being "safe to import", as
hopefully these modules won't introduce any changes to your config from
only an import

Change-Id: Ied99c3460a76f205de1724db2c531723cc3506b5
Reviewed-on: https://git.clicks.codes/c/Infra/NixFiles/+/812
Reviewed-by: Skyler Grey <minion@clicks.codes>
Tested-by: Skyler Grey <minion@clicks.codes>
diff --git a/flake.nix b/flake.nix
index 5500287..1215be6 100644
--- a/flake.nix
+++ b/flake.nix
@@ -100,7 +100,7 @@
           importedSpecs = lib.forEach specFiles (file: {
             name = builtins.unsafeDiscardStringContext (builtins.baseNameOf file);
             value = import file {
-              inherit channels lib;
+              inherit channels lib inputs;
             };
           });
         in builtins.listToAttrs importedSpecs;
diff --git a/lib/checks/default.nix b/lib/checks/default.nix
index 0340be1..9a21b20 100644
--- a/lib/checks/default.nix
+++ b/lib/checks/default.nix
@@ -29,6 +29,7 @@
           --eval-store $HOME \
           --flake \
           --option extra-experimental-features flakes \
+          --show-trace \
           ${inputPathArgs} \
           .#specs.${pkgs.system}
         touch $out
diff --git a/modules.spec.nix b/modules.spec.nix
new file mode 100644
index 0000000..3360af9
--- /dev/null
+++ b/modules.spec.nix
@@ -0,0 +1,47 @@
+{ inputs, lib, channels, ... }:
+
+# Clicks modules must fulfil a contract consisting of 2 items:
+# - They must evaluate when running with only the NixOS modules and other Clicks
+#   modules
+# - They must not change config without being enabled
+#
+# We can pretty eloquently test for both of these by evaluating our modules with
+# just the nixpkgs modules, and then doing the same thing without our modules
+{
+  testEmptyEvalMayNotChangeOutput = let
+    neededForEval = [
+      {
+        system.stateVersion = "24.05";
+      }
+      {
+        fileSystems."/" = {
+          device = "none";
+          fsType = "tmpfs";
+        };
+      }
+      {
+        boot.loader.grub.device = "nodev";
+      }
+      {
+        nixpkgs.config = {
+          allowBroken = true;
+          allowUnfree = true;
+        };
+      }
+    ];
+    libPlusClicks = lib.attrsets.recursiveUpdate channels.unstable.lib {
+      clicks = lib.clicks; # Our own lib is permitted as a requirement... but we're doing this song/dance to stop us, say, relying on snowfall lib/agenix lix/whatever...
+    };
+  in {
+    expr = (inputs.unstable.lib.nixosSystem {
+      lib = libPlusClicks;
+      system = channels.unstable.system;
+      modules = (lib.attrsets.attrValues inputs.self.nixosModules) ++ neededForEval;
+    }).config.system.build.toplevel.outPath;
+    expected = (inputs.unstable.lib.nixosSystem {
+      lib = libPlusClicks;
+      system = channels.unstable.system;
+      modules = neededForEval;
+    }).config.system.build.toplevel.outPath;
+  };
+}