<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 7sh1d0w7x</title>
    <description>The latest articles on DEV Community by 7sh1d0w7x (@7sh1d0w7x).</description>
    <link>https://dev.to/7sh1d0w7x</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4155454%2F417c4d9d-f862-458a-8aa7-1de6a90d7b84.png</url>
      <title>DEV Community: 7sh1d0w7x</title>
      <link>https://dev.to/7sh1d0w7x</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/7sh1d0w7x"/>
    <language>en</language>
    <item>
      <title>The command a tool tells you to run has to be correct for *your* machine</title>
      <dc:creator>7sh1d0w7x</dc:creator>
      <pubDate>Sun, 18 Oct 2026 14:14:18 +0000</pubDate>
      <link>https://dev.to/7sh1d0w7x/the-command-a-tool-tells-you-to-run-has-to-be-correct-for-your-machine-48bh</link>
      <guid>https://dev.to/7sh1d0w7x/the-command-a-tool-tells-you-to-run-has-to-be-correct-for-your-machine-48bh</guid>
      <description>&lt;p&gt;A health checker gave a Bazzite user a &lt;code&gt;dnf&lt;/code&gt; command.&lt;br&gt;
Bazzite has no writable root. Here is what I found across five distro families,&lt;br&gt;
and why "advice" is code.&lt;/p&gt;

&lt;p&gt;A user sent me this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Review both with \&lt;/code&gt;du -sh ~/.cache/* | sort -rh | head -20&lt;code&gt;…&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Two things were wrong with that line, and they were wrong in different ways.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The obvious one:&lt;/strong&gt; on their machine it errored. &lt;code&gt;~/.cache/*&lt;/code&gt; expands a glob —&lt;br&gt;
fine with 20 entries, "argument list too long" with 20,000, and it silently&lt;br&gt;
skips hidden entries. The second half, &lt;code&gt;~/.var/app/*/cache&lt;/code&gt;, stays &lt;em&gt;literal&lt;/em&gt;&lt;br&gt;
when no Flatpak app exists, so &lt;code&gt;du&lt;/code&gt; tries to read a directory called &lt;code&gt;*&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The one that took longer to see:&lt;/strong&gt; the same tool was telling people on&lt;br&gt;
Fedora Atomic desktops to run &lt;code&gt;sudo dnf install akmod-nvidia&lt;/code&gt;. On Bazzite,&lt;br&gt;
Silverblue and Kinoite the root filesystem is read-only and the rpm database is&lt;br&gt;
a bind mount. &lt;code&gt;dnf&lt;/code&gt; does not install anything there. The NVIDIA driver is &lt;em&gt;in&lt;br&gt;
the image&lt;/em&gt; — you switch images by rebasing. There is no package cache to clean.&lt;br&gt;
The kernel is not a removable package. &lt;code&gt;grub2-mkconfig&lt;/code&gt; is not how boot entries&lt;br&gt;
are made.&lt;/p&gt;

&lt;p&gt;None of that was a bug in the &lt;em&gt;checks&lt;/em&gt;. The checks were right. It was the&lt;br&gt;
&lt;strong&gt;advice&lt;/strong&gt; that was wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advice is code
&lt;/h3&gt;

&lt;p&gt;Every "recommended next step" is a string like any other, and it was written by&lt;br&gt;
one person on one distribution. If you write &lt;code&gt;sudo dnf install …&lt;/code&gt; at 2am while&lt;br&gt;
testing on Fedora, it ships to Arch, Alpine, Void and openSUSE.&lt;/p&gt;

&lt;p&gt;So I treated the advice as code and went looking for every place it was&lt;br&gt;
hard-coded. Two patterns came out:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Hard-coded invocations.&lt;/strong&gt; &lt;code&gt;"Install the driver (e.g. \&lt;/code&gt;sudo dnf install
akmod-nvidia&lt;code&gt;on Fedora/Bazzite)"&lt;/code&gt; — with Bazzite &lt;em&gt;named in the source&lt;/em&gt;,
which is how I knew nobody had tested it there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A wrong mental model.&lt;/strong&gt; "Clean the package cache" is meaningless on an
image-based system. The command isn't wrong, the &lt;em&gt;sentence&lt;/em&gt; is.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What the five families actually need
&lt;/h3&gt;

&lt;p&gt;I read the documentation for each family instead of trusting memory. A few&lt;br&gt;
things surprised me:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Fedora Atomic&lt;/th&gt;
&lt;th&gt;Classic Fedora&lt;/th&gt;
&lt;th&gt;Debian&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;install a package&lt;/td&gt;
&lt;td&gt;last resort; &lt;code&gt;rpm-ostree install&lt;/code&gt;, needs reboot&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dnf install&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;apt install&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;install NVIDIA&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;not a package&lt;/strong&gt; — rebase to the &lt;code&gt;-nvidia&lt;/code&gt; image&lt;/td&gt;
&lt;td&gt;RPM Fusion + &lt;code&gt;akmod-nvidia&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;contrib non-free&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;clear package cache&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;rpm-ostree cleanup -m&lt;/code&gt; (repodata); there is no dnf cache&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dnf clean all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;apt clean&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;remove old kernels&lt;/td&gt;
&lt;td&gt;nothing to remove — the kernel ships with the image&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dnf remove --oldinstallonly&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;apt autoremove --purge&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;regenerate GRUB&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;don't&lt;/strong&gt; — &lt;code&gt;rpm-ostree kargs&lt;/code&gt; / &lt;code&gt;ujust configure-grub&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;grub2-mkconfig&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;update-grub&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And beyond the package managers: &lt;strong&gt;Alpine and Gentoo run OpenRC, Void runs&lt;br&gt;
runit.&lt;/strong&gt; Telling those users to run &lt;code&gt;systemctl&lt;/code&gt; is not a typo, it's a different&lt;br&gt;
init system. They get &lt;code&gt;rc-service&lt;/code&gt; and &lt;code&gt;sv&lt;/code&gt; now.&lt;/p&gt;

&lt;h3&gt;
  
  
  The fix, in three parts
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;One source of truth.&lt;/strong&gt; &lt;code&gt;pkgInstall(dist, pkg)&lt;/code&gt; already existed; the
offenders had bypassed it. Now there are siblings — &lt;code&gt;pkgCacheClean&lt;/code&gt;,
&lt;code&gt;oldKernelClean&lt;/code&gt;, &lt;code&gt;bootloaderRefresh&lt;/code&gt;, &lt;code&gt;svcCmd&lt;/code&gt;, &lt;code&gt;svcLogs&lt;/code&gt;, &lt;code&gt;hasTimers&lt;/code&gt; —
and detection gained an &lt;code&gt;init&lt;/code&gt; field (&lt;code&gt;systemd&lt;/code&gt; / &lt;code&gt;openrc&lt;/code&gt; / &lt;code&gt;runit&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Say when the concept doesn't apply.&lt;/strong&gt; On an image-based system, "remove old
kernels" is answered with &lt;em&gt;there is nothing to remove, and here is why&lt;/em&gt;. A
&lt;code&gt;null&lt;/code&gt; is more honest than a plausible command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test the invariants.&lt;/strong&gt; There is now a test that reads every command the
checks hand to the runner — 145 call sites — and fails on &lt;code&gt;sudo&lt;/code&gt;, on a
mutating verb, on a service manager told to act, or on a package manager in a
non-query mode. The tool's promise is "read-only, and it never changes
anything"; that should not be a sentence in a README, it should be a test
that fails.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What I'd take away
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;If your tool prints commands, your commands are an API.&lt;/strong&gt; They run on
machines you have never seen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"It works on my distro" is a distribution problem, not an edge case.&lt;/strong&gt;
Fedora, Debian and Arch are maybe half your users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Naming a distro in a string is an admission.&lt;/strong&gt; &lt;code&gt;(Fedora/Bazzite)&lt;/code&gt; in a fix
means nobody ran it on Bazzite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A wrong command is worse than no command.&lt;/strong&gt; "Use your distribution's
package manager" is a useless sentence, and it is still better than
&lt;code&gt;sudo dnf install&lt;/code&gt; on a machine where that fails.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Linux Doctor is a read-only health checker for Linux: it explains every finding&lt;br&gt;
and gives the exact command that fixes it. 0.8.0 also brings a new interface.&lt;br&gt;
Free and open source: &lt;a href="https://github.com/7sh1d0w7x/linux-doctor" rel="noopener noreferrer"&gt;https://github.com/7sh1d0w7x/linux-doctor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you run it on a distro I haven't covered, I'd like the report — especially&lt;br&gt;
if the advice is wrong. That is how this post happened.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cli</category>
      <category>devops</category>
      <category>linux</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Linux Doctor, heal thyself: 20 ways my Linux health checker was wrong</title>
      <dc:creator>7sh1d0w7x</dc:creator>
      <pubDate>Thu, 01 Oct 2026 17:22:03 +0000</pubDate>
      <link>https://dev.to/7sh1d0w7x/linux-doctor-heal-thyself-20-ways-my-linux-health-checker-was-wrong-1b2a</link>
      <guid>https://dev.to/7sh1d0w7x/linux-doctor-heal-thyself-20-ways-my-linux-health-checker-was-wrong-1b2a</guid>
      <description>&lt;p&gt;A diagnostic tool has exactly one job: tell the truth about the machine in&lt;br&gt;
front of it. So when I built &lt;strong&gt;Linux Doctor&lt;/strong&gt; — a read-only checker that&lt;br&gt;
reports what is wrong and &lt;em&gt;prints&lt;/em&gt; the fix without ever running it — I did the&lt;br&gt;
thing a doctor dreads. I audited it against reality: five distro families,&lt;br&gt;
minimal container images, and machines that had been running for years.&lt;/p&gt;

&lt;p&gt;It lied about twenty times. None of them were exotic. Every one is a class of&lt;br&gt;
bug you can hit in any script that reads the output of system tools.&lt;/p&gt;

&lt;p&gt;Here they are, grouped by what they teach.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. A pipeline exits with the status of its &lt;em&gt;last&lt;/em&gt; command
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-P&lt;/span&gt; /boot | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 1     &lt;span class="c"&gt;# a failed df looks successful&lt;/span&gt;
journalctl &lt;span class="nt"&gt;-p&lt;/span&gt; err | &lt;span class="nb"&gt;grep &lt;/span&gt;MCE &lt;span class="c"&gt;# grep exits 1 when nothing matches&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;boot&lt;/code&gt; check read &lt;code&gt;/boot&lt;/code&gt;'s usage through &lt;code&gt;tail&lt;/code&gt;. If &lt;code&gt;df&lt;/code&gt; failed, the exit&lt;br&gt;
status still belonged to &lt;code&gt;tail&lt;/code&gt;, which succeeded — so a failed probe looked&lt;br&gt;
like a good one.&lt;/p&gt;

&lt;p&gt;Worse was &lt;code&gt;hardware&lt;/code&gt;. It used the exit status of &lt;code&gt;journalctl … | grep …&lt;/code&gt; as its&lt;br&gt;
&lt;em&gt;readability&lt;/em&gt; gate. But &lt;code&gt;grep&lt;/code&gt; exits &lt;code&gt;1&lt;/code&gt; when there is &lt;strong&gt;nothing to match&lt;/strong&gt; —&lt;br&gt;
so "no hardware errors" (good news) was read as "I could not read the log", and&lt;br&gt;
the check stayed silent on a healthy machine instead of saying "No hardware&lt;br&gt;
errors logged". A benign EDAC banner made &lt;code&gt;grep&lt;/code&gt; exit &lt;code&gt;0&lt;/code&gt; on my own box, which&lt;br&gt;
hid the bug for weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; never gate readability on a pipeline's status. Take the raw output&lt;br&gt;
and decide in code.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. "Nothing found" and "the command is missing" are not the same
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Minimal Debian, Fedora and Ubuntu images do not ship &lt;code&gt;ip&lt;/code&gt; (iproute2). The
probe's &lt;em&gt;failure&lt;/em&gt; was read as an empty route table — a medium
&lt;strong&gt;"No default network route"&lt;/strong&gt; on a machine with a perfectly good route.&lt;/li&gt;
&lt;li&gt;Minimal openSUSE has no &lt;code&gt;awk&lt;/code&gt;. &lt;code&gt;zypper … | awk&lt;/code&gt; produced nothing, so
Tumbleweed reported &lt;strong&gt;"System is up to date"&lt;/strong&gt; with thirteen lines of updates
on screen.&lt;/li&gt;
&lt;li&gt;The engine's own &lt;code&gt;run()&lt;/code&gt; only flagged a command as &lt;em&gt;missing&lt;/em&gt; when the &lt;strong&gt;shell
itself&lt;/strong&gt; was absent — which never happens. A missing tool exits &lt;code&gt;127&lt;/code&gt;
&lt;em&gt;through&lt;/em&gt; the shell. So every check that gated a "could not check" skip on
&lt;code&gt;missing&lt;/code&gt; stayed silent, and a minimal image scored as if those checks had
passed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; distinguish &lt;em&gt;"the tool answered"&lt;/em&gt; from &lt;em&gt;"the tool isn't there."&lt;/em&gt;&lt;br&gt;
Exit &lt;code&gt;127&lt;/code&gt; is the tell.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Success messages contain the words you search for
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;pacman -Dk&lt;/code&gt; prints &lt;strong&gt;"No database errors have been found!"&lt;/strong&gt; — a bare
&lt;code&gt;error&lt;/code&gt; match flagged a clean Arch system as having broken packages.&lt;/li&gt;
&lt;li&gt;The EDAC driver's startup line is &lt;strong&gt;"EDAC ie31200: No ECC support"&lt;/strong&gt; — the
check matched it as an ECC problem. It was the &lt;em&gt;top item&lt;/em&gt; in the report and
cost 9 points.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mce: CPU supports N MCE banks&lt;/code&gt; is printed once per CPU at boot on every
Intel machine. A bare &lt;code&gt;mce&lt;/code&gt; match read it as a machine-check exception.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; a keyword match is not a diagnostic. Require an actual event, and&lt;br&gt;
explicitly reject the routine preamble lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Kernel interfaces are not namespaced
&lt;/h2&gt;

&lt;p&gt;Inside a 256 MB container, &lt;code&gt;free -b&lt;/code&gt; reported the &lt;strong&gt;host's&lt;/strong&gt; 15 GB.&lt;br&gt;
&lt;code&gt;/proc/loadavg&lt;/code&gt; is the host's load average while &lt;code&gt;nproc&lt;/code&gt; reports the&lt;br&gt;
container's CPU count — and the ratio between them invented an &lt;em&gt;overloaded&lt;/em&gt;&lt;br&gt;
system out of an idle container. (All five test images reported it.) &lt;code&gt;lsblk&lt;/code&gt;&lt;br&gt;
and &lt;code&gt;/proc/swaps&lt;/code&gt; are not namespaced either, so the container was told about&lt;br&gt;
the host's disks and swap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; detect the container and say why you are skipping. That is a&lt;br&gt;
limitation of the environment, not a verdict about the host.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Sometimes the bug is you
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;fuser&lt;/code&gt;-based lock probe ran next to Linux Doctor's &lt;em&gt;own&lt;/em&gt; &lt;code&gt;apt-get check&lt;/code&gt;. So&lt;br&gt;
it found the tool itself holding the dpkg lock — and told the user to wait for,&lt;br&gt;
or kill, a process that &lt;strong&gt;was the tool&lt;/strong&gt;. It only happened when run as root, so&lt;br&gt;
almost nobody would ever have seen it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; when you inspect a global resource, exclude your own process group.&lt;/p&gt;

&lt;h2&gt;
  
  
  The wrong direction of wrong
&lt;/h2&gt;

&lt;p&gt;The dangerous bug is not a false alarm. It is a false &lt;em&gt;all-clear&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A fresh image that never ran &lt;code&gt;apt update&lt;/code&gt; answers &lt;strong&gt;"0 upgraded" with exit
0&lt;/strong&gt; — which read as "up to date". That is not being up to date. The check now
says it &lt;em&gt;cannot tell&lt;/em&gt; and points at &lt;code&gt;apt update&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;apk info -u&lt;/code&gt; is not a valid command at all (it exits &lt;code&gt;1&lt;/code&gt; with
&lt;code&gt;unrecognized option 'u'&lt;/code&gt;), so Alpine said &lt;strong&gt;nothing&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Void had no update branch, so a machine with &lt;strong&gt;54 pending updates&lt;/strong&gt; was
skipped and scored as current.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;flatpak remote-ls --updates&lt;/code&gt; prints a column table whose fields contain no
&lt;code&gt;/&lt;/code&gt;, which is exactly what the count looked for → "apps are up to date" with
updates pending.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; prefer &lt;em&gt;"unknown"&lt;/em&gt; to a confident lie. A check that says "I could&lt;br&gt;
not determine this, and here is the package that would let me" is worth more&lt;br&gt;
than one that silently scores a broken machine as healthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  And sometimes it answered a different question than the one asked
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;processes&lt;/code&gt; warned whenever one app used more than 20% of &lt;em&gt;total&lt;/em&gt; RAM,
ignoring what was actually free — so a 15 GB box with 9.4 GB free got a
medium warning about a browser.&lt;/li&gt;
&lt;li&gt;The same check listed a browser &lt;strong&gt;once per process&lt;/strong&gt; (its memory is spread
across many processes sharing one binary) and reported the largest single
process as "the app".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;timers&lt;/code&gt; called &lt;code&gt;dnf-makecache.timer&lt;/code&gt; a broken schedule. It is enabled on an
immutable system and &lt;strong&gt;can never run&lt;/strong&gt; — its start condition is unmet by
design, and &lt;code&gt;systemctl status&lt;/code&gt; says so.&lt;/li&gt;
&lt;li&gt;The KDE lock screen logs &lt;code&gt;Authentication attempt too soon&lt;/code&gt; every time you
retype a wrong password quickly. A healthy desktop got &lt;strong&gt;"6 recognized
errors"&lt;/strong&gt; and lost 8 points. The same string from &lt;code&gt;sshd&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; worth seeing —
only the screen locker's copy is noise.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; "the number is real" is not the same as "the number means what you&lt;br&gt;
think it means."&lt;/p&gt;

&lt;h2&gt;
  
  
  How these are caught now
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;clean-image gate&lt;/strong&gt; runs the engine inside Fedora, Debian, Ubuntu, Alpine
and Arch containers, and fails when an unexplained high or medium finding
appears.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recorded fixtures&lt;/strong&gt; from real machines replay through the same pipeline,
and every high/medium finding they produce needs a written reason.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;severity rubric&lt;/strong&gt; and a finding-code registry so severity cannot drift
silently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No fix lands without a regression test that fails first.&lt;/strong&gt; A wrong result
is reproduced before it is changed.&lt;/li&gt;
&lt;li&gt;The whole list is public, in both directions:
&lt;a href="https://github.com/7sh1d0w7x/linux-doctor/blob/main/docs/limitations.md" rel="noopener noreferrer"&gt;&lt;code&gt;docs/limitations.md&lt;/code&gt;&lt;/a&gt;
names every false positive and false negative it has shipped, with the test
that guards each one.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why tell on yourself
&lt;/h2&gt;

&lt;p&gt;The entire value of a diagnostic is trust — and trust is built by being&lt;br&gt;
explicit about where you might be wrong, not by never being wrong. A tool that&lt;br&gt;
admits &lt;em&gt;"I could not check this; here is the package that fixes it"&lt;/em&gt; is far&lt;br&gt;
more useful than one that quietly scores a minimal image as perfect.&lt;/p&gt;

&lt;p&gt;Linux Doctor is read-only by construction: it prints the fix and never runs it.&lt;br&gt;
One engine sits behind a CLI, a web dashboard and a desktop app — and the&lt;br&gt;
honesty document ships with it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;→ &lt;a href="https://github.com/7sh1d0w7x/linux-doctor" rel="noopener noreferrer"&gt;https://github.com/7sh1d0w7x/linux-doctor&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you run it and it gets something wrong, that is the most useful bug report&lt;br&gt;
the project can get — and it comes with a replayable fixture.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>bash</category>
      <category>opensource</category>
      <category>debugging</category>
    </item>
  </channel>
</rss>
