External review of the ruleset and reap. All five reproduced before
changing anything; two were worse than reported.
A capture narrower than the credential it matches stops early and the
preview then prints the rest of the key as surrounding context. The OpenAI
rule excluded `-` and `_`, so a modern sk-proj key ending on `-` had its tail
printed raw, and one ending on `_` matched nothing at all — a missed key, not
just a leaky preview. The rule is fixed, but the guarantee now holds
structurally: masked spans are widened over the whole credential-shaped run,
so any rule with that flaw is survivable, including ones added later.
The two NAME=value heuristics were blind inside JSONL transcripts, which is
the surface nanny exists for. A transcript's newlines are the two characters
\n and its quotes are \", so (?m)^ never matched; and \b does not match after
an underscore, so SECRET inside SUPABASE_SECRET_KEY was invisible. Measured
before: 3/3 in a raw .env dump, 0/3 inside a transcript line. After: 3/3 in
both. It also made the ruleset six times faster — consuming a real character
instead of a zero-width assertion lets the engine build a literal prefilter,
and 37.6 MB went from 1.7s to 0.29s.
Reap supersession paired each stale row against any survivor with a matching
fingerprint. Where one fingerprint covers several distinct secrets — which is
what a marker rule does — deleting one of two private keys from a file paired
both stale rows against the single survivor and recorded a deletion as a
move. Pairing is now one-to-one, which is also the right answer for ordinary
rules where the pool holds one entry.
The harness was inferred from the path although the collector knew it, so a
repository with its own .claude/ directory was labelled as the claude-code
harness and never got the working-tree demotion. Excerpts carry the
collector's answer now. And .txt no longer counts as documentation: a scratch
notes.txt is the likeliest place for a pasted key, and demoting it quietened
exactly the finding worth shouting about.
The sixth was found by running the fixes: editing two heuristics made 167
findings report as "no longer on disk" when nothing had moved. Reaping
compares against what a previous sweep recorded, so it is only meaningful
when both used the same ruleset. Sweeps now record a ruleset digest and stand
the reap down when it changes. The 172 rows falsely marked gone on this
machine have been cleared.
While confirming the transcript fix on real data, MAX_PROMPT_TOKENS turned
out to be a whole false-positive class the relaxation exposed. A suffix must
now start with an underscore, so plural names — counts and collections — no
longer match while SECRET_KEY_ID still does.
Measured on roosta: 743 new findings, 192 of them in claude transcripts that
were previously invisible, including 13 OpenAI keys.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqHWfdMAsYu1o36tgeima