Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
24 KiB
Niri Gamemode 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: A compositor-level gamemode for niri that inhibits idle, silences notifications, switches to the performance power profile (and bumps the fan), and hides waybar while a game runs — reverting cleanly when it ends — driven by both Feral gamemode hooks and a Mod+G toggle.
Architecture: A single reference-counted bash script, scripts/gamemode-session.sh, tracks two "sources" (feral, manual) via marker files in a runtime state dir. It applies effects only on the first active source (0→1) and reverts only on the last (1→0), snapshotting the pre-game baseline so revert restores exactly what was there. Feral's gamemode.ini custom hooks call add feral/del feral; a niri keybind calls toggle (flips manual).
Tech Stack: bash, systemd-inhibit, makoctl, powerprofilesctl, fw-fanctrl, niri KDL config, Feral gamemode (gamemoded).
Global Constraints
- Script naming:
scripts/<name>.shsymlinked to~/.local/bin/<name>(no.shin the bin name). New script isscripts/gamemode-session.sh→~/.local/bin/gamemode-session. Name isgamemode-session, NOTgamemode(avoids Feral'sgamemoderun/gamemodednamespace). - Script must be crash-tolerant and never wedge the session: every effect step is individually guarded; a missing tool or a failed sub-step degrades to a no-op, and revert always runs every restore step.
- Effects apply ONLY on 0→1 active sources and revert ONLY on 1→0. Never re-snapshot baseline while already active.
- Power profile: only change it if the baseline profile differs from
performance; on revert, only restore if we changed it (never clobber a deliberateperformancechoice). - All new dotfiles are tracked in
~/Documents/dotfiles(this repo) and deployed to their live locations by symlink/copy exactly as existing configs are. - Commit after each task. Co-author trailer:
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>. - Verified environment facts:
makoctl mode -a/-r <mode>andsystemd-inhibit --what=idleare available; hypridle already honors systemd idle inhibitors (ignore_systemd_inhibit = false);setsid,fw-fanctrl,powerprofilesctl,pgrep,pkillall present.
Task 1: Reference-counted state machine (gamemode-session.sh core)
Build the script's dispatch + source refcounting + baseline snapshot, with effects behind a GAMEMODE_DRYRUN seam so the state machine is testable without touching the live session. Effect bodies are stubbed in this task (dryrun-logged placeholders); Task 2 fills in the real commands.
Files:
- Create:
scripts/gamemode-session.sh - Test:
scripts/tests/gamemode-session.test.sh(new throwaway test harness, committed alongside)
Interfaces:
-
Produces: CLI
gamemode-session {add <source>|del <source>|toggle|status|reset}.add <src>: touchsrc.<src>marker; on 0→1 snapshot baseline +apply_effects.del <src>: removesrc.<src>; on 1→0revert_effects+ clear baseline/idle files.toggle: flip themanualsource.status:active(exit 0) /inactive(exit 1).reset: force-revert + wipe state dir.
-
Env seams (consumed by the test):
GAMEMODE_STATE_DIRoverrides the state dir;GAMEMODE_DRYRUN=1makesrun()and effect functions log instead of act. -
Produces for later tasks:
apply_effects/revert_effectsand per-effect functionseffect_idle_on/off,effect_dnd_on/off,effect_perf_on/off,effect_waybar_on/off(Task 2 replaces their bodies). -
Step 1: Write the failing test harness
Create scripts/tests/gamemode-session.test.sh:
#!/bin/bash
# Drives gamemode-session in dryrun against a temp state dir and asserts the
# reference-counting state machine. No live effects run.
set -u
HERE=$(cd "$(dirname "$0")/.." && pwd)
SCRIPT="$HERE/gamemode-session.sh"
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT
export GAMEMODE_STATE_DIR="$TMP/state"
export GAMEMODE_DRYRUN=1
fail=0
check() { # desc, actual, expected
if [ "$2" = "$3" ]; then printf 'ok - %s\n' "$1"
else printf 'FAIL - %s (got [%s] want [%s])\n' "$1" "$2" "$3"; fail=1; fi
}
active() { "$SCRIPT" status >/dev/null 2>&1 && echo active || echo inactive; }
check "starts inactive" "$(active)" "inactive"
"$SCRIPT" add feral >/dev/null 2>&1
check "feral activates" "$(active)" "active"
check "src.feral marker set" "$([ -e "$GAMEMODE_STATE_DIR/src.feral" ] && echo y)" "y"
check "baseline captured" "$([ -e "$GAMEMODE_STATE_DIR/baseline.profile" ] && echo y)" "y"
"$SCRIPT" add manual >/dev/null 2>&1
check "manual keeps active" "$(active)" "active"
"$SCRIPT" del feral >/dev/null 2>&1
check "still active on 1 left" "$(active)" "active"
"$SCRIPT" del manual >/dev/null 2>&1
check "last del deactivates" "$(active)" "inactive"
check "baseline cleared" "$([ -e "$GAMEMODE_STATE_DIR/baseline.profile" ] && echo y || echo n)" "n"
"$SCRIPT" toggle >/dev/null 2>&1
check "toggle on activates" "$(active)" "active"
"$SCRIPT" toggle >/dev/null 2>&1
check "toggle off deactivates" "$(active)" "inactive"
"$SCRIPT" reset >/dev/null 2>&1
check "reset leaves inactive" "$(active)" "inactive"
exit $fail
- Step 2: Run the test to verify it fails
Run: bash scripts/tests/gamemode-session.test.sh
Expected: FAIL / non-zero (script gamemode-session.sh does not exist yet — bash: .../gamemode-session.sh: No such file).
- Step 3: Write the core script
Create scripts/gamemode-session.sh:
#!/bin/bash
# gamemode-session — compositor-level gamemode for niri.
# Reference-counted over two sources (feral, manual). Applies effects on the
# first active source (0->1) and reverts on the last (1->0).
# Spec: docs/superpowers/specs/2026-07-15-niri-gamemode-design.md
set -u
STATE_DIR="${GAMEMODE_STATE_DIR:-${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/gamemode}"
FAN_AUTO="${XDG_STATE_HOME:-$HOME/.local/state}/fan-profile-auto"
DRYRUN="${GAMEMODE_DRYRUN:-0}"
log() { printf 'gamemode: %s\n' "$*" >&2; }
run() { if [ "$DRYRUN" = 1 ]; then log "would: $*"; else "$@"; fi; }
is_active() {
[ -n "$(find "$STATE_DIR" -maxdepth 1 -name 'src.*' -print -quit 2>/dev/null)" ]
}
snapshot_baseline() {
mkdir -p "$STATE_DIR"
powerprofilesctl get 2>/dev/null > "$STATE_DIR/baseline.profile" || : > "$STATE_DIR/baseline.profile"
if pgrep -x waybar >/dev/null 2>&1; then echo 1; else echo 0; fi > "$STATE_DIR/baseline.waybar"
if [ -f "$FAN_AUTO" ]; then echo 1; else echo 0; fi > "$STATE_DIR/baseline.fanauto"
}
# --- effects (bodies filled in Task 2; dryrun-safe stubs for now) -------------
effect_idle_on() { run : "idle inhibit on"; }
effect_idle_off() { run : "idle inhibit off"; }
effect_dnd_on() { run : "dnd on"; }
effect_dnd_off() { run : "dnd off"; }
effect_perf_on() { run : "perf on"; }
effect_perf_off() { run : "perf off"; }
effect_waybar_on() { run : "waybar hide"; }
effect_waybar_off(){ run : "waybar restore"; }
apply_effects() { effect_idle_on; effect_dnd_on; effect_perf_on; effect_waybar_on; }
revert_effects() { effect_idle_off; effect_dnd_off; effect_perf_off; effect_waybar_off; }
# --- state machine ------------------------------------------------------------
cmd_add() {
local src="$1" was=0
is_active && was=1
mkdir -p "$STATE_DIR"
touch "$STATE_DIR/src.$src"
if [ "$was" = 0 ]; then
snapshot_baseline
apply_effects
log "activated (source: $src)"
else
log "already active; +source: $src"
fi
}
cmd_del() {
local src="$1"
rm -f "$STATE_DIR/src.$src"
if ! is_active; then
revert_effects
rm -f "$STATE_DIR"/baseline.* "$STATE_DIR/idle.pid"
log "deactivated (last source: $src)"
else
log "still active; -source: $src"
fi
}
cmd_toggle() {
if [ -e "$STATE_DIR/src.manual" ]; then cmd_del manual; else cmd_add manual; fi
}
cmd_status() { if is_active; then echo active; exit 0; else echo inactive; exit 1; fi; }
cmd_reset() {
revert_effects 2>/dev/null || true
rm -rf "$STATE_DIR"
log "reset"
}
case "${1:-}" in
add) [ -n "${2:-}" ] || { log "add needs a source"; exit 2; }; cmd_add "$2" ;;
del) [ -n "${2:-}" ] || { log "del needs a source"; exit 2; }; cmd_del "$2" ;;
toggle) cmd_toggle ;;
status) cmd_status ;;
reset) cmd_reset ;;
*) log "usage: gamemode-session {add|del <source>|toggle|status|reset}"; exit 2 ;;
esac
Make it executable: chmod +x scripts/gamemode-session.sh.
- Step 4: Run the test to verify it passes + shellcheck
Run: bash -n scripts/gamemode-session.sh && shellcheck -x scripts/gamemode-session.sh; bash scripts/tests/gamemode-session.test.sh
Expected: bash -n silent; shellcheck clean (or only style-level SC2086-type notes — fix any warnings); all ok - lines, exit 0.
- Step 5: Commit
cd ~/Documents/dotfiles
git add scripts/gamemode-session.sh scripts/tests/gamemode-session.test.sh
git commit -m "gamemode-session: reference-counted state machine core
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"
Task 2: Real effect bodies (idle / DND / power+fan / waybar)
Replace the eight stubbed effect functions with the real commands. The Task 1 state-machine test still passes unchanged (it runs in dryrun, so effect bodies only log).
Files:
- Modify:
scripts/gamemode-session.sh(the eighteffect_*functions)
Interfaces:
-
Consumes:
STATE_DIR,FAN_AUTO,DRYRUN,run(),log(), and baseline filesbaseline.profile/baseline.waybar/baseline.fanautowritten bysnapshot_baseline. -
Produces:
idle.pidfile holding the systemd-inhibit PID while active. -
Step 1: Replace the effect stubs
In scripts/gamemode-session.sh, replace the entire # --- effects stub block with:
# --- effects ------------------------------------------------------------------
effect_idle_on() {
if [ "$DRYRUN" = 1 ]; then log "would: systemd-inhibit idle"; return; fi
command -v systemd-inhibit >/dev/null 2>&1 || { log "no systemd-inhibit"; return; }
systemd-inhibit --what=idle --who=gamemode --why="gaming session" --mode=block \
sleep infinity >/dev/null 2>&1 &
echo $! > "$STATE_DIR/idle.pid"
}
effect_idle_off() {
local pid; pid=$(cat "$STATE_DIR/idle.pid" 2>/dev/null || echo "")
[ -n "$pid" ] && run kill "$pid"
rm -f "$STATE_DIR/idle.pid"
}
effect_dnd_on() { command -v makoctl >/dev/null 2>&1 && run makoctl mode -a do-not-disturb; }
effect_dnd_off() { command -v makoctl >/dev/null 2>&1 && run makoctl mode -r do-not-disturb; }
# maps a power profile to the fw-fanctrl strategy (mirrors fan-profile.sh)
fan_for() { case "$1" in power-saver) echo lazy;; balanced) echo medium;; performance) echo agile;; *) return 1;; esac; }
effect_perf_on() {
local base; base=$(cat "$STATE_DIR/baseline.profile" 2>/dev/null || echo "")
if [ -n "$base" ] && [ "$base" != performance ]; then
run powerprofilesctl set performance
run pkill -RTMIN+8 waybar
fi
if [ "$(cat "$STATE_DIR/baseline.fanauto" 2>/dev/null)" = 1 ]; then
run fw-fanctrl use agile
fi
}
effect_perf_off() {
local base; base=$(cat "$STATE_DIR/baseline.profile" 2>/dev/null || echo "")
if [ -n "$base" ] && [ "$base" != performance ]; then
run powerprofilesctl set "$base"
run pkill -RTMIN+8 waybar
fi
if [ -n "$base" ] && [ "$(cat "$STATE_DIR/baseline.fanauto" 2>/dev/null)" = 1 ]; then
local strat; strat=$(fan_for "$base") && run fw-fanctrl use "$strat"
fi
}
effect_waybar_on() { # hide
pgrep -x waybar >/dev/null 2>&1 && run pkill -x waybar
}
effect_waybar_off() { # restore if it was running at entry
[ "$(cat "$STATE_DIR/baseline.waybar" 2>/dev/null)" = 1 ] || return 0
if [ "$DRYRUN" = 1 ]; then log "would: relaunch waybar"; else setsid waybar >/dev/null 2>&1 & fi
}
- Step 2: Re-run the state-machine test (must still pass in dryrun)
Run: bash -n scripts/gamemode-session.sh && shellcheck -x scripts/gamemode-session.sh; bash scripts/tests/gamemode-session.test.sh
Expected: shellcheck clean; all ok -, exit 0. (Effects only log under dryrun, so the state machine is unaffected.)
- Step 3: Dryrun effect-ordering smoke (visual check of the "would:" log)
Run: GAMEMODE_STATE_DIR=$(mktemp -d) GAMEMODE_DRYRUN=1 bash scripts/gamemode-session.sh add feral 2>&1
Expected output includes, in order: would: systemd-inhibit idle, would: makoctl mode -a do-not-disturb, a would: powerprofilesctl set performance (only if your current profile isn't already performance) and/or would: fw-fanctrl use agile, would: pkill -x waybar, then activated (source: feral).
- Step 4: Commit
cd ~/Documents/dotfiles
git add scripts/gamemode-session.sh
git commit -m "gamemode-session: real effects (idle, DND, perf+fan, waybar)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"
Task 3: mako do-not-disturb mode config
mako currently runs on defaults with no config file. Add a tracked config that folds in the current visible settings and adds the do-not-disturb mode so effect_dnd_* actually suppresses toasts.
Files:
- Create:
mako/config(dotfiles) → deployed to~/.config/mako/config
Interfaces:
-
Consumes:
makoctl mode -a/-r do-not-disturbfrom Task 2. -
Produces: a
[mode=do-not-disturb]block withinvisible=1. -
Step 1: Write the mako config
Create mako/config:
background-color=#1d1f21
text-color=#c5c8c6
border-size=2
border-color=#81a2be
default-timeout=4000
[mode=do-not-disturb]
invisible=1
- Step 2: Deploy + reload mako
mkdir -p ~/.config/mako
ln -sf ~/Documents/dotfiles/mako/config ~/.config/mako/config # match existing dotfile symlink style
makoctl reload
- Step 3: Verify DND suppresses, then restores
Run:
makoctl mode -a do-not-disturb; makoctl mode # expect list to include: do-not-disturb
notify-send "gamemode test" "should NOT appear" # no toast while DND active
makoctl mode -r do-not-disturb; makoctl mode # expect: default only
notify-send "gamemode test" "SHOULD appear" # toast appears
Expected: after -a, makoctl mode lists do-not-disturb and the first notification does not show; after -r, list is back to default and the second notification shows. (If notify-send is missing, install libnotify or skip — the mode-list assertion is the load-bearing check.)
- Step 4: Commit
cd ~/Documents/dotfiles
git add mako/config
git commit -m "mako: config with do-not-disturb mode for gamemode
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"
Task 4: Feral gamemode hooks (gamemode.ini)
Wire Feral gamemoded's custom start/end hooks to the script so gamemode-aware games trigger it automatically.
Files:
- Create:
gamemode.ini(dotfiles) → deployed to~/.config/gamemode.ini
Interfaces:
-
Consumes:
gamemode-session add feral/del feralfrom Tasks 1–2. -
Step 1: Write
gamemode.ini
Create gamemode.ini:
[custom]
start=/home/alex/.local/bin/gamemode-session add feral
end=/home/alex/.local/bin/gamemode-session del feral
- Step 2: Deploy
ln -sf ~/Documents/dotfiles/gamemode.ini ~/.config/gamemode.ini
- Step 3: Verify Feral reads the hooks
Run: gamemoderun gamemode-session status; echo "exit=$?"
Expected: while gamemoderun holds the game session, the custom start hook has fired add feral, so gamemode-session status prints active (exit 0). When gamemoderun exits it fires end → del feral. Immediately after, gamemode-session status prints inactive (exit 1). (If it stays active, run gamemode-session reset and check journalctl --user -u gamemoded / the gamemode.ini path.)
- Step 4: Commit
cd ~/Documents/dotfiles
git add gamemode.ini
git commit -m "gamemode.ini: Feral custom hooks drive gamemode-session
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"
Task 5: niri config — keybind + remove dead VRR rules
Add the Mod+G toggle and remove the three no-op VRR rules the review found (panel has no VRR).
Files:
- Modify:
niri/config.kdl
Interfaces:
-
Consumes:
gamemode-session togglefrom Tasks 1–2. -
Step 1: Add the keybind
In niri/config.kdl, inside the binds { ... } block, near the other spawn binds (after the Mod+Shift+B line), add:
Mod+G { spawn "gamemode-session" "toggle"; }
- Step 2: Remove the dead VRR rules
In niri/config.kdl:
a) In the steam_app_ window-rule, delete the line variable-refresh-rate true and change the comment to note the VRR removal. The rule becomes:
// Fullscreen games: no border, open fullscreen.
// (Re-add `variable-refresh-rate true` here if a VRR-capable external
// monitor is ever attached — the internal eDP-1 panel has no VRR.)
window-rule {
match app-id="steam_app_"
open-fullscreen true
border {
off
}
focus-ring {
off
}
}
b) Delete this entire rule (it wrongly targets every focused window and is a no-op here):
// Generic fullscreen request (any app asking to go fullscreen)
window-rule {
match is-focused=true
variable-refresh-rate true
}
- Step 3: Validate niri config
Run: niri validate -c ~/.config/niri/config.kdl
Expected: Config is valid (or niri's success message). Fix any parse error before continuing.
- Step 4: Verify the bind live (optional if in a niri session)
Run: niri msg action do-nothing 2>/dev/null; grep -n "Mod+G" ~/.config/niri/config.kdl
Expected: the Mod+G line is present. After niri reloads the config (niri hot-reloads on save), pressing Mod+G toggles gamemode; confirm with gamemode-session status.
- Step 5: Commit
cd ~/Documents/dotfiles
git add niri/config.kdl
git commit -m "niri: Mod+G gamemode toggle; drop dead VRR rules
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"
Task 6: Wiring + live end-to-end smoke
Create the ~/.local/bin symlink for the script (matching every other script), update install.sh if it enumerates them, then run one real activate/deactivate cycle and assert observable effects revert.
Files:
- Create: symlink
~/.local/bin/gamemode-session→~/Documents/dotfiles/scripts/gamemode-session.sh - Modify:
install.sh(only if it lists script/config symlinks; otherwise no change)
Interfaces:
-
Consumes: everything from Tasks 1–5.
-
Step 1: Create the bin symlink
ln -sf ~/Documents/dotfiles/scripts/gamemode-session.sh ~/.local/bin/gamemode-session
gamemode-session status; echo "exit=$?" # expect: inactive / exit=1
- Step 2: Wire install.sh if applicable
Inspect install.sh for where existing scripts/configs get symlinked (e.g. a loop over scripts/*.sh, or explicit ln -sf lines). If found, add gamemode-session, ~/.config/gamemode.ini, and ~/.config/mako/config to the same mechanism. If install.sh does NOT enumerate these (the existing bin symlinks appear to be created manually), skip this step and note it in the commit.
Run: grep -nE "ln -s|scripts/|\.local/bin|\.config" install.sh | head
Expected: shows the deploy mechanism (or nothing → manual, skip).
- Step 3: Live end-to-end — capture baseline
echo "profile: $(powerprofilesctl get)"
pgrep -x waybar >/dev/null && echo "waybar: up" || echo "waybar: down"
makoctl mode
Record these; the cycle must return to exactly this state.
- Step 4: Activate and assert effects applied
gamemode-session add manual
sleep 1
gamemode-session status; echo "status_exit=$?" # active / 0
systemd-inhibit --list | grep -q gamemode && echo "idle: inhibited" # idle: inhibited
makoctl mode | grep -q do-not-disturb && echo "dnd: on" # dnd: on
echo "profile now: $(powerprofilesctl get)" # performance (unless baseline already performance)
pgrep -x waybar >/dev/null && echo "waybar: up" || echo "waybar: down" # down
Expected: status active; idle inhibited (a gamemode entry in the list); DND on; profile is performance; waybar down.
- Step 5: Deactivate and assert full revert
gamemode-session del manual
sleep 2
gamemode-session status; echo "status_exit=$?" # inactive / 1
systemd-inhibit --list | grep -q gamemode && echo "idle: STILL inhibited (BUG)" || echo "idle: released"
makoctl mode | grep -q do-not-disturb && echo "dnd: STILL on (BUG)" || echo "dnd: off"
echo "profile now: $(powerprofilesctl get)" # back to Step 3 value
pgrep -x waybar >/dev/null && echo "waybar: up" || echo "waybar: down" # up (matches Step 3)
Expected: status inactive; idle released; DND off; profile matches the Step 3 baseline; waybar back up. If any line reports a BUG or a mismatch, run gamemode-session reset to force-clean, then debug the corresponding effect_*_off before proceeding.
- Step 6: Manual verification note (idle timeout)
The 5-minute blank-suppression can't be asserted in seconds. Manually verify once: activate gamemode, leave the machine idle past 5 minutes (no input), confirm the screen does NOT blank; then del/toggle off and confirm hypridle resumes (screen blanks on the next idle window). Record the result. If it DOES blank while active, hypridle isn't honoring the systemd idle inhibitor on this build — fall back to a Wayland idle-inhibitor helper (documented follow-up), but the systemd path matches the current hypridle config intent.
- Step 7: Commit
cd ~/Documents/dotfiles
git add -A install.sh # only if changed; otherwise omit
git commit -m "gamemode: wire bin symlink + live smoke verified
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>" # allow empty note if only the symlink (untracked) changed
(The ~/.local/bin/gamemode-session symlink lives outside the repo — like the other script symlinks — so it isn't committed; note that it was created.)
Self-Review
Spec coverage:
- Reference-counted two-source state machine → Task 1. ✓
- Idle inhibit / DND / performance+fan / hide waybar effects, each with exact-baseline revert → Task 2. ✓
- Baseline snapshot (profile, waybar, fanauto, idle.pid) → Task 1 (
snapshot_baseline) + Task 2 (idle.pid). ✓ - "only change profile if baseline != performance; only restore if changed" → Task 2
effect_perf_on/off. ✓ - mako
[mode=do-not-disturb]config → Task 3. ✓ gamemode.iniFeral hooks → Task 4. ✓- niri
Mod+Gbind + removal of 3 dead VRR rules (incl.is-focused=true) + breadcrumb comment → Task 5. ✓ resetescape hatch → Task 1 dispatch + used in Task 6 debugging. ✓statussubcommand for future waybar module → Task 1. ✓- Script naming
gamemode-session,scripts/<name>.sh→~/.local/bin/<name>convention → Global Constraints + Task 6. ✓ - Steam
gamemoderun %command%usage → user-side (documented in spec Usage; not a code task), reflected in Task 4 verification viagamemoderun. ✓
Placeholder scan: No TBD/TODO; every code step shows full content; no "add error handling" hand-waves (guards are written out). ✓
Type/name consistency: effect_idle_on/off, effect_dnd_on/off, effect_perf_on/off, effect_waybar_on/off, apply_effects, revert_effects, snapshot_baseline, is_active, fan_for, and the env seams GAMEMODE_STATE_DIR/GAMEMODE_DRYRUN are named identically across Tasks 1, 2, and 6. Baseline filenames baseline.profile/baseline.waybar/baseline.fanauto and idle.pid/src.<source> are consistent throughout. ✓