Commit graph

2 commits

Author SHA1 Message Date
dev
a3f31288fa rootkit: stop reporting every process on the machine as hidden
A clean laptop reported 988 critical rootkit findings; this server
3786, PID 1 among them. Every one was false, and the cause was our own
systemd hardening.

ProtectProc=invisible hides processes the daemon does not own from its
view of /proc, while kill(pid, 0) keeps answering truthfully because it
is a syscall and not a filesystem lookup. The hidden-process check
compares exactly those two sources, so with that setting every process
on the machine looked concealed. Enumerating processes is this daemon's
job, so it needs the default view.

Removing the setting is not enough on its own — hidepid= on the /proc
mount produces the same blindness and we do not control that. So the
detector now recognises when it cannot see:

  - PID 1 is the control. It always exists and nothing hides init; a
    rootkit that did would break the machine it is living on. If PID 1
    answers kill(1, 0) but is absent from the listing, we are blind and
    say so as info rather than crying rootkit.
  - A plausibility ceiling of 32. Hiding a handful of processes is the
    entire point of a rootkit; hundreds means a broken observer. An
    antivirus that reports a critical rootkit finding on every clean
    machine teaches people to ignore the one time it is real.

Also in this change, from testing on a real desktop:

  - Closing the window hides it to the tray instead of exiting, with a
    one-time notification so it does not read as a crash. Quit lives
    only in the tray menu and confirms first. The settings already had
    close_to_tray and confirm_quit fields wired to nothing; they are
    honoured now rather than hardcoded.
  - The tray menu and Scan Home sent the literal string "~". A shell
    would have expanded it, nothing here did, so the daemon was asked
    to scan a directory of that name. It failed silently until the
    per-peer readability check made it audible.
  - Administrative actions elevate through polkit instead of telling
    people to open a terminal. The app tries unprivileged first and
    only on a privilege refusal runs `pkexec hound admin-rpc`, which
    forwards one request as root. auth_admin_keep, because prompting on
    every settings toggle trains people to authenticate without reading
    the prompt. This grants what `sudo hound` already grants to people
    who could already run sudo — a transport, not a new privilege.
  - `hound settings exec-gate on|off` now exists. The install script,
    the AppImage banner, the rpm spec, the AUR install file and
    llms.txt all told users to run `hound settings set exec_gate true`.
    There was no `set` subcommand and no way to enable the execution
    gate from the CLI at all: the flagship paid feature was unreachable
    and the first thing a new user was told to type returned an error.
    A test now asserts every documented command parses.
  - `settings show` displays the exec gate state, and no longer prints
    its own header twice.
  - The CLI help still described ClamAV, which has not been the engine
    for some time. So did the socket permission error, which now
    explains the `hound` group and the log-out-and-back-in it needs.

368 tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 11:21:06 -05:00
Hound
13a9333e3f site: white button labels, pricing structure, copy icons, and GEO
Four things Joe asked for, one of which needed a decision he did not
make.

WHITE BUTTON LABELS. "White on both themes" could not be done by reusing
--brand: white on the dark theme's #9896E0 is 2.70:1, which fails AA
outright and would have looked washed out rather than crisp. Buttons now
have their own background — #5A58C8 light, #5A58D6 dark, the same
periwinkle the desktop app already uses for its primary button — at
5.52:1 and 5.73:1. The label is white in both, which is what makes the
control read as the same object when the theme changes. Contrast was
computed before choosing the colour rather than after somebody
complained.

PRICING. Cards are equal-height flex columns so the buttons line up
regardless of how many features each lists. The featured tier is marked
by a rule along its top edge and a badge rather than a different fill —
it is the same object, just the one being pointed at. Differentiating
features are bold, each tier carries a one-line footnote answering the
question the price raises ("Annual only", "Over 20 seats? We will quote
you"), and the feature text now says what the thing does rather than
naming it: "a malicious binary is refused before it runs, in 2 ms".

COPY BUTTONS are a clipboard icon that becomes a green tick, with
aria-label toggling to "Copied" so it is not a visual-only signal.

GEO AND SEO — the part with real leverage:

  - JSON-LD SoftwareApplication with 11 features and all three offers,
    and a FAQPage with nine questions.
  - A VISIBLE FAQ backing that schema. Schema describing content that is
    not on the page is both invalid and dishonest, so the nine questions
    are really there, in <details> elements, and they are the questions
    somebody actually asks before installing a root daemon.
  - llms.txt — a structured summary written for a model deciding whether
    to recommend Hound, including a section of honest limitations.
    Linux only, no RPM package yet, gate needs root, small rule pack,
    full-download definitions. A recommendation that omits those is
    worse than none, and a model that repeats them is a model that got
    the answer right.
  - robots.txt naming GPTBot, ClaudeBot, PerplexityBot, Google-Extended,
    Applebot-Extended, CCBot and others explicitly. Hound exists partly
    to be used BY coding agents; an agent reading this site should not
    have to guess whether it is welcome. Several of those crawlers treat
    silence as refusal, and silence is not the same as consent.
  - Canonical, Open Graph, Twitter card, theme-color, sitemap.

Every number in the structured data and in llms.txt is measured or comes
from a published feed. No ratings, no awards, no "trusted by" — a model
that quotes a fabricated number does more damage than one that quotes
nothing, because it is confident.

All four assets verified live: HTML 200, robots 200, sitemap 200,
llms.txt 200, and both JSON-LD blocks parse from the served page.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 09:43:46 -05:00