Skip to content

ai-slop audit: directory targets silently fall back to an untracked-inclusive filesystem walk when git and shell path spellings differ #3266

Description

@kyle-sexton

What is wrong

plugins/ai-slop/skills/audit/scripts/detect.sh expands a directory target to the markdown files beneath it. The code comment states the intended contract: "tracked files when the directory is inside a git checkout, a filesystem walk otherwise". The expansion is built as this pipeline:

git -C "$t" ls-files --full-name '*.md' |
  sed "s|^|$(git -C "$t" rev-parse --show-toplevel)/|" |
  grep -F "$(cd "$t" && pwd)/" ||
  find "$t" -name '*.md' -type f

The sed prefix and the grep -F filter are spelled by two different sources. git rev-parse --show-toplevel answers in git's own spelling of the path; cd "$t" && pwd answers in the shell's. On Git Bash these differ — git reports D:/repo where the shell reports /d/repo — so no prefixed line can match the filter, grep exits non-zero, and the || find fallback runs in place of the primary branch.

Why it matters

The fallback is not equivalent to the branch it replaces. git ls-files lists tracked files only; find walks the filesystem and returns untracked and ignored markdown as well. On any platform where the two spellings differ, a directory target therefore audits files the checkout does not track, and reports no indication that the intended tracked-files-only expansion was skipped.

Evidence

The repository's own test asserts exactly this property, and it fails:

FAIL: dir target in git repo: only the tracked file counts

That case lives in plugins/ai-slop/skills/audit/scripts/detect.test.sh. It builds a fixture repository containing one tracked and one untracked markdown file, points a directory target at it, and asserts 1 files scanned. The find fallback returns both files, so the assertion sees 2.

Reproduced directly against the pipeline:

$ t=plugins/ai-slop
$ git -C "$t" rev-parse --show-toplevel
D:/worktrees/<checkout>
$ (cd "$t" && pwd)
/d/worktrees/<checkout>/plugins/ai-slop
$ git -C "$t" ls-files --full-name '*.md' \
    | sed "s|^|$(git -C "$t" rev-parse --show-toplevel)/|" \
    | grep -F "$(cd "$t" && pwd)/" | wc -l
0

Zero of the 13 tracked markdown files under that directory survive the filter.

Suggested direction

Spell the prefix and the filter from one source. git rev-parse --show-prefix reports the target's path from the checkout root in the same spelling ls-files --full-name already uses, so the candidates can be narrowed without involving pwd at all.

The same two-spelling hazard appears twice more in this file, in matches_glob and in the rel computation in the scan loop. Both strip $REPO_ROOT from a caller-supplied path lexically (${1#"$REPO_ROOT"/}). When the caller's spelling differs from $REPO_ROOT's, the strip is a no-op, the path stays absolute, and an absolute path is still a well-formed value — so exclusion globs quietly stop matching and an absolute path can reach the Location field.

Context

#3242 resolved repo-root spelling differences in the two emit-findings.sh producers by carrying a second anchor (REPO_ROOT_ALT / REPO_ROOT_PWD) alongside the git-reported one. detect.sh was not given the same treatment and still resolves paths from a single anchor.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions