Context
The hygiene job's gitleaks step fails on pull requests that do not touch the flagged file,
which fails the ci-status rollup and blocks merge. Observed on #3588, whose diff is
documentation only.
The finding, reproduced locally with the CI-pinned gitleaks 8.30.1 and this repo's
.gitleaks.toml:
RuleID: generic-api-key
Secret: CLAUDE_SHIM=0
File: plugins/claude-config/lib/resolve-convention-home.sh
Line: 248
Commit: f7aec1549dec60407a24a7d8ea720696b7b099af
Fingerprint: f7aec1549dec60407a24a7d8ea720696b7b099af:plugins/claude-config/lib/resolve-convention-home.sh:generic-api-key:248
The source is an ordinary shell variable initialization:
AGENTS_STATE="none"; AGENTS_TOKEN=""
CLAUDE_STATE="none"; CLAUDE_TOKEN=""
CLAUDE_SHIM=0
generic-api-key fires because the preceding CLAUDE_TOKEN="" line supplies the keyword context
and CLAUDE_SHIM=0 is captured as the value. There is no secret here.
Why this reaches unrelated pull requests
The commit is not on main and not on the branch of the pull request that fails. It is reachable
from origin/chore/bespoke-conversion and origin/chore/retired-conventions-mechanism, both
pushed 2026-09-01T21:47Z. The CI checkout fetches all branches, and the gitleaks step's git scan
reaches the commit through those refs — the failing run reported 1,987 commits scanned where the
pull request head's own history is 1,976. A scan confined to the head resolves clean; adding
--log-opts=--all reproduces the finding exactly.
main's own last push run (2026-09-01T21:40Z) predates the offending push by seven minutes, which
is why main is still green while every pull request opened or pushed after it is red.
Proposed fix
.gitleaks.toml states the policy: "inherit the upstream default ruleset and add nothing
repo-specific. Managed consumers do not edit this file. Intentional findings use a
repository-owned .gitleaksignore or inline gitleaks:allow comment." So the config is not the
place to fix this. Two options, in order of preference:
- On the branch that introduced the line, add an inline allow marker, or rename the variable so
the keyword context no longer forms (for example CLAUDE_SHIM_PRESENT=0 reads the same and
does not sit under a *_TOKEN line).
- A
.gitleaksignore fingerprint entry. Weaker: the fingerprint is commit-scoped, so a rebase of
that branch invalidates it.
Worth considering separately: whether the gitleaks step should scan the pull request's own history
rather than every fetched ref. Scanning all refs means any branch in the repository can red-line
every open pull request, which is what happened here.
Acceptance criteria
References
Context
The
hygienejob'sgitleaksstep fails on pull requests that do not touch the flagged file,which fails the
ci-statusrollup and blocks merge. Observed on #3588, whose diff isdocumentation only.
The finding, reproduced locally with the CI-pinned gitleaks 8.30.1 and this repo's
.gitleaks.toml:The source is an ordinary shell variable initialization:
generic-api-keyfires because the precedingCLAUDE_TOKEN=""line supplies the keyword contextand
CLAUDE_SHIM=0is captured as the value. There is no secret here.Why this reaches unrelated pull requests
The commit is not on
mainand not on the branch of the pull request that fails. It is reachablefrom
origin/chore/bespoke-conversionandorigin/chore/retired-conventions-mechanism, bothpushed 2026-09-01T21:47Z. The CI checkout fetches all branches, and the gitleaks step's git scan
reaches the commit through those refs — the failing run reported 1,987 commits scanned where the
pull request head's own history is 1,976. A scan confined to the head resolves clean; adding
--log-opts=--allreproduces the finding exactly.main's own last push run (2026-09-01T21:40Z) predates the offending push by seven minutes, whichis why
mainis still green while every pull request opened or pushed after it is red.Proposed fix
.gitleaks.tomlstates the policy: "inherit the upstream default ruleset and add nothingrepo-specific. Managed consumers do not edit this file. Intentional findings use a
repository-owned
.gitleaksignoreor inlinegitleaks:allowcomment." So the config is not theplace to fix this. Two options, in order of preference:
the keyword context no longer forms (for example
CLAUDE_SHIM_PRESENT=0reads the same anddoes not sit under a
*_TOKENline)..gitleaksignorefingerprint entry. Weaker: the fingerprint is commit-scoped, so a rebase ofthat branch invalidates it.
Worth considering separately: whether the gitleaks step should scan the pull request's own history
rather than every fetched ref. Scanning all refs means any branch in the repository can red-line
every open pull request, which is what happened here.
Acceptance criteria
hygienejob's gitleaks step passes on a pull request whose diff does not touchplugins/claude-config/lib/resolve-convention-home.sh..gitleaks.toml.commits.
References
.gitleaks.toml(root-canonical policy,[extend].useDefault)