Files
dotfiles/docs/superpowers/plans/2026-05-13-networkmanager-activation.md
funman300 b57d134c2b docs: implementation plan for NetworkManager activation
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:44:57 -07:00

9.5 KiB

NetworkManager Activation Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Activate NetworkManager (with iwd as wifi backend) so the existing nm-applet, networkmanager_dmenu, and waybar network widget actually work.

Architecture: One tracked drop-in (NetworkManager/conf.d/wifi-backend.conf) deployed by install.sh. Re-add the package and the niri spawn-at-startup line that were removed when nm-applet was useless. Document the one-time systemctl swap in README. iwd keeps running as wifi backend; systemd-networkd is disabled by the user via the documented commands.

Tech Stack: NetworkManager 1.56, iwd, niri, systemd, install(1).

Spec: docs/superpowers/specs/2026-05-13-networkmanager-activation-design.md

Verification model: Bash syntax checks + niri validate for static correctness. Functional checks (NetworkManager active, wifi connected, tray icon present) require the live session — controller verifies after the README's manual systemctl commands run.


File Structure

File Role
NetworkManager/conf.d/wifi-backend.conf New tracked dotfile. One-line [device] block telling NetworkManager to use iwd as wifi backend.
install.sh Modified: append one sudo install -Dm644 line to deploy the drop-in.
packages.txt Modified: re-add network-manager-applet.
niri/config.kdl Modified: re-add spawn-at-startup "nm-applet" "--indicator".
README.md Modified: append ### One-time NetworkManager activation subsection under ## Setup.

Task 1: Tracked drop-in + install.sh deploy

After this task, the repo carries the wifi-backend drop-in and install.sh deploys it. The system file /etc/NetworkManager/conf.d/wifi-backend.conf lands when install.sh runs. NetworkManager isn't enabled yet — Task 4 (manual user step) does that.

Files:

  • Create: NetworkManager/conf.d/wifi-backend.conf

  • Modify: install.sh (append after the existing sleep/hibernate-delay.conf line at line 73)

  • Step 1: Create the directory and drop-in file

mkdir -p NetworkManager/conf.d

Write NetworkManager/conf.d/wifi-backend.conf with this exact content:

[device]
wifi.backend=iwd
  • Step 2: Verify file contents
cat NetworkManager/conf.d/wifi-backend.conf

Expected: exactly the two lines above.

  • Step 3: Add deploy line to install.sh

Find the existing suspend/hibernate deploy block in install.sh (lines 71-73):

echo "==> Deploying suspend/hibernate config"
sudo install -Dm644 "$(pwd)/logind/lid.conf" /etc/systemd/logind.conf.d/lid.conf
sudo install -Dm644 "$(pwd)/sleep/hibernate-delay.conf" /etc/systemd/sleep.conf.d/hibernate-delay.conf

Immediately after the second sudo install -Dm644 line (the sleep one), insert:


echo "==> Deploying NetworkManager config"
sudo install -Dm644 "$(pwd)/NetworkManager/conf.d/wifi-backend.conf" /etc/NetworkManager/conf.d/wifi-backend.conf

(Leading blank line for visual separation between the two deploy blocks.)

  • Step 4: Bash-syntax-check install.sh
bash -n install.sh && echo "syntax ok"

Expected: syntax ok and exit 0.

  • Step 5: Confirm the new line is in place
grep -n "wifi-backend" install.sh

Expected output:

sudo install -Dm644 "$(pwd)/NetworkManager/conf.d/wifi-backend.conf" /etc/NetworkManager/conf.d/wifi-backend.conf
  • Step 6: Commit
git add NetworkManager/conf.d/wifi-backend.conf install.sh
git commit -m "NetworkManager: track wifi-backend.conf and deploy via install.sh"

Task 2: Re-add network-manager-applet to packages.txt

After this task, network-manager-applet is back in the package manifest. Anyone setting up the system fresh installs the applet binary (currently still on this user's machine — uninstalling wasn't part of the earlier removal — but the manifest needs to match reality).

Files:

  • Modify: packages.txt (re-add one line)

  • Step 1: Add network-manager-applet back to packages.txt

Open packages.txt. The list isn't strictly alphabetical, but networkmanager is on line 17 (existing), so insert the applet on line 18 right after it:

Current lines 17-18:

networkmanager
xdg-desktop-portal-wlr

Becomes:

networkmanager
network-manager-applet
xdg-desktop-portal-wlr
  • Step 2: Verify the entry is present exactly once
grep -c "^network-manager-applet$" packages.txt

Expected: 1.

  • Step 3: Commit
git add packages.txt
git commit -m "packages: re-add network-manager-applet (now functional)"

Task 3: Re-add nm-applet spawn-at-startup in niri

After this task, nm-applet --indicator runs at niri start. Combined with the working SNI watcher (waybar's built-in), the network connection icon will appear in the tray once NetworkManager is enabled (Task 5, manual).

Files:

  • Modify: niri/config.kdl (insert one spawn-at-startup line)

  • Step 1: Find the right insertion point

The existing spawn-at-startup block is around lines 34-46 (after the env block, before binds {). It currently does NOT contain nm-applet. Insertion goes anywhere in that block; placing it logically with other applet-style spawns (after awww-daemon which is line 36) keeps it grouped with desktop-startup helpers.

  • Step 2: Insert the line

Find lines 36-37:

spawn-at-startup "awww-daemon"
spawn-at-startup "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1"

Insert between them:

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

Result (lines 36-38):

spawn-at-startup "awww-daemon"
spawn-at-startup "nm-applet" "--indicator"
spawn-at-startup "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1"
  • Step 3: Validate niri config
niri validate 2>&1 | tail -2

Expected: a final line INFO niri: config is valid. Non-zero exit means a syntax issue.

  • Step 4: Confirm the line is in place
grep -n 'nm-applet' niri/config.kdl

Expected: one match, spawn-at-startup "nm-applet" "--indicator".

  • Step 5: Commit
git add niri/config.kdl
git commit -m "niri: re-add nm-applet --indicator spawn-at-startup"

Task 4: README — One-time NetworkManager activation subsection

After this task, the README documents the one-time systemctl swap so a fresh-install reader knows the manual step required after install.sh deploys the config.

Files:

  • Modify: README.md (append a subsection after the existing "One-time hibernation enablement")

  • Step 1: Append the new subsection

Open README.md. The last subsection is ### One-time hibernation enablement (added previously). After its closing line, append:


### One-time NetworkManager activation

After `install.sh` deploys the NetworkManager 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` (tray icon) or `networkmanager_dmenu` (waybar network widget click).

(The outer fence above is four backticks because the block contains a triple-backtick code block — paste the inner content verbatim, no enclosing 4-backtick fence.)

  • Step 2: Verify the section was added
grep -A 6 "One-time NetworkManager activation" README.md

Expected: the new subsection prints, including the sudo systemctl enable --now NetworkManager line.

  • Step 3: Commit
git add README.md
git commit -m "docs: document one-time NetworkManager activation"

Final verification (controller, post-merge)

These run on the live system, after merging all four task commits and running the README's manual systemctl commands.

  • Run install.sh to deploy the config
bash install.sh
# Expects "==> Deploying NetworkManager config" to appear in output
ls -la /etc/NetworkManager/conf.d/wifi-backend.conf

Expected: the file exists, mode 644, owned by root, content matches the repo file.

  • Run the documented systemctl swap (one-time, requires sudo)
sudo systemctl disable --now systemd-networkd
sudo systemctl enable --now NetworkManager

Expected: both succeed; wifi briefly drops then reconnects within ~5-10 s.

  • Verify NetworkManager is the active connection manager
systemctl is-active NetworkManager      # active
systemctl is-active systemd-networkd    # inactive
nmcli general status                    # prints connectivity status
nmcli connection show --active          # shows the wifi connection
  • Verify nm-applet appears in the tray

After a niri restart (or niri msg action spawn -- nm-applet --indicator if niri's spawn IPC supports it), the nm-applet tray icon should appear in waybar:

busctl --user get-property org.kde.StatusNotifierWatcher \
    /StatusNotifierWatcher org.kde.StatusNotifierWatcher RegisteredStatusNotifierItems

Expected: includes :.../org/ayatana/NotificationItem/nm_applet (or similar nm_applet entry).

  • Verify the waybar network widget click works

Click the network module in waybar — networkmanager_dmenu should pop up a wofi-style picker listing available networks. Selecting one should connect.