Skip to content

fix(checks): stop SpellingDialect rewriting Tailwind and CSS tokens (CD-319) - #207

Open
TAJD wants to merge 1 commit into
mainfrom
fix/cd-319
Open

fix(checks): stop SpellingDialect rewriting Tailwind and CSS tokens (CD-319)#207
TAJD wants to merge 1 commit into
mainfrom
fix/cd-319

Conversation

@TAJD

@TAJD TAJD commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Fixes CD-319.

Consistency.SpellingDialect counted any string literal containing a space as prose, so a Tailwind class list qualified. Pinning dialect = "british" on bestefforttools turned 12 findings into 322, of which ~60 were instructions to rewrite items-center as items-centre. Tailwind emits no rule for items-centre, so following the check's own advice breaks the UI silently and passes review. The check is currently disabled in all five repos in the estate because of it.

What changed

Three exclusions in crates/cofferdam-checks/src/consistency.rs, cheapest first:

  • a className / class JSX attribute is never scanned;
  • an object property keyed by a CSS property name is never scanned, covering both style={{ backgroundColor: … }} and { 'background-color': … };
  • a dialect word hyphen-adjacent to a utility-class root is skipped wherever it appears, so a class list assembled with clsx/cn is covered too.

The third is gated on the word itself being CSS vocabulary (center, color, gray, normalize, capitalize, behavior, both spellings). Without the gate, self — both a Tailwind root and an English hyphen prefix — silences self-defence as readily as self-center.

The single-pass shape of collect_dialect_hits is preserved. Scanning per spelling costs 170 passes over every comment and showed up as a 20% whole-run regression, so it stays one pass.

Validation

Real repos, dialect = "british" pinned, --no-cache --no-baseline:

Repo Before After
bestefforttools 322 89
poker-puzzle (class-name rewrites) ~60 0

Every one of the 89 survivors on bestefforttools is a genuine American spelling in prose (optimization, analyze, favorite, labeled). poker-puzzle is down to five prose comments.

Tests

Eight cases in spelling_dialect_tests: className attribute, CSS-property-keyed object value, bare class-shaped string outside JSX, media-query feature name, a genuine hyphenated compound (well-organised), the self-defence / self-center pair, and a prose literal reporting alongside an excluded position in the same file. Fixtures extended in examples/spelling_dialect.ts plus a new examples/spelling_dialect_jsx.tsx.

Known limits

Both lists are curated, not exhaustive — an uncommon CSS property or a plugin-added Tailwind root falls through to the ordinary prose rules. That matches DIALECT_PAIRS' own restraint and fails in the safe direction only for the positional exclusions; a missed root means a false positive returns, not a silent miss.

🤖 Generated with Claude Code

https://claude.ai/code/session_019afugU2bTYCtXn6Vy9dn1v

…CD-319)

The check counted any string literal containing a space as prose, so a
class list qualified and it recommended `items-center` -> `items-centre`.
Tailwind emits no rule for `items-centre`, so following the advice broke
the UI silently. Three exclusions, cheapest first:

- a `className`/`class` JSX attribute is never scanned;
- an object property keyed by a CSS property name is never scanned,
  including the camelCase `backgroundColor` form;
- a dialect word hyphen-adjacent to a utility-class root is skipped
  wherever it appears, so a class list built with `clsx` is covered too.

The third is gated on the word itself being CSS vocabulary. Without that
gate `self` — a Tailwind root and an English hyphen prefix — silences
`self-defence` as readily as `self-center`.

Validated against two real repos with `dialect = "british"` pinned:
bestefforttools 322 -> 89 findings, every survivor a genuine American
spelling in prose; poker-puzzle's ~60 class-name rewrites -> 0, five
prose comments left.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019afugU2bTYCtXn6Vy9dn1v
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

Criterion benchmark comparison (PR head vs base branch)

�[1m�[92m   Compiling�[0m cofferdam-checks v0.4.2 (/home/runner/work/cofferdam/cofferdam/crates/cofferdam-checks)
�[1m�[92m   Compiling�[0m cofferdam-engine v0.4.2 (/home/runner/work/cofferdam/cofferdam/crates/cofferdam-engine)
�[1m�[92m    Finished�[0m `bench` profile [optimized] target(s) in 49.45s
�[1m�[92m     Running�[0m benches/engine_bench.rs (target/release/deps/engine_bench-e0ce420cbfc0fb1d)
Gnuplot not found, using plotters backend
Benchmarking full_run_no_cache
Benchmarking full_run_no_cache: Warming up for 3.0000 s
Benchmarking full_run_no_cache: Collecting 20 samples in estimated 7.2135 s (420 iterations)
Benchmarking full_run_no_cache: Analyzing
full_run_no_cache       time:   [16.372 ms 16.462 ms 16.549 ms]
                        change: [+1.5685% +2.0329% +2.5214%] (p = 0.00 < 0.05)
                        Performance has regressed.

Benchmarking single_file_edit_incremental
Benchmarking single_file_edit_incremental: Warming up for 3.0000 s

Warning: Unable to complete 20 samples in 5.0s. You may wish to increase target time to 9.7s, enable flat sampling, or reduce sample count to 10.
Benchmarking single_file_edit_incremental: Collecting 20 samples in estimated 9.6682 s (210 iterations)
Benchmarking single_file_edit_incremental: Analyzing
single_file_edit_incremental
                        time:   [7.4797 ms 7.5216 ms 7.5575 ms]
                        change: [-2.3647% -0.7755% +0.4320%] (p = 0.34 > 0.05)
                        No change in performance detected.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant