Malware scanning asks whether a file is hostile. The check that
actually loses people their accounts is a different one: what has
already been exposed, and what is about to be? crates/hound-supply/src/
hygiene.rs answers it, and runs as part of every project sweep.
- A secret file tracked by git. The emergency case: it is in the
history, in every clone, and in every fork. The advice says rotate
BEFORE `git rm --cached`, because removing a pushed secret does not
un-share it, and a test asserts that ordering.
- Credentials hardcoded in source, recognised by issuer format —
AWS, GitHub, Anthropic, OpenAI, Stripe, Slack, GitLab, npm, PyPI,
Google, and the PEM private-key headers.
- Secret files readable by every account on the machine.
- Secret files with nothing in .gitignore covering them: the near
miss that the next `git add -A` turns into the emergency above.
- GitHub Actions: pull_request_target with a checkout of the pull
request (a stranger's code, your secrets, your write token), a
secret echoed into the build log, a downloaded script piped into a
shell, and third-party actions on a moving tag.
Two rules govern all of it. **Findings are actionable**: no entropy
heuristics, because "high entropy string" is a coin flip a human then
has to adjudicate, and people stop reading after the second false
alarm. Every detector recognises a documented credential format or
reports a structural fact that is true or false. **Nothing secret is
copied into a finding** — a report naming the key it found has moved
the key into a log, a CI artefact, or an assistant's context window,
which is the thing being prevented. There is a test for that.
Tracked-file status comes from parsing .git/index rather than running
git: the sweep is pointed at repositories precisely because they are
not trusted, and starting a subprocess inside one is what a hostile
repository wants.
Against a deliberately bad test repository: four critical, five
warnings, and correctly silent on .env.example and actions/checkout@v4
— flagging those is how a scanner gets ignored.
Also in this release:
- Right-click "Scan for Threats with Hound" in Nemo, Caja and
Dolphin, whose menu entries are system files. GNOME Files and
Thunar keep theirs per-user, so `hound context-menu install`
handles those. The icon is symbolic, so the file manager recolours
it to the menu's own theme instead of dropping a violet dog into a
monochrome menu.
- A right-click while the app is already open hands the request to
the running instance rather than refusing. A menu item that
silently does nothing because the app happens to be open is
indefensible.
- Two fixes for the duplicate tray icon. The updater slept a fixed
600ms after SIGTERM and then started the replacement; if the old
process outlived that, the panel kept its item and the result was
two dogs, the older of which could not be clicked or closed because
nothing was behind it. It now waits for the process to actually
leave /proc, escalating to SIGKILL after five seconds. And the app
itself now holds an advisory lock for its lifetime, so a second
instance cannot exist — the kernel releases the lock however the
process dies, so a stale one is not a state that can happen.
402 tests pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>