Skip to content

guardrails: hardcoded-path-check false positives — repo-path branch flags all paths under home; percent-env interpolations flagged #389

Description

@kyle-sexton

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: highSignificant impact, or blocks an imminent release; staff this cycle.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions