feat(#72): add CI typography gate for outward-facing docs - #78
Merged
Conversation
Mechanizes the existing no-em-dash writing-style rule so it can't
regress silently: a git grep step in the shell CI job (mirrored in
.local-ci.json) fails the build on em/en-dashes or curly quotes in
README.md, docs/*.md, docs/index.html, and the plugin marketplace
description. Fixed the one live violation, in
.claude-plugin/marketplace.json's description.
The .local-ci.json entry uses literal Unicode characters in the
bracket class rather than \x{...} hex escapes: local-ci's custom-check
extraction pipes each check's "run" field through jq's @TSV, which
escapes embedded backslashes for safe TSV framing, and the downstream
`read -r` + `bash -c` preserves that doubling literally inside the
command's own single-quoted argument - turning \x{2014} into \\x{2014}
and silently breaking the PCRE hex-escape into a bogus literal
character class. Caught by actually running the check through
local-ci.sh (not just testing the command by hand) and comparing the
output against a byte-count sanity check. ci.yml's own step is
unaffected (GitHub Actions runs it directly, no jq round-trip) and
keeps the \x{...} form specifically to avoid pasting a literal
em-dash into the workflow file itself.
Closes #72
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019VuUKvqH3q511w8xVd4VFY
…UTF-8 locale)
git grep -P only enables PCRE2's UTF mode under a UTF-8 locale
codeset; \x{2013} exceeds PCRE2's 8-bit max outside one, so under
e.g. LC_ALL=C the pattern fails to COMPILE (rc=128) rather than
finding zero matches (rc=1). The prior `if git grep ...; then FAIL;
fi` treated that compile failure identically to "no match found" and
passed clean - a gate whose entire point is "can't regress silently"
had a silent-pass failure mode of its own.
ci.yml: pins LC_ALL=C.UTF-8 on the invocation and checks the exit
code explicitly (0 = matches found = fail; 1 = clean; anything else =
the check itself broke = fail loud, never silent-pass).
.local-ci.json: same fix, and closes the mirror-image bug the
reviewer also found - the literal-Unicode-character bracket class
(needed there to route around the @TSV double-escaping bug from the
prior commit) degrades to a raw BYTE class outside a UTF-8 locale
under LC_ALL=C, over-matching unrelated multi-byte sequences (verified:
40 false positives on docs/REFERENCE.md's box-drawing tree chars).
Verified live through the actual local-ci.sh custom-check driver, not
just by hand: normal pass, a staged regression still fails correctly,
and the explicit rc-check was exercised directly under a broken locale.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019VuUKvqH3q511w8xVd4VFY
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
git grep-based typography check to CI'sshelljob (Linux leg), mirrored in.local-ci.json: fails the build on em/en-dashes or curly quotes inREADME.md,docs/*.md,docs/index.html, and the plugin marketplace description..claude-plugin/marketplace.json's description.Note: the
.local-ci.jsonentry uses literal Unicode characters in its bracket class rather than\x{...}hex escapes — local-ci's custom-check extraction round-trips each command through jq's@tsv, which escapes embedded backslashes, and the doubled backslash silently breaks the PCRE hex-escape when re-parsed.ci.yml's own step is unaffected (Actions runs it directly) and keeps the\x{...}form to avoid a literal em-dash in the workflow file itself.Closes #72
Test plan
local-ci --strict— all checks pass (186/186 hook test assertions unaffected, typography check passes)sh tests/run.sh— 186/186README.md, confirmed the check fails (both the rawgit grepcommand and through the actuallocal-ci.shrunner), then reverted.local-ci.jsonescaping bug by running the check through the reallocal-ci.shcustom-check driver, not just testing the shell command by hand🤖 Generated with Claude Code
https://claude.ai/code/session_019VuUKvqH3q511w8xVd4VFY