--- name: linux-userland os: lnx disable-model-invocation: true description: "Use for Linux user-owned config and environment: HOME/XDG paths, shell, PATH, dotfiles, user systemd, desktop/session settings, caches, state dirs." --- # Linux Userland Linux config work inside the user's ownership boundary. **Boundary:** operate under `$HOME` and user managers only. If a fix needs `/etc`, `/usr`, `/var/lib`, packages, kernel settings, devices, or `sudo`, stop and use `linux` escalation. ## Workflow 1. Identify app/tool, config file discovery rules, and current user/session. 2. Resolve XDG paths; do not hard-code `~/.config` if env overrides exist. 3. Read installed docs: `man`, `--help`, app config docs in repo/package. 4. Inspect current config/env/state. 5. Back up before edits; make minimal change. 6. Validate with app-specific parser/check command. 7. Reload/restart only user-owned process/service. Provide rollback. ## XDG Paths | Purpose | Env | Default | | ------------------ | ----------------- | -------------------- | | Config | `XDG_CONFIG_HOME` | `$HOME/.config` | | Data | `XDG_DATA_HOME` | `$HOME/.local/share` | | State/logs/history | `XDG_STATE_HOME` | `$HOME/.local/state` | | Cache | `XDG_CACHE_HOME` | `$HOME/.cache` | | Runtime sockets | `XDG_RUNTIME_DIR` | set by login/session | Probe safely: ```bash printf 'HOME=%s\nXDG_CONFIG_HOME=%s\nXDG_DATA_HOME=%s\nXDG_STATE_HOME=%s\nXDG_CACHE_HOME=%s\nXDG_RUNTIME_DIR=%s\n' \ "$HOME" "${XDG_CONFIG_HOME:-$HOME/.config}" "${XDG_DATA_HOME:-$HOME/.local/share}" \ "${XDG_STATE_HOME:-$HOME/.local/state}" "${XDG_CACHE_HOME:-$HOME/.cache}" "${XDG_RUNTIME_DIR:-}" ``` XDG env vars must be absolute paths to be valid. ## Shell + Environment Diagnosis The agent's tool shell may not equal the user's interactive shell. Detect before giving syntax: ```bash printf 'SHELL=%s\n' "$SHELL" getent passwd "$(id -un)" | awk -F: '{print "login_shell=" $7}' printf 'PATH=%s\n' "$PATH" | tr ':' '\n' ``` Startup files by shell: | Shell | Common user files | PATH/export syntax | | ------- | -------------------------------------------- | ----------------------------------------- | | bash | `~/.bashrc`, `~/.bash_profile`, `~/.profile` | `export NAME=value` | | zsh | `~/.zshrc`, `~/.zprofile`, `~/.zshenv` | `export NAME=value` | | fish | `~/.config/fish/config.fish` | `set -gx NAME value`; `fish_add_path DIR` | | nushell | `~/.config/nushell/env.nu`, `config.nu` | `$env.NAME = value` | Prefer editing the shell's config file over emitting complex copy-paste snippets. If root is needed, do not craft fish/nushell sudo heredocs; use `linux` script escalation. ## User systemd Units User units live primarily in `$XDG_CONFIG_HOME/systemd/user` (default `~/.config/systemd/user`). Read: ```bash systemctl --user --no-pager --full list-units --failed systemctl --user --no-pager --full status UNIT systemctl --user show UNIT -p LoadState -p ActiveState -p SubState -p Result -p ExecMainStatus systemctl --user cat UNIT journalctl --user-unit UNIT -b --no-pager --full -n 200 systemd-analyze --user verify "${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/UNIT" ``` After editing a user unit: ```bash systemctl --user daemon-reload systemctl --user status UNIT --no-pager --full journalctl --user-unit UNIT -b --no-pager --full -n 100 ``` Restart only if the user asked for restart or the service was active before edit: ```bash systemctl --user restart UNIT ``` Use `enable --now` only when the user asked for autostart. ## Safe Edit Pattern For an existing regular config file, resolve symlinks first and confirm the target is inside the authorized user-owned boundary. Edit and restore the resolved target, leaving the original symlink intact. A `cp -a` backup of a symlink copies only the link, not a content snapshot. ```bash file=$(realpath -e -- /path/to/file) || exit 1 [ -f "$file" ] || exit 1 backup=$(mktemp -- "$file.bak.XXXXXX") || exit 1 cp -p -- "$file" "$backup" || exit 1 # edit "$file" # run validator/reload # rollback if bad: cp -p -- "$backup" "$file" ``` Stop on resolution or backup failure; do not create a missing symlink target implicitly. Validation examples: - systemd user unit: `systemd-analyze --user verify FILE` - shell config: run the shell parser if available (`bash -n FILE`, `zsh -n FILE`); fish/nushell need shell-specific checks. - app config: use the app's documented `check`, `validate`, `doctor`, or dry-run command. ## Common Mistakes | Mistake | Fix | | --------------------------------- | -------------------------------------------------------- | | Editing `/etc` from userland task | Stop; use `linux` escalation | | Assuming bash syntax | Detect shell; prefer editing files or POSIX `sh` scripts | | Ignoring XDG overrides | Resolve env/defaults first | | Restarting system service | Only use `systemctl --user`; escalate otherwise | | Changing config without rollback | Backup + validate + rollback command |