feat(ci): CSS class consistency build-time gate — fail build on undefined class references (#2503)#2516
Merged
alexey-pelykh merged 1 commit intomainfrom Apr 24, 2026
Merged
Conversation
…am-sync class renames from silently desyncing (#2503) Adds lint:ui:no-css-class-drift pnpm script invoking the existing scripts/audit-css-class-drift.mjs (#2502), and appends it to the pnpm check chain so the lint CI job now fails on any template-string class reference in ui/src/**/*.{ts,tsx,html} that has no matching rule in the CSS files reachable from ui/src/styles.css. Baseline on main: 0 orphans / 403 references / 733 defined classes (cluster fixes from #2506, #2512, #2513, #2514, #2515 already resolved all existing drift before this gate is wired, per the #2503 AC "All findings from D-1 resolved BEFORE this check is wired into CI"). Script name adapted from the issue's suggested lint:css-classes to lint:ui:no-css-class-drift — matches the lint:<area>:no-<thing> pattern used by lint:ui:no-raw-window-open, lint:tmp:no-random-messaging, and lint:plugins:no-monolithic-plugin-sdk-entry-imports. Documented in CLAUDE.md § Formatting & Linting (local-dev orientation) and § Fork-integrity gates (CI/fork-lifecycle orientation, cross-referenced with the existing rebrand / zombie-import / stub-debt / throwing-stub-callers / obsolescence-audit gates). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Closes #2503.
pnpm lint:ui:no-css-class-driftscript invoking the existingscripts/audit-css-class-drift.mjs(landed in audit(ui): CSS class drift audit script (#2502) #2507 / audit(ui): one-shot CSS class drift audit — surface fork-side references with no CSS definition #2502).pnpm checkchain — thelintCI job already runspnpm check, so the drift gate now runs in CI automatically without any workflow edit.Baseline verification (AC: "All findings from D-1 resolved BEFORE wiring")
On
mainat branch base (20984fb998):All drift clusters identified by #2502's audit were resolved in merged PRs #2506 (→ #2501), #2512 (→ #2510), #2513 (→ #2508), #2514 (→ #2509), and #2515 (→ #2511). Wiring this gate now will NOT make CI permanently red.
Gate behavior verification
Full
pnpm checkrun on this branch: passes (format:check, tsgo, oxlint, lint:tmp:no-random-messaging, lint:no-remoteclaw-ai, lint:ui:no-css-class-drift).Adversarial test: injected a fake class
definitely-not-a-real-class-xyz-probeintoui/src/main.ts→Post-revert:
Orphans: 0, exit 0. Gate catches drift;pnpm checkfails on any class reference with no matching rule.Script naming deviation
Issue #2503 AC line 6 suggests
pnpm lint:css-classes. Project convention islint:<area>:<predicate>, established by:lint:ui:no-raw-window-openlint:tmp:no-random-messaginglint:plugins:no-monolithic-plugin-sdk-entry-importsUsed
lint:ui:no-css-class-driftto match —uiarea scope (the check scansui/src/**/*.{ts,tsx,html}andui/src/styles.cssimport graph),no-<thing>negated-predicate form. The issue'slint:css-classeswas a proposed name in an "Implementation plan" section; the AC is about the check running inpnpm check, which this PR delivers.AC coverage
pnpm lint:*script exists and runs strict checklint:ui:no-css-class-driftruns audit; exit 1 on findings (adversarial test); naming deviation documented abovepnpm checkincludes itpackage.json:234— chain ends with&& pnpm lint:ui:no-css-class-drift.github/workflows/ci.ymllintjob runspnpm check→ gate → exit 1 on drift (demonstrated by adversarial test)Test plan
pnpm install(worktree was fresh; dependencies installed)node scripts/audit-css-class-drift.mjsbaseline: 0 orphans, exit 0pnpm checkfull chain passes locally (~15s total)pnpm lint:ui:no-css-class-driftruns in isolation: exit 0lintjob passes on PR🤖 Generated with Claude Code