Skip to content

fix(docs-hygiene): audit-noise silently skips uncommitted paths git quotes or renders with an arrow #3164

Description

@kyle-sexton

Summary

audit-noise's default-target router parses git status --porcelain v1 output. Two classes of path survive that parse incorrectly and are silently dropped from the target list, so the run reports a clean tree while real findings sit in the working tree.

This is the same defect class as #3126 (fixed for audit-comment-residue in #3151). It was found while fixing that one: audit-noise's parse was initially ported into audit-comment-residue as the mature, proven implementation, and review on #3151 showed it is not.

Observed in docs-hygiene@0.18.3, current at dff0942. Confirmed against git 2.55.

The two cases

Input v1 renders as parse yields
café.md (default core.quotePath) ?? "caf\303\251.md" caf\303\251.md — literal escape sequence, names nothing
left -> right.md (an ordinary file) ?? "left -> right.md" right.md" — arrow split misfires, names nothing

audit-noise strips the surrounding quotes and unescapes \" (scripts/detect.sh, the porcelain branch), but does not decode C-style octal escapes. It also splits on -> unconditionally, so an ordinary filename containing that substring is mistaken for a rename.

Reproduction

A git repo containing two untracked files, café.md and left -> right.md, each with a line matching the citation shape (The helper was renamed to newName in a later revision.):

$ git status --porcelain
?? "caf\303\251.md"
?? "left -> right.md"

$ detect.sh                                    # default target
Summary total: files=0 T1=0 T2=0 T3=0

$ detect.sh "café.md" "left -> right.md"       # control, explicit paths
Summary total: files=2 T1=2 T2=0 T3=0

The findings exist. Only the default-target path misses them.

Why it matters

A false negative in an audit tool is worse than an error. An error prompts a retry; a confident files=0 ends the investigation. The caller gets no signal that anything was skipped.

Suggested fix

Read the NUL-delimited --porcelain -z form, which git documents as performing no quoting or backslash-escaping. This is what #3151 landed for audit-comment-residue after review rejected patching the v1 parse — writing a full C-style decoder (\303\251, \t, \n, \\) is avoidable surface area when a format with no escaping exists.

One detail worth carrying over, since it is the reverse of the v1 display order: under -z a rename emits the new path first and the original as a following record.

v1:  R  plain.md -> "renamed one.md"
-z:  R  renamed one.md\0plain.md\0

The second record must be consumed and discarded, or the audit targets a path that no longer exists.

Note audit-noise's router also handles --paths-file and offset/limit pagination, neither of which is affected — the change is confined to the porcelain branch. Worth regression fixtures for all three cases (spaced, non-ASCII, arrow-bearing) plus the discarded rename original; see audit-comment-residue's detect.test.sh case 9/10 in #3151 for the shape.

Metadata

Metadata

Assignees

Labels

agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: needs-triageDefault until a priority tier is assigned.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions