{
  description = "PatOS is a minimal, immutable Linux distribution specialized for the Patagia Platform.";

  inputs = {
    flake-utils.url = "github:numtide/flake-utils";
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  };

  outputs =
    {
      self,
      flake-utils,
      nixpkgs,
    }:
    flake-utils.lib.eachDefaultSystem (
      system:
      let
        version = "0.0.1";
        secureBoot = "false";
        microcode = "intel";
        updateUrl = "http://10.0.2.2:8000/";

        overlay = final: prev: {
          patos = prev.lib.makeScope prev.newScope (self: {
            kernel = final.callPackage ./pkgs/kernel { };
            glibc = final.callPackage ./pkgs/glibc { };
            busybox = final.callPackage ./pkgs/busybox { };
            openssl = final.callPackage ./pkgs/openssl { };
            kexec = final.callPackage ./pkgs/kexec-tools { };
            lvm2 = final.callPackage ./pkgs/lvm2 { };
            tpm2-tools = final.callPackage ./pkgs/tpm2-tools { };
            tpm2-tss = final.callPackage ./pkgs/tpm2-tss { };
            systemd = final.callPackage ./pkgs/systemd { };
            dbus-broker = final.callPackage ./pkgs/dbus-broker { };

            rootfs = final.callPackage ./pkgs/rootfs/mkrootfs.nix { inherit version; };
            initrd = final.callPackage ./pkgs/rootfs/mkinitrd.nix { inherit version; };
          });
        };

        pkgs = import nixpkgs { inherit system; overlays = [ overlay ]; };
        pkgsCross = import nixpkgs {
          inherit system;
          overlays = [ overlay ];
          crossSystem = {
            config = "aarch64-unknown-linux-gnu";
          };
        };
      in
      {
        packages = {
          default = self.packages.${system}.image;

          image = pkgs.callPackage ./pkgs/image { inherit version updateUrl microcode secureBoot; };
          image-aarch64 = pkgsCross.callPackage ./pkgs/image { inherit version updateUrl secureBoot; };

          qemu-uefi-tpm = pkgs.callPackage ./utils/qemu-uefi-tpm.nix { };

          firewall-sysext = pkgs.callPackage ./lib/make-sysext.nix {
            name = "firewall-tools";
            version = "0.0.1";
            packages = [
              # network/firewalling
              { drv = pkgs.iproute2; path = "bin/"; }
              { drv = pkgs.nftables; path = "bin/"; }
              { drv = pkgs.wireguard-tools; path = "bin/.wg-wrapped"; destpath = "bin/wg"; }
              # deps
              { drv = pkgs.nftables; path = "lib/"; }
              { drv = pkgs.libnftnl; path = "lib/"; }
              { drv = pkgs.iptables; path = "lib/"; }
              { drv = pkgs.libgcc.lib; path = "lib/"; }
              { drv = pkgs.libgcc; path = "lib/"; }
              { drv = pkgs.libmnl; path = "lib/"; }
              { drv = pkgs.gmp; path = "lib/"; }
              { drv = pkgs.jansson.out; path = "lib/"; }
              { drv = pkgs.ncurses.out; path = "lib/"; }
              { drv = pkgs.libedit; path = "lib/"; }
            ];
          };

          debug-tools-sysext = pkgs.callPackage ./lib/make-sysext.nix {
            name = "debug-tools";
            version = "0.0.1";
            packages = [
              { drv = pkgs.curl; path = "bin/"; }
              { drv = pkgs.bash; path = "bin/"; }
              { drv = pkgs.keyutils; path = "bin/"; }
              { drv = pkgs.gnutar; path = "bin/"; }
              { drv = pkgs.strace; path = "bin/"; }
              { drv = pkgs.cryptsetup; path = "bin/"; }
              { drv = pkgs.erofs-utils; path = "bin/"; }
              { drv = pkgs.binutils-unwrapped; path = "bin/"; }
              { drv = pkgs.binutils-unwrapped.lib; path = "lib/"; }
              { drv = pkgs.util-linuxMinimal; path = "bin/"; }
              { drv = pkgs.util-linuxMinimal.mount; path = "bin/"; }
              { drv = pkgs.util-linuxMinimal.login; path = "bin/"; }
              { drv = pkgs.util-linuxMinimal.swap; path = "bin/"; }
              { drv = pkgs.patos.glibc; path = "bin/ldd"; }
              { drv = pkgs.patos.tpm2-tools; path = "bin/tpm2"; }
              { drv = pkgs.patos.openssl; path = "bin/openssl"; }
              # shared lib required for mkfs.erofs
              { drv = pkgs.lz4.lib; path = "lib/"; }
              # shared lib required for cryptsetup
              { drv = pkgs.popt; path = "lib/"; }
              # shared lib required for strace
              { drv = pkgs.elfutils.out; path = "lib/"; }
              # shared lib required for bash
              { drv = pkgs.readline.out; path = "lib/"; }
              { drv = pkgs.ncurses.out; path = "lib/"; }
            ];
          };
        };

        checks = {
          simple-test = pkgs.runCommand "simple-test" { } ''
            ${self.packages.${system}.default}/bin/my-program
            touch $out
          '';
        };

        formatter = pkgs.nixpkgs-fmt;

        devShells.default = pkgs.mkShell {
          buildInputs = with pkgs; [
            just
            nixd
            nixfmt-rfc-style
            self.packages.${system}.qemu-uefi-tpm
          ];
        };

      }
    );
}