--- name: linux os: lnx disable-model-invocation: true description: "Use for Linux system diagnosis: host state, systemd/journal, services, boot, permissions, devices, network, root escalation. For user-owned config use linux-userland." --- # Linux Safe Linux diagnosis for agents without root. **Boundary:** read system state; do not mutate system config. For user-owned config under `$HOME`, also use `linux-userland`. ## Non-Negotiables - No `sudo`, `su`, `doas`, `pkexec`, package manager install/remove, system-service mutation, `/etc` edits, kernel/sysctl changes, or device writes from the agent. - User-service changes follow [linux-userland](../linux-userland/SKILL.md); the system-service ban does not cover them. - Read-only probes first. Prefer commands with `--no-pager`, `--full`, bounded output, and explicit units/time ranges. - Prefer installed truth: `man`, `--help`, distro files. Web docs may not match host version. - Redact secrets from env, tokens, key files, URLs, logs, and command output. - If root is required, explain why and give a copy-paste command or script for the human to run. ## Workflow 1. Classify: user config? → `linux-userland`. system state/root/service/device/package? → continue here. 2. Inventory host facts before hypotheses. 3. Inspect installed docs for exact command/config behavior. 4. Gather bounded logs/status. 5. State root cause confidence + evidence. If changing system state is needed, escalate to human. ## Read-Only Inventory ```bash uname -a cat /etc/os-release id printf 'SHELL=%s\n' "$SHELL" getent passwd "$(id -un)" systemctl --version 2>/dev/null || true loginctl show-user "$(id -un)" 2>/dev/null || true ``` ## Installed Documentation ```bash MANWIDTH=100 MANPAGER=cat man systemctl | col -b | head -120 MANWIDTH=100 MANPAGER=cat man 5 systemd.service | col -b | rg -n 'ExecStart|Type=|Restart=' man -k 'journal|systemd|network' --help 2>&1 | head -80 ``` Use section numbers: `man 1 command`, `man 5 config-file`, `man 7 topic`, `man 8 admin-command`. ## systemd Diagnosis System manager is OS-level. User manager is per-user; see `linux-userland` for editing user units. ```bash systemctl --no-pager --full status UNIT systemctl --no-pager --full list-units --failed systemctl show UNIT -p LoadState -p ActiveState -p SubState -p Result -p ExecMainStatus systemctl cat UNIT systemd-analyze verify /path/to/unit.service ``` `systemctl status` is for humans. `systemctl show` is for parseable properties. ## Network Read-Only Probes ```bash ip addr ip route resolvectl status 2>/dev/null || true ``` ## journalctl Diagnosis Always bound logs: ```bash journalctl -b --no-pager -n 200 journalctl -b -u UNIT --no-pager --full -n 200 journalctl -b --since '1 hour ago' -p warning..alert --no-pager journalctl --list-boots --no-pager ``` Unprivileged users may not read system journal. If denied, report the permission boundary; do not try `sudo`. ## Root Escalation Escalate only after read-only evidence shows user privileges are insufficient. Never execute elevation. Follow the global command-handoff policy. Prefer a direct launch with no shell syntax: ```text sudo systemctl status UNIT --no-pager --full ``` For multi-step or shell-sensitive actions, write a reviewed POSIX shell script in a user-owned path and provide a launch command: ```text sudo sh /tmp/pi-root-action.sh ``` Write the script to a path without spaces, e.g. `/tmp/pi-root-action.sh` or `$HOME/.cache/pi-root-action.sh`. Include: - what it changes - pre-checks - backup path when editing - rollback command - verification command ## Common Mistakes | Mistake | Fix | | ------------------------------ | --------------------------------------- | | Running unbounded `journalctl` | Add `-b`, `-n`, `--since`, `--no-pager` | | Treating web docs as exact | Check installed `man`/`--help` | | Using `sudo` from agent | Stop; give human command/script | | Editing `/etc` directly | Escalate with backup + rollback | | Guessing before inventory | Collect host facts + logs first |