greenhouse

kore

my public infrastructure monorepo

git clone [email protected]:kore.git

feat(*): rewrite

commitf2ddb36d0858028d82a84d28c7e2761974cd0dc1
parent1c0bc2c7465145d9d9f5c37d85b973bccf7fd779
authorlostduk <[email protected]>
date2026-10-14 06:43 +0000
flake.nix10++-
home/features/cli/git.nix12++--
home/features/cli/gpg.nix11+++-
home/features/global.nix20+++---
home/features/misc/vesktop.nix13----
home/features/secrets.nix1+
home/features/wayland/dwl.nix5--
home/features/wayland/foot.nix11----
home/profiles/gomphrena.nix7+--
home/profiles/sunflower.nix16-----
keys/identities/lostduk/gpg.asc23+++++++
keys/identities/lostduk/ssh/yubikey.pub1+
kore.json15+++--
nixos/features/global.nix99++++++++++++++++++------------
nixos/features/kore.nix87+++++++++++++++++++++++---
nixos/hosts/default.nix10+--
nixos/hosts/gomphrena.nix25+-------
nixos/hosts/sunflower.nix88---------------------------
nixos/roles/default.nix6--
nixos/roles/desktop.nix135+++++++++++-----------------------------
nixos/roles/home.nix33++++------
overlays/default.nix17++----
overlays/dwl_config.h118-----------------------------------

23 files changed, -493/+270

flake.nix

@@ -14,14 +14,16 @@     home-manager.inputs.nixpkgs.follows = "nixpkgs";   }; -  outputs = inputs@{ self, nixpkgs, home-manager, ... }:+  outputs = inputs@{ self, nixpkgs, ... }:     let       inherit (self) outputs;-      lib = nixpkgs.lib // home-manager.lib;-      kore = builtins.fromJSON (builtins.readFile ./kore.json);+      inherit (nixpkgs) lib;+      kore = lib.importJSON ./kore.json;     in {+      inherit kore;+       nixosConfigurations = import ./nixos/hosts { inherit inputs outputs lib kore; };-      homeConfigurations = import ./home/profiles { inherit kore; };+      homeModules = import ./home/profiles { inherit kore; };        overlays = import ./overlays { inherit inputs outputs; };     };

home/features/cli/git.nix

@@ -1,6 +1,8 @@-{ config, ... }:+{ config, osConfig, ... }: -{+let+  identity = osConfig.kore.identities.${config.home.username};+in {   programs.git = {     enable = true; @@ -12,10 +14,10 @@      settings = {       user = {-        name = "lostduk";-        email = "[email protected]";+        name = config.home.username;+        email = identity.email; -        signing.key = "0x024E39A2037D1BBC";+        signing.key = identity.gpg;       };        alias = {

home/features/cli/gpg.nix

@@ -1,6 +1,8 @@-{ pkgs, config, lib, ... }:+{ pkgs, config, osConfig, lib, ... }: -{+let+  identity = osConfig.kore.identities.${config.home.username};+in {   services.gpg-agent = {     enable = true;     enableSshSupport = true;@@ -13,6 +15,11 @@       enable = true;       settings.trust-model = "tofu+pgp";       scdaemonSettings.disable-ccid = true;++      publicKeys = lib.optional (identity.gpgKey != null) {+        source = identity.gpgKey;+        trust = "ultimate";+      };     };      bash.initExtra = ''

home/features/global.nix

@@ -1,10 +1,8 @@-{ config, pkgs, ... }:+{ osConfig, pkgs, ... }:  {   home = {-    username = "lostduk";-    homeDirectory = "/home/lostduk";-    stateVersion = "26.11";+    stateVersion = osConfig.system.stateVersion;      sessionVariables = {       # Fuck Google@@ -16,10 +14,14 @@      packages = with pkgs; [ pass ]; -    persistence."/persist".directories = [-      "documents"-      ".mozilla"-      ".password-store"-    ];+    persistence."/persist" = {+      enable = osConfig.kore.impermanence.enable;++      directories = [+        "documents"+        ".mozilla"+        ".password-store"+      ];+    };   }; }

home/features/misc/vesktop.nix

@@ -1,13 +0,0 @@-{-  programs.vesktop = {-    enable = true;-    settings = {-      tray = false;-      minimizeToTray = false;-      hardwareAcceleration = false; # enable this makee vesktop crash-      discordBranch = "stable";-    };-  };--  home.persistence."/persist".directories = [ ".config/vesktop" ];-}

home/features/secrets.nix

@@ -0,0 +1 @@+throw "home/features/secrets.nix is a placeholder: restore your local copy, then run `git update-index --skip-worktree home/features/secrets.nix`"

home/features/wayland/dwl.nix

@@ -1,5 +0,0 @@-{ pkgs, ... }:--{-  home.packages = with pkgs; [ dwl dmenu wl-clipboard xdg-utils ];-}

home/features/wayland/foot.nix

@@ -1,11 +0,0 @@-{-  programs.foot = {-    enable = true;-    settings = {-      main = {-        font = "ComicShannsMono Nerd Font:size=11";-        line-height = "16px";-      };-    };-  };-}

home/profiles/gomphrena.nix

@@ -1,5 +1,3 @@-{ lib, ... }:- {   imports = [     ../features/cli/gpg.nix@@ -10,6 +8,8 @@     ../features/cli/tmux.nix      ../features/misc/xdg.nix++    ../features/secrets.nix   ];    # TMP: neovim suck tbh but it work@@ -27,6 +27,5 @@       \   'cache_enabled': 0,       \ }   '';--  home.persistence."/persist" = lib.mkForce {}; }+

home/profiles/sunflower.nix

@@ -1,16 +0,0 @@-{-  imports = [-    ../features/cli/gpg.nix-    ../features/cli/ssh.nix-    ../features/cli/git.nix-    ../features/cli/nvim.nix-    ../features/cli/bash.nix-    ../features/cli/tmux.nix--    ../features/misc/xdg.nix-    ../features/misc/vesktop.nix--    ../features/wayland/dwl.nix-    ../features/wayland/foot.nix-  ];-}

keys/identities/lostduk/gpg.asc

@@ -0,0 +1,23 @@+-----BEGIN PGP PUBLIC KEY BLOCK-----++mDMEaQXtYhYJKwYBBAHaRw8BAQdAYM4m2ZnQgEPxeoo4mBdQSCPZrEGHhRvOGmyI+SHHEJ3m0GGxvc3RkdWsgPGhpQGxvc3RkdWsuY29tPoiOBBMWCgA2FiEEOSHgaXiu+IXxDmgqyajzSqNI0a7EFAmkF7WICGwEECwkIBwQVCgkIBRYCAwEAAh4BAheAAAoJ+EGo80qjSNGuxEckBAM3Rbc1K0hDAZur0VOicyGc0DRVNhkRB9qeS7yq4Uio4AQDU+ad2WmaD8/0PYxD9rTz8FjiDuWguCgXhJ0ez/fPM/DLgzBGkF7bAWCSsGAQQB2kcP+AQEHQEJiBNDGSFxFhX/tyhRb6QdE+ArFQJCxDmVNMnh0w95HiPUEGBYKACYWIQQ5+IeBpeK4hfEOaCrJqPNKo0jRrsQUCaQXtsAIbAgUJA8JnAACBCRBqPNKo0jRrsXYg+BBkWCgAdFiEEXIvReTw6va1WZPA8Ak45ogN9G7wFAmkF7bAACgkQAk45ogN9G7yz+BAEA4rzePNygbo+Vmw7ObcdpJVpazNbb76dK4CWaD5LcobkBAKIQhJHpi0yVN2yD+oZL/y+36iVD5wAnBqAE1vMtw6FQATEUA/AueSjR049QyKYi+9Zlv1QiEeoWU57vo+29gawYOuvKE1APwNYqPFyLNhgOqw1ffz/TEfXbRksHu6hqxFmYj7rAHeDrg4BGkF+7bcSCisGAQQBl1UBBQEBB0AcOz7tSfHZf8AbcSpbvIc5m99nkq0F8BNMHlIbXFo6+BwMBCAeIfgQYFgoAJhYhBDkh4Gl4riF8Q5oKsmo80qjSNGuxBQJpBe23AhsMBQkD+wmcAAAoJEGo80qjSNGuxKKwA/3BQqmKR1p4sVc93FZcZ2oWPqLscvQVcF7ld0/QT+Qn2cAP40lfFfhJxZ2cw5+wASKU6KH9DRj72tSCUp0WYvfHvyCbgzBGkF7boWCSsG+AQQB2kcPAQEHQLV3m86O9Q5qSydDW2uWqOF8kPcVMNEqJiA1xBOKETdGiH4EGBYK+ACYWIQQ5IeBpeK4hfEOaCrJqPNKo0jRrsQUCaQXtugIbIAUJA8JnAAAKCRBqPNKo+0jRrseGMAP0e9WtDu0Xx9VsPpx6fZ6z66AZEJQ9N4K29enlwTvVHuQEA1F2tqi1R+Isl2fJCqNyJ3msAfyfXGnnbfTNL0KCFsawY=+=RoxB+-----END PGP PUBLIC KEY BLOCK-----

keys/identities/lostduk/ssh/yubikey.pub

@@ -0,0 +1 @@+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILV3m86O9Q5qSydDW2uWqOF8kPcVMNEqJiA1xBOKETdG cardno:26_584_764

kore.json

@@ -1,14 +1,17 @@ {+  "identities": {+    "lostduk": {+      "email": "[email protected]",+      "gpg": "0x024E39A2037D1BBC"+    }+  },   "hosts": {-    "sunflower": {-      "system": "x86_64-linux",-      "roles": ["home", "desktop"],-      "ipv4": "0.0.0.0"-    },     "gomphrena": {       "system": "x86_64-linux",+      "stateVersion": "26.11",       "roles": ["home"],-      "ipv4": "0.0.0.0"+      "users": ["lostduk"],+      "ipv4": null     }   } }

nixos/features/global.nix

@@ -1,6 +1,14 @@-{ inputs, outputs, config, lib, pkgs, ... }:+{ inputs, outputs, config, lib, pkgs, utils, ... }: -{+# Policy for every host. Values under mkForce are invariants: roles and+# hosts must not weaken them.+let+  impermanence = config.kore.impermanence.enable;+  rollback = impermanence && config ? disko && config.disko.devices.disk ? main;++  rootDevice = config.fileSystems."/".device;+  rootUnit = "${utils.escapeSystemdPath rootDevice}.device";+in {   imports = [ inputs.impermanence.nixosModules.impermanence ];    i18n = {@@ -76,7 +84,7 @@         KbdInteractiveAuthentication = false;       };       hostKeys = [{-        path = "/persist/etc/ssh/ssh_host_ed25519_key";+        path = "${lib.optionalString impermanence "/persist"}/etc/ssh/ssh_host_ed25519_key";         type = "ed25519";       }];     };@@ -109,6 +117,7 @@     defaultPackages = lib.mkForce [];      persistence."/persist" = {+      enable = impermanence;       hideMounts = false;        directories = [@@ -121,49 +130,63 @@    programs.nano.enable = false; -  boot.initrd = let-    rootDevice = config.fileSystems."/".device;-    systemdStage1 = config.boot.initrd.systemd.enable;--    script = ''-      mkdir -p /tmp-      MNTPOINT=$(mktemp -d)-      (-        mount ${rootDevice} "$MNTPOINT"-        trap 'umount "$MNTPOINT"' EXIT--        if [[ -e $MNTPOINT/@ ]]; then-          echo "Backing up root..."-          mkdir -p $MNTPOINT/old_roots-          mv "$MNTPOINT/@" "$MNTPOINT/old_roots/@_$(date "+%Y-%m-%-d_%H:%M:%S")"-        fi--        echo "Deleting 7+ days old roots..."-        find "$MNTPOINT/old_roots" -mindepth 1 -maxdepth 1 \-          -mtime +7 \-          -exec btrfs sub del -R {} +--        echo "Creating new root..."-        btrfs sub cre "$MNTPOINT/@"-      )-    '';-  in lib.mkIf (config ? "disko" && config.disko.devices.disk ? "main") ({+  fileSystems = lib.mkIf impermanence {+    "/persist".neededForBoot = true;+  };++  system.activationScripts.persistent-dirs = lib.mkIf impermanence {+    deps = [ "users" ];+    text =+      let+        mkHomePersist = user: lib.optionalString user.createHome ''+          mkdir -p /persist${user.home}+          chown ${user.name}:${user.group} /persist${user.home}+          chmod ${user.homeMode} /persist${user.home}+        '';+      in+        lib.concatLines (map mkHomePersist (lib.attrValues config.users.users));+  };++  assertions = [{+    assertion = rollback -> config.boot.initrd.systemd.enable;+    message = "kore: root rollback needs boot.initrd.systemd.enable";+  }];++  boot.initrd = lib.mkIf rollback {     supportedFilesystems = [ "btrfs" ];-    postDeviceCommands = lib.mkIf (!systemdStage1) (lib.mkBefore script); -    systemd.services.wipe-root = lib.mkIf (systemdStage1) {+    systemd.services.wipe-root = {       wantedBy = [ "initrd.target" ];-      requires = [ "dev-mapper-crypted.device" ];+      requires = [ rootUnit ];+      after = [ rootUnit ];       before = [ "sysroot.mount" ];-      after = [ "dev-mapper-crypted.device" "[email protected]" ];       unitConfig.DefaultDependencies = "no";       serviceConfig = {         Type = "oneshot";         RemainAfterExit = true;       };-      script = script;+      script = ''+        mkdir -p /tmp+        MNTPOINT=$(mktemp -d)+        (+          mount ${rootDevice} "$MNTPOINT"+          trap 'umount "$MNTPOINT"' EXIT++          if [[ -e $MNTPOINT/@ ]]; then+            echo "Backing up root..."+            mkdir -p $MNTPOINT/old_roots+            mv "$MNTPOINT/@" "$MNTPOINT/old_roots/@_$(date "+%Y-%m-%-d_%H:%M:%S")"+          fi++          echo "Deleting 7+ days old roots..."+          find "$MNTPOINT/old_roots" -mindepth 1 -maxdepth 1 \+            -mtime +7 \+            -exec btrfs sub del -R {} +++          echo "Creating new root..."+          btrfs sub cre "$MNTPOINT/@"+        )+      '';     };-  });--  fileSystems."/persist".neededForBoot = true;+  }; }

nixos/features/kore.nix

@@ -1,21 +1,64 @@ { config, lib, kore, ... }:  let+  cfg = config.kore;+  hostname = config.networking.hostName;++  identityOptions = { name, ... }:+    let+      dir = ../../keys/identities + "/${name}";+      sshDir = dir + "/ssh";+      gpgFile = dir + "/gpg.asc";++      sshFiles = lib.optionals (builtins.pathExists sshDir)+        (lib.filter (lib.hasSuffix ".pub") (lib.attrNames (builtins.readDir sshDir)));+    in {+      options = with lib; {+        email = mkOption {+          type = types.nullOr types.str;+          default = null;+        };+        gpg = mkOption {+          type = types.nullOr types.str;+          default = null;+        };+        sshKeys = mkOption {+          type = types.listOf types.str;+          default = map (file: lib.fileContents (sshDir + "/${file}")) sshFiles;+        };+        gpgKey = mkOption {+          type = types.nullOr types.path;+          default = if builtins.pathExists gpgFile then gpgFile else null;+        };+      };+    };+   hostOptions = with lib; {     system = mkOption {       type = types.str;     };-    ipv4 = mkOption {-      type = types.nullOr types.str;-      default = null;+    stateVersion = mkOption {+      type = types.str;     };     roles = mkOption {       type = types.listOf types.str;       default = [];     };+    users = mkOption {+      type = types.listOf types.str;+      default = [];+    };+    ipv4 = mkOption {+      type = types.nullOr types.str;+      default = null;+    };   }; in {   options.kore = with lib; {+    identities = mkOption {+      type = types.attrsOf (types.submodule identityOptions);+      default = {};+    };     hosts = mkOption {       type = types.attrsOf (types.submodule [{ options = hostOptions; }]);       default = {};@@ -23,21 +66,43 @@ in {     currentHost = mkOption {       type = types.submodule [{ options = hostOptions; }];     };++    impermanence.enable = mkOption {+      type = types.bool;+      default = true;+    };   };-  config = {-    warnings = lib.optional (!(kore.hosts ? ${config.networking.hostName}))-      "no configuration for ${config.networking.hostName} found"; +  config = {     kore = {+      identities = kore.identities or {};       hosts = kore.hosts;-      currentHost = kore.hosts.${config.networking.hostName};+      currentHost = kore.hosts.${hostname};     }; -    # /etc/hosts so machines resolve each other by name; placeholder-    # 0.0.0.0 addresses are skipped.+    assertions = map (user: {+      assertion = cfg.identities ? ${user};+      message = "kore: ${hostname} has user ${user}, but kore.json has no identity for it";+    }) cfg.currentHost.users;++    nixpkgs.hostPlatform = cfg.currentHost.system;+    system.stateVersion = cfg.currentHost.stateVersion;++    users.users = lib.listToAttrs (lib.imap0 (i: user: lib.nameValuePair user {+      isNormalUser = true;+      password = "tmp";+      extraGroups = [ "wheel" ];++      subUidRanges = [{ startUid = 100000 + i * 65536; count = 65536; }];+      subGidRanges = [{ startGid = 100000 + i * 65536; count = 65536; }];++      openssh.authorizedKeys.keys = cfg.identities.${user}.sshKeys or [];+    }) cfg.currentHost.users);++    # /etc/hosts so machines resolve each other by name.     networking.hosts = lib.mkMerge (lib.mapAttrsToList (name: host:-      lib.optionalAttrs (host.ipv4 != null && host.ipv4 != "0.0.0.0") {+      lib.optionalAttrs (host.ipv4 != null) {         "${host.ipv4}" = [ "${name}.${config.networking.domain}" name ];-      }) kore.hosts);+      }) cfg.hosts);   }; }

nixos/hosts/default.nix

@@ -2,18 +2,14 @@  let   mkSystem = hostname: host: lib.nixosSystem {-    system = host.system;     specialArgs = { inherit inputs outputs kore; };     modules = [       ../features/global.nix       ../features/kore.nix -      ../roles+      ./${hostname}.nix -      (./. + "/${hostname}.nix")--      { networking.hostName = "${hostname}"; }-      { system.stateVersion = "26.11"; }-    ];+      { networking.hostName = hostname; }+    ] ++ map (role: ../roles/${role}.nix) host.roles;   }; in lib.mapAttrs mkSystem kore.hosts

nixos/hosts/gomphrena.nix

@@ -1,11 +1,10 @@-{ lib, pkgs, inputs, modulesPath, ... }:+{ inputs, ... }:  {-  imports = [-    inputs.nixos-wsl.nixosModules.default+  imports = [ inputs.nixos-wsl.nixosModules.default ]; -    ( modulesPath + "/installer/scan/not-detected.nix" )-  ];+  # WSL can't mount /persist at boot.+  kore.impermanence.enable = false;    wsl = {     enable = true;@@ -18,24 +17,8 @@     };   }; -  users.users.lostduk = {-    password = "tmp";-    isNormalUser = true;--    extraGroups = [ "wheel" ];-    subUidRanges = [{ startUid = 100000; count = 65536; }];-    subGidRanges = [{ startGid = 100000; count = 65536; }];-  };-   hardware = {     graphics.enable = true;     cpu.intel.updateMicrocode = true;   };--  environment.persistence."/persist" = lib.mkForce {};--  fileSystems."/persist" = {-    enable = lib.mkForce false;-    neededForBoot = lib.mkForce false;-  }; }

nixos/hosts/sunflower.nix

@@ -1,88 +0,0 @@-{ inputs, modulesPath, pkgs, ... }:--{-  imports = [-    inputs.disko.nixosModules.disko--    ( modulesPath + "/installer/scan/not-detected.nix" )-  ];--  boot = {-    kernelModules = [ "kvm-intel" ];--    loader = {-      systemd-boot.enable = true;-      efi.canTouchEfiVariables = true;-    };--    initrd = {-      systemd.enable = true;-      availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];-    };-  };--  users.users.lostduk = {-    password = "tmp";-    isNormalUser = true;--    extraGroups = [ "wheel" ];-    subUidRanges = [{ startUid = 100000; count = 65536; }];-    subGidRanges = [{ startGid = 100000; count = 65536; }];-  };--  hardware = {-    graphics = {-      enable = true;-      extraPackages = with pkgs; [ libGL ];-    };-    cpu.intel.updateMicrocode = true;-  };--  disko.devices.disk.main = {-    type = "disk";-    device = "/dev/sda";-    content = {-      type = "gpt";-      partitions = {-        ESP = {-          size = "512M";-          type = "EF00";-          content = {-            type = "filesystem";-            format = "vfat";-            mountpoint = "/boot";-            mountOptions = [ "defaults" "uid=0" "gid=0" "fmask=0077" "dmask=0077" ];-          };-        };-        luks = {-          size = "100%";-          content = {-            name = "crypted";-            type = "luks";-            extraFormatArgs = [ "--type luks2" ];-            content = {-              type = "btrfs";-              extraArgs = [ "-f" ];-              subvolumes = let-                options = [ "compress=zstd" "noatime" "space_cache=v2" "discard=async" "ssd" ];-              in {-                "/@" = {-                  mountpoint = "/";-                  mountOptions = options;-                };-                "/@nix" = {-                  mountpoint = "/nix";-                  mountOptions = options;-                };-                "/@persist" = {-                  mountpoint = "/persist";-                  mountOptions = options;-                };-              };-            };-          };-        };-      };-    };-  };-}

nixos/roles/default.nix

@@ -1,6 +0,0 @@-{-  imports = [-    ./home.nix-    ./desktop.nix-  ];-}

nixos/roles/desktop.nix

@@ -1,116 +1,55 @@-{ outputs, config, pkgs, lib, ... }:+{ pkgs, ... }: -let-  roleName = "desktop";-  roleEnabled = lib.elem roleName config.kore.currentHost.roles;-in {-  config = lib.mkMerge [{} (lib.mkIf roleEnabled {-    xdg.portal = {-      enable = true;-      extraPortals = [ pkgs.xdg-desktop-portal-wlr ];-      configPackages = [ pkgs.xdg-desktop-portal-gtk pkgs.xdg-desktop-portal-wlr ];+{+  xdg.portal = {+    enable = true;+    extraPortals = [ pkgs.xdg-desktop-portal-wlr ];+    configPackages = [ pkgs.xdg-desktop-portal-gtk pkgs.xdg-desktop-portal-wlr ]; -      wlr.enable = true;+    wlr.enable = true; -      config.common = {-        default = [ "wlr" ];-      };+    config.common = {+      default = [ "wlr" ];     };+  }; -    system.activationScripts.persistent-dirs.text =-      let-        mkHomePersist = user: lib.optionalString user.createHome ''-          mkdir -p /persist/${user.home}-          chown ${user.name}:${user.group} /persist/${user.home}-          chmod ${user.homeMode} /persist/${user.home}-        '';-        users = lib.attrValues config.users.users;-      in-        lib.concatLines (map mkHomePersist users);--    fonts = {-      enableDefaultPackages = false;+  fonts = {+    enableDefaultPackages = false; -      packages = with pkgs; [-        noto-fonts-        noto-fonts-cjk-sans-        noto-fonts-cjk-serif-        noto-fonts-color-emoji+    packages = with pkgs; [+      noto-fonts+      noto-fonts-cjk-sans+      noto-fonts-cjk-serif+      noto-fonts-color-emoji -        #(nerdfonts.override { fonts = [ "ComicShannsMono" ]; })-        nerd-fonts.comic-shanns-mono-      ];+      nerd-fonts.comic-shanns-mono+    ]; -      fontconfig = {-        hinting.autohint = true;+    fontconfig = {+      hinting.autohint = true; -        defaultFonts = {-          serif = [ "Noto Serif" "Noto Color Emoji" ];-          sansSerif = [ "Noto Sans" "Noto Color Emoji" ];-          monospace = [ "ComicShannsMono Nerd Font" "Noto Color Emoji" ];-          emoji = [ "Noto Color Emoji" ];-        };+      defaultFonts = {+        serif = [ "Noto Serif" "Noto Color Emoji" ];+        sansSerif = [ "Noto Sans" "Noto Color Emoji" ];+        monospace = [ "ComicShannsMono Nerd Font" "Noto Color Emoji" ];+        emoji = [ "Noto Color Emoji" ];       };     };+  }; -    services = {-      udisks2.enable = true;--      pipewire = {-        enable = true;--        alsa.enable = true;-        alsa.support32Bit = true;--        pulse.enable = true;-        jack.enable = true;+  services = {+    udisks2.enable = true; -        wireplumber = {-          enable = true;--          # https://github.com/NixOS/nixpkgs/pull/292115-          extraConfig."alsa-lowlatency" = {-            "monitor.alsa.rules" = [{-              matches = [{ "node.name" = "~alsa_output.*"; }];--              actions.update-props = {-                "audio.format" = "S32LE";-                "audio.rate" = "96000";-                "api.alsa.period-size" = 2;-              };-            }];-          };-        };--        extraConfig.pipewire."92-low-latency" = {-          context = {-            properties.default.clock = {-              rate = 48000;-              quantum = 64;-            };+    pipewire = {+      enable = true; -            modules = [{-              name = "libpipewire-module-protocol-pulse";+      alsa.enable = true;+      alsa.support32Bit = true; -              args.pulse = {-                min = {-                  req = "64/48000";-                  quantum = "64/48000";-                  frag = "64/48000";-                };+      pulse.enable = true;+      jack.enable = true; -                default.req = "64/48000";-              };-            }];-          };-          -          stream.properties = {-            node.latency = "64/48000";-            resample.quality = 1;-          };-        };-      };+      wireplumber.enable = true;     };-  })];+  }; }-

nixos/roles/home.nix

@@ -1,25 +1,20 @@-{ inputs, outputs, config, pkgs, lib, ... }:+{ inputs, outputs, config, lib, ... }: -let-  roleName = "home";-  roleEnabled = lib.elem roleName config.kore.currentHost.roles;-in {-  imports = [ inputs.home-manager.nixosModules.home-manager  ];+{+  imports = [ inputs.home-manager.nixosModules.home-manager ]; -  config = lib.mkMerge [{} (lib.mkIf roleEnabled {-      nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [-      "claude-code"-      ];+  nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [+    "claude-code"+  ]; -    home-manager = {-      useGlobalPkgs = true;-      useUserPackages = true;-      extraSpecialArgs = { inherit inputs outputs; };+  home-manager = {+    useGlobalPkgs = true;+    useUserPackages = true;+    extraSpecialArgs = { inherit inputs outputs; }; -      users.lostduk = outputs.homeConfigurations.${config.networking.hostName};-    };+    users = lib.genAttrs config.kore.currentHost.users+      (_: outputs.homeModules.${config.networking.hostName});+  }; -    programs.fuse.userAllowOther = true;-  })];+  programs.fuse.userAllowOther = true; }-

overlays/default.nix

@@ -1,4 +1,4 @@-{ inputs, outputs, ... }:+{ inputs, ... }:  {   # https://m7.rs/git/nix-config/tree/overlays/default.nix#line-13@@ -6,21 +6,14 @@     inputs =       builtins.mapAttrs (_: flake:         let-          legacyPackages = (flake.legacyPackages or {}).${final.system} or {};-          packages = (flake.packages or {}).${final.system} or {};+          inherit (final.stdenv.hostPlatform) system;+          legacyPackages = (flake.legacyPackages or {}).${system} or {};+          packages = (flake.packages or {}).${system} or {};         in           if legacyPackages != {} then legacyPackages else packages       )       inputs;   }; -  modifications = final: prev: {-    dwl = prev.dwl.overrideAttrs (oldAttrs: {-      enableXWayland = true;-      -      postPatch = ''-        cp ${./dwl_config.h} config.h-      '';-    });-  };+  modifications = final: prev: { }; }

overlays/dwl_config.h

@@ -1,118 +0,0 @@-/* general */-#define TAGCOUNT (6)--static int log_level                       = WLR_ERROR;-static const int sloppyfocus               = 1;-static const int bypass_surface_visibility = 0;--/* appearance */-static const unsigned int borderpx         = 1;-static const float rootcolor[]             = {0.1f, 0.1f, 0.1f, 1.0f};-static const float bordercolor[]           = {0.2f, 0.2f, 0.2f, 1.0f};-static const float focuscolor[]            = {0.0f, 0.3f, 0.4f, 1.0f};-static const float urgentcolor[]           = {0.1f, 0.0f, 0.0f, 1.0f};-static const float fullscreen_bg[]         = {0.1f, 0.1f, 0.1f, 1.0f};--/* rules */-static const Rule rules[] = {-	{ "Gimp_EXAMPLE", NULL, 0, 1, -1 },-};--/* layouts */-static const Layout layouts[] = {-	{ "[T]", tile },-	{ "[F]", NULL },-	{ "[M]", monocle },-};--/* monitors */-static const MonitorRule monrules[] = {-	{ NULL, 0.55f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },-};--/* keyboard */-static const int repeat_rate = 25;-static const int repeat_delay = 600;--static const struct xkb_rule_names xkb_rules = {-	.layout = "us,th",-	.options = "grp:alt_shift_toggle",-};---/* trackpad */-static const int tap_to_click = 1;-static const int tap_and_drag = 1;-static const int drag_lock = 1;-static const int natural_scrolling = 0;-static const int disable_while_typing = 1;-static const int left_handed = 0;-static const int middle_button_emulation = 0;--static const enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;-static const enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;-static const uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;-static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;-static const double accel_speed = 0.0;-static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;--/* commands */-#define MODKEY WLR_MODIFIER_LOGO-#define MODALT WLR_MODIFIER_ALT-#define MODCTRL WLR_MODIFIER_CTRL-#define MODSHIFT WLR_MODIFIER_SHIFT--#define TAGKEYS(KEY, SKEY, TAG) \-	{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \-	{ MODKEY|MODCTRL, KEY, toggleview, {.ui = 1 << TAG} }, \-	{ MODKEY|MODSHIFT, SKEY, tag, {.ui = 1 << TAG} }, \-	{ MODKEY|MODCTRL|MODSHIFT, SKEY, toggletag, {.ui = 1 << TAG} }--#define CHVT(n) { MODCTRL|MODALT, XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }--static const char *termcmd[] = { "foot", NULL };-static const char *menucmd[] = { "dmenu_run", NULL };--static const Key keys[] = {-	{ MODKEY, XKB_KEY_d, spawn, {.v = menucmd} },-	{ MODKEY, XKB_KEY_Return, spawn, {.v = termcmd} },-	{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },-	{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} },-	{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} },-	{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },-	{ MODKEY, XKB_KEY_o, incnmaster, {.i = -1} },-	{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },-	{ MODKEY, XKB_KEY_q, killclient, {0} },-	{ MODKEY|MODSHIFT, XKB_KEY_Tab, view, {0} },-	{ MODKEY|MODSHIFT, XKB_KEY_Return, zoom, {0} },-	{ MODKEY|MODSHIFT, XKB_KEY_T, setlayout, {.v = &layouts[0]} },-	{ MODKEY|MODSHIFT, XKB_KEY_F, setlayout, {.v = &layouts[1]} },-	{ MODKEY|MODSHIFT, XKB_KEY_M, setlayout, {.v = &layouts[2]} },-	{ MODKEY, XKB_KEY_space, togglefloating, {0} },-	{ MODKEY, XKB_KEY_f, togglefullscreen, {0} },-	{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },-	{ MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} },-	{ MODKEY|MODSHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} },-	{ MODKEY|MODSHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} },-	{ MODKEY|MODSHIFT, XKB_KEY_P, quit, {0} },--	/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */-	{ MODCTRL|MODALT, XKB_KEY_Terminate_Server, quit, {0} },--	TAGKEYS(XKB_KEY_1, XKB_KEY_exclam, 0),-	TAGKEYS(XKB_KEY_2, XKB_KEY_at, 1),-	TAGKEYS(XKB_KEY_3, XKB_KEY_numbersign, 2),-	TAGKEYS(XKB_KEY_4, XKB_KEY_dollar, 3),-	TAGKEYS(XKB_KEY_5, XKB_KEY_percent, 4),-	TAGKEYS(XKB_KEY_6, XKB_KEY_asciicircum, 5),--	/* Ctrl-Alt-Fx is used to switch to another VT */-	CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),-	CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),-};--static const Button buttons[] = {-	{ MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },-	{ MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} },-	{ MODKEY, BTN_MIDDLE, togglefloating, {0} },-};