Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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 existingsleep/hibernate-delay.confline 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-appletback topackages.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.