Summary
guardrails hardcoded-path-check has two independent false-positive bugs that hard-deny
(exit 2) legitimate writes. Both were hit/confirmed this session while writing a machine-scoped
Windows helper script.
F1 (primary — root cause of the incident): repo-path branch flags every path under $HOME when the project dir is home
lib/path-detection/hardcoded-path-patterns.sh:147-159 (repo-path branch) matches PROJECT_ROOT
as a substring via grep -nFi, and per the comment at :144-146 it is never
OS-context-suppressed.
hooks/hardcoded-path-check.sh:110-117 resolves PROJECT_ROOT from CLAUDE_PROJECT_DIR.
When CLAUDE_PROJECT_DIR is an ancestor of the target — most acutely when it is the user's
home — every absolute path under home (AppData\..., Desktop\..., Documents\...) matches the
checkout-root literal and is blocked as a "leak." The scope pre-gate (:66-74) does not help: the
target is inside the "project," so the hook proceeds to deny.
Repro (confirmed by audit): session rooted at home; write any file whose body contains a real
absolute path under home → exit 2, "Machine-specific repo path detected." In this session that
blocked a Desktop .cmd that legitimately referenced a vhdx under AppData\Local\Docker\....
Suggested fix: gate the repo-path branch on PROJECT_ROOT being a real git checkout AND not
$HOME (nor a home-adjacent ancestor). That removes the false positive without loosening
leak-detection inside genuine repos. Keep existing DETECT test cases green.
F2 (independent): Windows env-var interpolations flagged as hardcoded
lib/path-detection/machine-path-patterns.sh:40,43,47 — the negative char class [^/\\$<{~]+
excludes $, <, {, ~ (so $HOME, ${...}, <placeholder> correctly break the match) but
not %.
So a legitimately portable interpolation — a percent-env token (USERPROFILE, USERNAME,
LOCALAPPDATA) used as the user segment of a Windows user path — is matched as a hardcoded path.
The LOCALAPPDATA percent-form only survives by accident (it contains no Users/repos literal),
not by recognition.
Meta-confirmation: this very issue body was blocked on first write because an earlier draft
contained a percent-interpolated user path in a fenced example; it had to be reworded to file.
That is F2 reproducing live.
Suggested fix: add % to the excluded class, or add a grep -v exclusion stage for segments
that are %...% (or $env:...) tokens, mirroring the existing macOS exclusion stages.
Impact
On any session whose project dir is (or is under) the user's home, the hook blocks routine writes
of machine-scoped scripts (Desktop helpers, provisioning .cmd/.ps1, runbooks) that correctly use
absolute or percent-env paths. The documented escape hatches don't reach these cases (see the
companion enhancement issue).
Environment
guardrails@melodic-software 0.7.0, Claude Code 2.1.215, Windows 11, session cwd = user home.
Summary
guardrailshardcoded-path-checkhas two independent false-positive bugs that hard-deny(
exit 2) legitimate writes. Both were hit/confirmed this session while writing a machine-scopedWindows helper script.
F1 (primary — root cause of the incident): repo-path branch flags every path under
$HOMEwhen the project dir is homelib/path-detection/hardcoded-path-patterns.sh:147-159(repo-path branch) matchesPROJECT_ROOTas a substring via
grep -nFi, and per the comment at:144-146it is neverOS-context-suppressed.
hooks/hardcoded-path-check.sh:110-117resolvesPROJECT_ROOTfromCLAUDE_PROJECT_DIR.When
CLAUDE_PROJECT_DIRis an ancestor of the target — most acutely when it is the user'shome — every absolute path under home (
AppData\...,Desktop\...,Documents\...) matches thecheckout-root literal and is blocked as a "leak." The scope pre-gate (
:66-74) does not help: thetarget is inside the "project," so the hook proceeds to deny.
Repro (confirmed by audit): session rooted at home; write any file whose body contains a real
absolute path under home →
exit 2, "Machine-specific repo path detected." In this session thatblocked a Desktop
.cmdthat legitimately referenced a vhdx underAppData\Local\Docker\....Suggested fix: gate the repo-path branch on
PROJECT_ROOTbeing a real git checkout AND not$HOME(nor a home-adjacent ancestor). That removes the false positive without looseningleak-detection inside genuine repos. Keep existing DETECT test cases green.
F2 (independent): Windows env-var interpolations flagged as hardcoded
lib/path-detection/machine-path-patterns.sh:40,43,47— the negative char class[^/\\$<{~]+excludes
$,<,{,~(so$HOME,${...},<placeholder>correctly break the match) butnot
%.So a legitimately portable interpolation — a percent-env token (
USERPROFILE,USERNAME,LOCALAPPDATA) used as the user segment of a Windows user path — is matched as a hardcoded path.The
LOCALAPPDATApercent-form only survives by accident (it contains noUsers/reposliteral),not by recognition.
Suggested fix: add
%to the excluded class, or add agrep -vexclusion stage for segmentsthat are
%...%(or$env:...) tokens, mirroring the existing macOS exclusion stages.Impact
On any session whose project dir is (or is under) the user's home, the hook blocks routine writes
of machine-scoped scripts (Desktop helpers, provisioning
.cmd/.ps1, runbooks) that correctly useabsolute or percent-env paths. The documented escape hatches don't reach these cases (see the
companion enhancement issue).
Environment
guardrails@melodic-software0.7.0, Claude Code 2.1.215, Windows 11, session cwd = user home.