fix(ci): the invisible-character gate never matched anything - #65
Conversation
MEASURED 2026-08-27: this gate's pattern caught 0 OF 6 invisible-character test
cases. It has never detected an NBSP, zero-width space, BOM, soft hyphen, bidi
override or word joiner.
ROOT CAUSE: the pattern used UTF-8 BYTE sequences (\xc2\xa0) while grep -P
matches CHARACTERS. Bytes c2 a0 are ONE character U+00A0; \xc2\xa0 asks for TWO
characters, U+00C2 then U+00A0, which is never present.
grep -P '\xc2\xa0' -> miss
grep -P '\x{a0}' -> MATCH
Only \x00 worked, being single-byte in both readings.
FIXED: codepoint escapes; C0 control characters \x01-\x08,\x0B,\x0C,\x0E-\x1F
added (TAB/LF/CR excluded); and grep -a, without which grep skips any NUL-bearing
file as binary.
The C0 range matters: a stray BACKSPACE byte made a workflow unparseable in
developer-ecosystem, so it never ran, and this linter called it clean.
Canonical fix: hyperpolymath/empty-linter#70. 1 file(s) here.
VERIFIED: YAML re-parsed, and the corrected pattern was confirmed to catch a real
NBSP before the change was kept.
Up to standards ✅🟢 Issues
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📜 Recent review details⏰ Context from checks skipped due to timeout. (2)
🔇 Additional comments (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe empty-lint workflow now matches invisible characters with Unicode code-point escapes, includes the full C0 control range and U+2060, and uses ChangesInvisible-character gate
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This PR corrects the invisible-character gate's matching behavior in one workflow file. No actionable merge-blocking risk remains after normal checks and review. Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Full details: Docstring CoverageExplanation No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (1 skipped: 1 unsupported.) Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull Request Overview
The PR successfully addresses a configuration issue where the invisible-character CI gate was non-functional. The update to use Perl-compatible regex (-P) with Unicode codepoint escapes and the addition of the -a flag for null-byte handling correctly aligns with the intent to broaden detection capabilities. Codacy analysis indicates the changes are up to standards.
However, a critical gap exists in regression testing. Although the logic was manually verified, no automated test cases (files containing the target characters) were added to the repository. Without these, future changes to the CI environment or regex patterns could silently break the gate again, as occurred previously. Additionally, the grep implementation in the workflow can be optimized for performance.
About this PR
- The PR lacks automated regression tests. It is strongly recommended to add a suite of test files containing the targeted invisible characters and C0 control codes to the repository. This ensures that the CI gate remains functional across future updates to the runner environment or regex patterns.
Test suggestions
- Verify detection of multi-byte Unicode characters (e.g., NBSP, ZWS) using codepoint escapes.
- Verify detection of C0 control characters (e.g., Backspace \x08) while ignoring Tab/LF/CR.
- Verify that files containing NUL bytes (\x00) are scanned and reported rather than skipped as binary files.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Verify detection of multi-byte Unicode characters (e.g., NBSP, ZWS) using codepoint escapes.
2. Verify detection of C0 control characters (e.g., Backspace \x08) while ignoring Tab/LF/CR.
3. Verify that files containing NUL bytes (\x00) are scanned and reported rather than skipped as binary files.
TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback
| -o -name '*.idr' -o -name '*.zig' -o -name '*.v' -o -name '*.jl' \ | ||
| -o -name '*.gleam' -o -name '*.hs' -o -name '*.ml' -o -name '*.sh' \) \ | ||
| -exec grep -Prl "$PATTERNS" {} \; > /tmp/empty-lint-results.txt 2>/dev/null | ||
| -exec grep -aPrl "$PATTERNS" {} \; > /tmp/empty-lint-results.txt 2>/dev/null |
There was a problem hiding this comment.
🟡 MEDIUM RISK
Suggestion: The -r (recursive) flag is unnecessary because find is already providing file paths. Additionally, switching from -exec ... {} ; to -exec ... {} + improves performance by batching file paths and reducing the number of grep processes spawned.
| -exec grep -aPrl "$PATTERNS" {} \; > /tmp/empty-lint-results.txt 2>/dev/null | |
| -exec grep -aPl "$PATTERNS" {} + > /tmp/empty-lint-results.txt 2>/dev/null |
Measured 2026-08-27: this gate caught 0 of 6 invisible-character test cases. It has never detected an NBSP, zero-width space, BOM, soft hyphen, bidi override or word joiner.
Root cause
The pattern used UTF-8 byte sequences (
\xc2\xa0) whilegrep -Pmatches characters. Bytesc2 a0are one character U+00A0;\xc2\xa0asks for two, U+00C2 then U+00A0 — never present.Only
\x00worked, being single-byte in both readings. The gate ran, passed, and could not see what it exists to see.Fixed
\x01-\x08,\x0B,\x0C,\x0E-\x1Fadded (TAB/LF/CR excluded)grep -a— without it grep skips any NUL-bearing file as binaryThe C0 range matters: a stray backspace byte made a workflow unparseable in
developer-ecosystem, so it never ran — and this linter called it clean.Canonical fix: hyperpolymath/empty-linter#70. 1 file(s) here.
Verified: YAML re-parsed, and the corrected pattern was confirmed to catch a real NBSP before the change was kept.