Skip to content

feat(ci): CSS class consistency build-time gate — fail build on undefined class references (#2503)#2516

Merged
alexey-pelykh merged 1 commit intomainfrom
feat/2503-css-class-drift-gate
Apr 24, 2026
Merged

feat(ci): CSS class consistency build-time gate — fail build on undefined class references (#2503)#2516
alexey-pelykh merged 1 commit intomainfrom
feat/2503-css-class-drift-gate

Conversation

@alexey-pelykh
Copy link
Copy Markdown

Summary

Closes #2503.

Baseline verification (AC: "All findings from D-1 resolved BEFORE wiring")

On main at branch base (20984fb998):

CSS class drift audit
  CSS files (import graph): 14
  TS/TSX files scanned:     118
  Classes defined:          733
  Classes referenced:       403
  Orphans:                  0

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 check run 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-probe into ui/src/main.ts

Orphans: 1
ELIFECYCLE Command failed with exit code 1.

Post-revert: Orphans: 0, exit 0. Gate catches drift; pnpm check fails on any class reference with no matching rule.

Script naming deviation

Issue #2503 AC line 6 suggests pnpm lint:css-classes. Project convention is lint:<area>:<predicate>, established by:

  • lint:ui:no-raw-window-open
  • lint:tmp:no-random-messaging
  • lint:plugins:no-monolithic-plugin-sdk-entry-imports

Used lint:ui:no-css-class-drift to match — ui area scope (the check scans ui/src/**/*.{ts,tsx,html} and ui/src/styles.css import graph), no-<thing> negated-predicate form. The issue's lint:css-classes was a proposed name in an "Implementation plan" section; the AC is about the check running in pnpm check, which this PR delivers.

AC coverage

AC Status Evidence
pnpm lint:* script exists and runs strict check ✅ adapted lint:ui:no-css-class-drift runs audit; exit 1 on findings (adversarial test); naming deviation documented above
pnpm check includes it package.json:234 — chain ends with && pnpm lint:ui:no-css-class-drift
CI fails on new undefined class reference .github/workflows/ci.yml lint job runs pnpm check → gate → exit 1 on drift (demonstrated by adversarial test)
All D-1 findings resolved before wiring Baseline audit on branch: 0 orphans
Documented in CLAUDE.md Two bullets added (see diff)
False-positive rate < 5% 0/403 = 0% on current codebase

Test plan

  • pnpm install (worktree was fresh; dependencies installed)
  • node scripts/audit-css-class-drift.mjs baseline: 0 orphans, exit 0
  • pnpm check full chain passes locally (~15s total)
  • pnpm lint:ui:no-css-class-drift runs in isolation: exit 0
  • Adversarial test: fake orphan injection → audit reports 1 orphan, pnpm exits 1
  • CLAUDE.md renders correctly (markdown preview)
  • CI lint job passes on PR

🤖 Generated with Claude Code

…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>
@alexey-pelykh alexey-pelykh merged commit 588e946 into main Apr 24, 2026
15 checks passed
@alexey-pelykh alexey-pelykh deleted the feat/2503-css-class-drift-gate branch April 24, 2026 06:25
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.

feat(ci): CSS class consistency build-time gate — fail build on undefined class references

1 participant