Parent
Source: handoff-inbox item 20260723-084139-actionlint-plugin-audit-findings (Findings 1, 2, 3, 6 — the silent-failure cluster; F1 reproduced Tier-0 with hand-built payloads in both path forms).
What to build
Silent-skip and silent-failure fixes in the actionlint hook (actionlint-check.sh call site — not the synced shared lib):
F1 (MED, the driver): membership guard silently skips lint on Windows 8.3 short paths. hook::read_file_path compares physical+normalized file_path against CLAUDE_PROJECT_DIR; GNU realpath under Git Bash does not expand 8.3 short names, so C:\Users\KYLESE~1\... fails the prefix match and the hook exits silently — no lint, no notice, no telemetry (exit precedes the skipped branch). Short-form paths occur in practice (Claude Code's scratchpad env var is short-form; CC does not normalize tool_input.file_path).
Producer's primary recommendation, adopt unless evidence against: remove the membership guard from this hook. PostToolUse cannot block or undo the write (hooks docs exit-code table: "PostToolUse | No | Shows stderr to Claude; the tool already ran"), so the guard protects nothing and every guard false-negative is a silent coverage loss — violating the plugin's own prerequisite-visibility doctrine ("a silently skipped feature is a defect", CHANGELOG 0.3.0). Fallback if the guard must stay: expand BOTH comparison sides via cygpath -lm on MSYS (the hook already uses cygpath -lm for FILE_REL), and make guard rejection emit the once-per-session visible skip notice instead of a bare return 1.
F2 (LOW-MED): cd failure falls through to "clean". AL_OUTPUT=$(cd "$REPO_ROOT" && actionlint ... 2>&1) || true — a failed cd yields empty output and the clean-workflow branch emits telemetry status:"ok", findings:[], indistinguishable from a real pass. Verify actionlint actually executed; emit a distinct skipped/error telemetry status on failure.
F3 (LOW): data.file can leak an absolute path. When cygpath -lm succeeds but the prefix-strip does not match (mount/symlink mismatch), FILE_REL silently stays absolute and flows into telemetry data.file, violating the schema's repo-relative contract. Degrade visibly (basename or explicit marker) rather than leaking the absolute path.
F6 (test gaps riding along): add a short-form-path regression case (suite currently leaves CLAUDE_PROJECT_DIR unset — the guard path is entirely untested); add a -pyflakes= regression fixture (only -shellcheck= is exercised; dropping -pyflakes= passes 35/35 today).
Reproduce F1 before fixing (payloads in both path forms). Verify harness claims against current official hooks docs per the repo's fresh-docs mandate.
Acceptance criteria
Blocked by
None — can start immediately.
Parent
Source: handoff-inbox item
20260723-084139-actionlint-plugin-audit-findings(Findings 1, 2, 3, 6 — the silent-failure cluster; F1 reproduced Tier-0 with hand-built payloads in both path forms).What to build
Silent-skip and silent-failure fixes in the actionlint hook (
actionlint-check.shcall site — not the synced shared lib):F1 (MED, the driver): membership guard silently skips lint on Windows 8.3 short paths.
hook::read_file_pathcompares physical+normalizedfile_pathagainstCLAUDE_PROJECT_DIR; GNUrealpathunder Git Bash does not expand 8.3 short names, soC:\Users\KYLESE~1\...fails the prefix match and the hook exits silently — no lint, no notice, no telemetry (exit precedes theskippedbranch). Short-form paths occur in practice (Claude Code's scratchpad env var is short-form; CC does not normalizetool_input.file_path).Producer's primary recommendation, adopt unless evidence against: remove the membership guard from this hook. PostToolUse cannot block or undo the write (hooks docs exit-code table: "PostToolUse | No | Shows stderr to Claude; the tool already ran"), so the guard protects nothing and every guard false-negative is a silent coverage loss — violating the plugin's own prerequisite-visibility doctrine ("a silently skipped feature is a defect", CHANGELOG 0.3.0). Fallback if the guard must stay: expand BOTH comparison sides via
cygpath -lmon MSYS (the hook already usescygpath -lmforFILE_REL), and make guard rejection emit the once-per-session visible skip notice instead of a barereturn 1.F2 (LOW-MED):
cdfailure falls through to "clean".AL_OUTPUT=$(cd "$REPO_ROOT" && actionlint ... 2>&1) || true— a failedcdyields empty output and the clean-workflow branch emits telemetrystatus:"ok", findings:[], indistinguishable from a real pass. Verify actionlint actually executed; emit a distinctskipped/errortelemetry status on failure.F3 (LOW):
data.filecan leak an absolute path. Whencygpath -lmsucceeds but the prefix-strip does not match (mount/symlink mismatch),FILE_RELsilently stays absolute and flows into telemetrydata.file, violating the schema's repo-relative contract. Degrade visibly (basename or explicit marker) rather than leaking the absolute path.F6 (test gaps riding along): add a short-form-path regression case (suite currently leaves
CLAUDE_PROJECT_DIRunset — the guard path is entirely untested); add a-pyflakes=regression fixture (only-shellcheck=is exercised; dropping-pyflakes=passes 35/35 today).Reproduce F1 before fixing (payloads in both path forms). Verify harness claims against current official hooks docs per the repo's fresh-docs mandate.
Acceptance criteria
file_pathis linted (or, if the guard is retained, produces a visible once-per-session skip notice + telemetry) — never a silent exitcd/actionlint launch yields a distinctskipped/errortelemetry status, neverstatus:"ok"with empty findingsdata.filenever carries an absolute path; mismatch case degrades visibly-pyflakes=fixture; full suite passes; shellcheck cleanBlocked by
None — can start immediately.