Skip to content

claude-config audit-instructions: emit-findings.sh declines the relative scan-row paths instruction-scan.sh produces, dropping those findings #3267

Description

@kyle-sexton

What is wrong

Two sibling scripts in the claude-config:audit-instructions skill disagree about the path form a scan row may carry, so findings are discarded between them.

scripts/instruction-scan.sh emits candidate rows as file:line:check-id, using whatever path form the caller handed it. Naming a repo-owned surface relatively is the ordinary invocation, and SKILL.md documents the call as instruction-scan.sh <file>... with no requirement that the path be absolute.

scripts/emit-findings.sh relativizes each row's path with relativize_in_repo(), which tests the path against three absolute anchors (repo_root_pwd, repo_root, repo_root_alt) and returns the empty string when none of them prefixes it. A path that is already repo-relative — exactly the form Location requires — matches no absolute anchor, so it returns empty and the row is declined as outside-repo-root.

Reproduction

In a git checkout containing withfm.md (a file with ordinary YAML frontmatter and a CRITICAL: directive in its body):

$ bash instruction-scan.sh --body-only withfm.md
withfm.md:6:I28-a

$ bash emit-findings.sh --from scan.txt --out out.md --branch b
$ grep -E '^\| [0-9]|Declined|Emitted' out.md
Scan rows read: 1. Emitted: 0.
Declined candidates: I28-a count=1 reason=outside-repo-root (Location must be repo-relative; human report only)

The identical file named by absolute path emits normally:

Scan rows read: 1. Emitted: 1.
| 1 | IMPORTANT | high | withfm.md:6 | ... |

Note that the emitted Location in the working case is withfm.md:6 — the very form that was rejected as not repo-relative when supplied directly.

Why it matters

The scanner's own natural output is silently unusable by its consumer. Every finding from a relatively-named target is dropped from the machine-readable relay and survives only in the human report, and the stated decline reason ("Location must be repo-relative") is the opposite of the truth for these rows.

plugins/ai-slop/skills/audit/scripts/emit-findings.sh does not have this gap: its relativize() returns the path unchanged when no anchor matches, rather than declining the row.

Suggested direction

Treat a path that is not absolute as already repo-relative and admit it as-is.

One caveat worth handling in the same change: admitting relative paths is what makes traversal expressible here. The anchor test is lexical, so .. segments are not currently considered — <repo>/../outside.md prefix-matches an anchor and would relativize to ../outside.md, which the fix pass would then resolve outside the working tree. A path holding a .. segment should be refused outright, which is the fail-closed direction and preserves the fence's stated purpose.

Context

#3242 reworked path anchoring in both emit-findings.sh producers to resolve repo-root spelling differences. The relative-path case was not part of that change. There is no test covering a relative scan-row path in scripts/emit-findings.test.sh today.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions