# Linux Triage > Paste the console output a misbehaving Linux host just gave you and work it in one sitting: name > the fault chain, decode the access denials, recover the package state, write the runbook. URL: https://linux-triage.skillsafe.ai/ API docs: https://linux-triage.skillsafe.ai/api.html Token panel: https://linux-triage.skillsafe.ai/tokens.html ## What it is for One work object: **the console output from a Linux host that is misbehaving**. A `systemctl status` block, a `journalctl` tail, the kernel ring buffer, a failed `apt`/`dnf`/`pacman` transaction, the SELinux AVC or AppArmor DENIED records that came with it, and whatever `df` output got pasted along the way — in whatever order the operator copied them. It is deliberately NOT a code reviewer. Nothing here reads a unit file, a manifest, a Dockerfile or a shell script you wrote. It reads what the machine *emitted*, which is a different artifact with a different grammar and a different kind of answer. ## The four lanes | Lane (`task`) | Question | Verdicts | | --- | --- | --- | | `triage` | What broke, in order, with the line that proves it? | `root-cause-identified`, `narrowed`, `insufficient-evidence` | | `denial` | What did SELinux or AppArmor refuse, and what is the narrowest change? | `policy-change`, `relabel`, `not-the-cause`, `no-denials-present` | | `package` | What did the transaction leave behind, and how is it recovered? | `recoverable-in-place`, `needs-intervention`, `no-package-failure` | | `runbook` | What is the ordered fix, with its rollback and its stop condition? | `ready-to-run`, `needs-approval`, `blocked-on-evidence` | Each lane's result carries a button that hands its output into the next lane, so the sitting runs `triage -> denial and/or package -> runbook` without re-pasting anything. ## What runs in your browser, free, before anything is sent This is the larger half of the app and it costs nothing: - **Masking, first.** Host names, IPv4 and IPv6 addresses, MAC addresses, UUIDs, mail addresses, account names in home paths, and container ids on container-related lines are replaced with stable pseudonyms (`HOST-1`, `IP-2`, `USER-1`). Aliases go with them, so an FQDN and its short form get the same pseudonym. The scan only ever sees masked text, so no field it produces can carry an identity by construction. You can add your own terms. - **Line typing** against six fixed grammars: RFC 3164 syslog, journalctl ISO, journalctl JSON, the kernel ring buffer, `systemctl status` blocks, and the audit record format. - **The unit timeline**, with restart-loop detection from the **median** gap between starts, so one long pause before the loop began cannot hide it. - **Exit-code decoding** against systemd's own launch-failure table (200–243) as well as the process table, because `status=203/EXEC` means systemd never ran your binary and `status=1` means your binary decided to exit — the most consequential misreading of a status block. - **Denial parsing** into subject type, target type, class and permission, including `permissive=1`, which means the denial was logged and then allowed. - **Package transaction parsing** per manager (apt, dnf, pacman), inferred from the grammar that matched rather than from the distribution guess. - **Arithmetic that is read, not just parsed.** Every `df` Use% is recomputed from the size and used columns beside it and a wide gap is flagged as byte output pasted together with inode output. The kernel's kB memory figures and systemd's binary `Memory:` figures are converted to bytes before either is compared with the other. - **About twenty lints, every one tri-state.** A finding with a line behind it is `definite`. A finding that rests on something being *absent* from the paste is `unknown` — because a paste is an excerpt, and "no AVC records here" is a fact about the excerpt, never about the machine. The downgrade is enforced centrally: a rule that tries to set its own state throws. ## Grounding The scan's facts go into every run, and the model has to return one `coverage_check` entry per flag. The result page shows every flag beside whether the reply actually addressed it, so a flag the model ignored is visible rather than lost. ## Cost, privacy and limits - The in-browser scan, `estimate`, sign-in and the three bundled examples cost nothing. Every example ships a saved model run that replays through the real render path, so you can see a whole lane without an account and without a credit. - Running a lane is metered against your SkillSafe balance. The header shows the reservation, not the price; you are charged what the run uses, usually far less. - Files you drop are read with `FileReader` in the browser and are never uploaded. - If any masked value survives anywhere in the assembled request, the run is **blocked**, not merely flagged. - Run history is saved to a declared collection on your SkillSafe account and mirrored in this browser. What is stored is the masked text, not the original. - Linux Triage reads an excerpt. It cannot see your machine. Read every command it proposes before you run it. ## Source skills Derived from the Linux triage skills in `github/awesome-copilot`: - `@github/debian-linux-triage` — apt and dpkg, systemd, AppArmor - `@github/centos-linux-triage` — RHEL-compatible tooling, SELinux, firewalld - `@github/fedora-linux-triage` — dnf, systemd, SELinux - `@github/arch-linux-triage` — pacman and rolling-release practice ## Programmatic use Base URL `https://api.skillsafe.ai/v1/app-api`, app slug `linux-triage`. The run input is a JSON object whose first field is `task` (one of `triage`, `denial`, `package`, `runbook`) and whose main field is `console_output`. The reply is a single JSON object with the same envelope on every lane: `lane`, `title`, `headline`, `verdict`, `confidence`, `summary`, `chain[]`, `steps[]`, `findings[]`, `artifact`, `coverage_check[]`, `questions[]`. Full worked examples per lane, in eight languages, are at /api.html.