{ lib, ... }: {
  flake.lib.sshInventory =
    let
      # Hosts: pure network endpoints. No public keys live here anymore —
      # keys are per USER (see `users` below), one key per person.
      hosts = {
        "14900k" = {
          hostName = "192.168.2.25";
          aliases = [ "14900k" "nixdesk" ];
        };
        ideapad = {
          hostName = "192.168.2.229";
          aliases = [ "ideapad" ];
        };
        t2mbp = {
          hostName = "192.168.2.15";
          aliases = [ "t2mbp" ];
        };
        "uConsole" = {
          hostName = "192.168.2.99";
          aliases = [ "uConsole" "uconsole" ];
        };
        # Scratchpad / recovery target — hostName isn't an IP, so `activeHosts`
        # excludes it from navi deployments. Leave it in `hosts` for inventory
        # visibility while recovery is in progress.
        test = {
          hostName = "test";
          aliases = [ "test" ];
        };
        "nix-server" = {
          hostName = "192.168.2.238";
          aliases = [ "nix-server" ];
        };
        r5500 = {
          hostName = "192.168.2.100";
          aliases = [ "r5500" ];
        };
      };

      # Per-user public keys. One keypair per person, generated once with
      # `ssh-keygen -t ed25519 -C <comment>` (or `rbw gen ssh-key <user>`),
      # private key stored in Bitwarden under the same name. Paste the
      # `ssh-ed25519 AAAA… <comment>` line here.
      users = {
        olivier = {
          publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICpORzDw8kEOobjywl7bQaEp6Tez1c/ZP+7VBDsTcM8I olivier";
        };
        server = {
          publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICsksvNGOt/ebJtpRi9ocLBjwyl16VSaf+BsL2Hz5PRy server";
        };
        builder = {
          publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIILBtfW1cq9mG6uAjAfpZuVa1EWDSTPSCThapDXXlLgV builder";
        };
      };

      # Hosts SSH is actually safe to deploy/scan to: anything whose hostName
      # parses as an IPv4 dotted-quad. Filters out scratchpad/non-routable
      # entries (e.g. `hostName = "test"`).
      activeHosts = lib.filterAttrs
        (_: h: lib.match "^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$" h.hostName != null)
        hosts;

      # .pub filename convention. OpenSSH 7.3+ accepts a `.pub` file as
      # IdentityFile to filter `IdentityAgent` (rbw) keys without storing the
      # private key on disk — keep this trick.
      mkIdentityFileName = userName: ".ssh/id_ed25519_${lib.strings.toLower userName}.pub";

      mkSshConfigTemplate =
        {
          selectedHosts ? activeHosts,
          user ? null,
          # Catalog accounts the operator may authenticate AS via
          # `ssh <account>@<host>`. Each entry gets a `Match user <account>`
          # block that overrides IdentityFile so OpenSSH asks the rbw agent
          # for that account's private key. `cfg.user` is already covered
          # by the Host blocks, so don't list it here.
          extraIdentities ? [ ],
          identityAgent ? "SSH_AUTH_SOCK",
        }:
        let
          # Shared `IdentityFile` filter line (when `user` is set). Used by
          # both the per-host and gitea blocks so the two can't drift apart.
          idLine = lib.optionalString (user != null) "  IdentityFile ~/${mkIdentityFileName user}\n";

          # Match blocks for cross-account SSH. Filter out cfg.user since
          # the matching pub is already loaded via the Host block's
          # IdentityFile line — re-emitting it would just duplicate.
          matchBlocks = lib.concatStringsSep "\n" (map
            (n: ''
              Match user ${n}
                IdentityFile ~/${mkIdentityFileName n}
                IdentitiesOnly yes
            '')
            (builtins.filter (n: n != user) extraIdentities));

          # Per-host block. `IdentityFile` (when `user` is set) is a .pub file
          # pointing at the agent's matching private key. With IdentitiesOnly
          # yes, only agent keys matching that pub are tried — fixes the old
          # "too many auth failures" symptom by design.
          hostBlock = hostName:
            let
              e = selectedHosts.${hostName};
              hostPatterns = lib.concatStringsSep " " (e.aliases ++ [ e.hostName ]);
            in ''
              Host ${hostPatterns}
                HostName ${e.hostName}
              ${idLine}  IdentityAgent ${identityAgent}
                IdentitiesOnly yes
            '';

          # Gitea block: always emitted. `User git`, port 222. olivier's
          # public key (passed via `IdentityFile`) is what gitea accepts
          # because it gets pushed into gitea's authorized_keys through
          # gitea's own UI for that account.
          giteaBlock = ''
            Host git.chiasson.cloud gitea
              HostName 192.168.2.238
              Port 222
              User git
            ${idLine}  IdentityAgent ${identityAgent}
              IdentitiesOnly yes
          '';

          hostBlocks = lib.concatStringsSep "\n" (map hostBlock (lib.attrNames selectedHosts));
        in
        # Filter empty sections so an absent Match block (no extraIdentities)
        # doesn't add leading whitespace to the rendered config.
        lib.concatStringsSep "\n" (lib.filter (s: s != "") [
          matchBlocks
          giteaBlock
          hostBlocks
          ''
            Host *
              IdentitiesOnly yes
              IdentityAgent none
          ''
        ]);

      # Per-user line for `users.users.<u>.openssh.authorizedKeys.keys`.
      # `selection` is either "all" or a list of source identifiers for
      # sshd's `from=` constraint (IP, CIDR, or hostname if reverse-DNS works).
      # Returns null if inventory is missing the user's pubkey — caller is
      # expected to assert and fail the build rather than silently lock out.
      mkAuthorizedKeyLine = userName: selection:
        let
          entry = users.${userName} or null;
        in
        if entry == null then null
        else if (entry.publicKey or "") == "" then null
        else if selection == "all" then entry.publicKey
        else ''from="${lib.concatStringsSep "," selection}" ${entry.publicKey}'';
    in
    {
      inherit hosts users activeHosts;
      mkSshConfigTemplate = mkSshConfigTemplate;
      mkAuthorizedKeyLine = mkAuthorizedKeyLine;
      mkIdentityFileName = mkIdentityFileName;
    };
}
