Files
dotfiles/docs/superpowers/specs/2026-05-13-networkmanager-activation-design.md
T
funman300 101accc26b docs: spec for NetworkManager activation with iwd backend
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:43:10 -07:00

5.3 KiB

NetworkManager Activation Design

Date: 2026-05-13 Status: Approved

Summary

Activate NetworkManager (already installed but disabled) and configure it to use iwd as its wifi backend. Disables systemd-networkd (the current connection manager) to avoid conflicts. Re-enables nm-applet and networkmanager_dmenu paths that were dead because NM wasn't running.

Current Behaviour

  • iwd is running — manages wifi at the protocol level
  • systemd-networkd is running — handles DHCP and link config
  • NetworkManager.service is installed but disabled (inactive/dead)
  • nm-applet runs at no-op (no dbus peer to connect to)
  • networkmanager_dmenu (waybar network module's on-click) errors with "NetworkManager is not running"

End result: connectivity works, but the entire NM-based UI ecosystem (applet, dmenu picker, nmcli) is non-functional.

Target Behaviour

  • iwd continues running, now as NM's wifi backend
  • NetworkManager runs as the connection manager
  • systemd-networkd stopped and disabled
  • nm-applet shows connection state in the waybar tray (works because the SNI watcher chain works)
  • networkmanager_dmenu opens a wofi-style picker that lists/connects to known networks
  • Existing wifi profiles preserved (NM reads iwd's known-networks via the backend interface)

Implementation

Tracked dotfile

NetworkManager/conf.d/wifi-backend.conf (new file in repo, deployed to /etc/NetworkManager/conf.d/):

[device]
wifi.backend=iwd

This is the only file NM needs. It tells NM to delegate wifi to iwd (which is already running) instead of spawning its own wpa_supplicant. Modern, well-supported configuration on Arch.

install.sh

Append one block in the existing system-deploy section (after the hibernate sleep.conf.d line):

sudo install -Dm644 "$(pwd)/NetworkManager/conf.d/wifi-backend.conf" \
    /etc/NetworkManager/conf.d/wifi-backend.conf

install -Dm644 creates /etc/NetworkManager/conf.d/ if it doesn't exist (it usually does, since the NM package ships an empty stub) and sets mode 644.

packages.txt

Re-add network-manager-applet (removed in commit 4303562 when nm-applet was non-functional). Insertion can go anywhere — alphabetical-ish near the existing networkmanager-related lines.

niri/config.kdl

Re-add the spawn-at-startup line (removed in same earlier commit):

spawn-at-startup "nm-applet" "--indicator"

Position: with the other applet/daemon spawns, alphabetical order doesn't matter.

One-time service swap (manual, with sudo)

Documented in README, not scripted. Two commands run once:

sudo systemctl disable --now systemd-networkd
sudo systemctl enable --now NetworkManager

Why not script it: systemd unit state is persistent. Once flipped, it stays. Doesn't need to be in install.sh (which runs frequently). A one-time README instruction matches the existing pattern for enable-hibernation.sh.

README.md

Append a subsection under ## Setup, alongside the existing "One-time hibernation enablement":

### One-time NetworkManager activation

After `install.sh` deploys the NM config, swap from systemd-networkd to NetworkManager (one-time, persistent across reboots):

\`\`\`bash
sudo systemctl disable --now systemd-networkd
sudo systemctl enable --now NetworkManager
\`\`\`

Wifi will drop for a few seconds and reconnect via iwd's stored profiles. If reconnection fails, re-enter the wifi password via `nm-applet` or `networkmanager_dmenu`.

Files Touched

File Action
NetworkManager/conf.d/wifi-backend.conf created
install.sh append one sudo install -Dm644 line
packages.txt re-add network-manager-applet
niri/config.kdl re-add spawn-at-startup "nm-applet" "--indicator"
README.md append "One-time NetworkManager activation" subsection

Verification

After install.sh + the two systemctl commands:

systemctl is-active NetworkManager     # active
systemctl is-active systemd-networkd   # inactive
nmcli general status                   # prints connectivity status
nmcli -f WIFI-PROPERTIES.WPA general status   # confirms iwd backend is alive
nmcli connection show --active         # shows the wifi connection
busctl --user get-property org.kde.StatusNotifierWatcher \
    /StatusNotifierWatcher org.kde.StatusNotifierWatcher RegisteredStatusNotifierItems
                                       # should include nm-applet's tray entry

Behavioural checks:

  1. Wifi stays connected (after a brief drop during the swap).
  2. Click waybar's network widget — networkmanager_dmenu opens with available networks.
  3. The nm-applet tray icon shows current connection state.

Out of Scope

  • Migrating iwd profiles to NM-format files — not needed; NM reads iwd's known-networks via the backend interface.
  • Removing iwd — kept as the wifi backend.
  • Removing the networkmanager package — already installed; we just enable the service.
  • DNS / dispatcher / split-tunnel / VPN config — beyond scope; default NM behaviour is fine.
  • Wired-only fallback — out of scope; NM handles ethernet automatically when present.
  • Deleting the obsolete nm-applet removal commit from history — keep history honest.
  • Auto-running the systemctl commands from install.sh — out of scope; service-state changes are one-time and persistent.