-
Notifications
You must be signed in to change notification settings - Fork 0
Home
github-actions[bot] edited this page Sep 5, 2026
·
19 revisions
Welcome to the Charites Static Analysis Rule Catalog. Charites is an ultra-fast, zero-CGO, zero-Node.js static analysis compiler for Astro, React TSX, and Tailwind CSS design tokens.
| Category | Rules Count | Documentation |
|---|---|---|
theme |
15 | theme |
| Rule ID | Category | Severity | Description | Documentation |
|---|---|---|---|---|
theme.backdrop-blur-hardcode |
theme |
WARN |
Detects hardcoded arbitrary blur and backdrop-blur scalars in Tailwind utility classes | theme.backdrop-blur-hardcode |
theme.focus-ring-hardcode |
theme |
WARN |
Detects hardcoded primitive palette or arbitrary hex colors on focus rings and outlines | theme.focus-ring-hardcode |
theme.gradient-hardcode |
theme |
WARN |
Detects hardcoded primitive, arbitrary hex, or monochrome colors in gradient stops | theme.gradient-hardcode |
theme.hardcode-border-color |
theme |
WARN |
Detects hardcoded border and divider colors using primitive palettes, raw hex literals, or static monochrome | theme.hardcode-border-color |
theme.hardcode-border-radius |
theme |
WARN |
Detects hardcoded arbitrary border-radius scalars in Tailwind utility classes | theme.hardcode-border-radius |
theme.hardcode-color |
theme |
WARN |
Detects hardcoded arbitrary hex or rgb color literals in Tailwind utility classes and arbitrary properties | theme.hardcode-color |
theme.hardcode-monochrome |
theme |
WARN |
Detects hardcoded monochrome utilities (white/black) that fail to adapt across light and dark themes | theme.hardcode-monochrome |
theme.hardcode-opacity-color |
theme |
ERROR |
Detects utility classes with hardcoded slash opacity modifiers that have official semantic token replacements | theme.hardcode-opacity-color |
theme.hardcode-shadow-color |
theme |
WARN |
Detects hardcoded color literals embedded in box-shadow declarations | theme.hardcode-shadow-color |
theme.hardcode-size |
theme |
WARN |
Detects hardcoded arbitrary size, spacing, or typography scalars in Tailwind utility classes | theme.hardcode-size |
theme.hardcode-z-index |
theme |
WARN |
Detects hardcoded arbitrary z-index scalars that trigger stacking context wars | theme.hardcode-z-index |
theme.important-override |
theme |
ERROR |
Detects !important modifiers on color utility classes that break theme cascade and specificity hierarchy | theme.important-override |
theme.inline-style-hardcode |
theme |
ERROR |
Detects hardcoded color literals inside HTML/JSX style attributes that prevent theme cascade | theme.inline-style-hardcode |
theme.primitive-in-component |
theme |
ERROR |
Detects direct usage of Tailwind primitive palette colors in component classes instead of semantic tokens | theme.primitive-in-component |
theme.pseudo-hardcode-color |
theme |
WARN |
Detects hardcoded primitive, arbitrary hex, or monochrome colors inside pseudo-element and pseudo-class variants | theme.pseudo-hardcode-color |
Charites processes project source code and design tokens through a unified 4-stage pipeline:
flowchart LR
subgraph Discovery ["1. Source & SSOT Discovery"]
TargetFiles["Target Files (*.astro, *.tsx)"]
TokensSSOT["Design Tokens SSOT (global.css, tokens.json)"]
end
subgraph Pipeline ["2. Extraction & Graph"]
TargetFiles --> Scanner["Fast Walker & Worker Pool (internal/scanner)"]
Scanner --> Parser["AST & IR Builder (internal/parser)"]
TokensSSOT --> TokenEngine["Token Subsystem (internal/token)"]
TokenEngine --> Graph["Directed Token Dependency Graph"]
end
subgraph Engine ["3. Static Analysis Across Categories"]
Parser --> Analyzer["IR Traversal Engine (internal/analyzer)"]
Graph --> Context["Read-Only Token Context Facade"]
Analyzer <--> RulesTheme["Theme Rules (internal/rules/theme)"]
Analyzer <--> RulesA11y["A11y Rules (internal/rules/a11y)"]
Analyzer <--> RulesResp["Responsive & Perf Rules"]
Context -.-> RulesTheme
Context -.-> RulesA11y
end
subgraph Output ["4. Reporting"]
RulesTheme --> Reporter["Reporter Engine (Terminal ANSI, JSON, MCP)"]
RulesA11y --> Reporter
RulesResp --> Reporter
end
-
Target Discovery & AST Construction:
internal/scannerdiscovers and walks workspace source files in parallel, streaming.astroand.tsxcomponents tointernal/parserto construct normalizedir.Nodestructures. -
Multi-Format SSOT Token Graph:
internal/tokenauto-discovers design token sources across both CSS (global.css,index.css,@theme) and JSON manifests (tokens.jsonW3C DTCG format). It parses custom properties (--*), nested themes (:root,.dark), and variable references (var(--...)), constructing a design-agnosticDirected Token Dependency Graphwith visited-set cycle detection and recursion budget limits. -
Stateless Traversal & Multi-Category Evaluation:
internal/analyzercoordinates parallel IR node traversal across modular rule domains:-
Theme Governance (
internal/rules/theme): Validates utility classes, stripping variants and ensuring opacity/color modifications use official semantic tokens declared in the graph. -
Accessibility Verification (
internal/rules/a11y): Replaces legacy regex heuristics (migrated fromcharites-legacy/a11y-checker.ts) with AST-grounded validation of label/input bindings, heading hierarchies, missing alt-text, and token-resolved WCAG 2.2 color contrast ratios. -
Responsive & Performance (
internal/rules/{responsive,perf}): Enforces Fitts's Law touch target ergonomics (>= 44x44px), modern@containerqueries, and Core Web Vitals (LCP, CLS, INP).
-
Theme Governance (
- Multi-Channel Delivery: Diagnostics are deterministically rendered for ANSI terminal output, streaming JSON envelopes, or MCP JSON-RPC 2.0 tool calls.
Charites enforces correctness, resilience, and zero false positives across four interconnected testing tiers:
flowchart TD
subgraph Suite ["The 4-Layer Verification Harness"]
subgraph L1 ["Layer 1: Unit & Subsystem Tests"]
U1["CSS Lexer & Parser Tests (internal/token/theme)"]
U2["Token Graph Cycles & DoS Budget (internal/token)"]
U3["Extractor & Scope Specificity (internal/token)"]
U4["IR Parser & AST Visitors (internal/parser)"]
end
subgraph L2 ["Layer 2: 1-SSOT Golden Tri-Corpus"]
G1["Positive (P1-P5): Verified true positives with exact line & span"]
G2["Negative (N1-N5): Zero false positives on valid tokens & Banana Test"]
G3["Adversarial (A1-A7): Resilience to cyclic vars, ternaries, obfuscation"]
end
subgraph L3 ["Layer 3: Monorepo Integration"]
I1["Upward Directory Discovery: global.css from nested subdirectories"]
I2["Multi-Scope Theme Switching: :root vs .dark resolution"]
I3["E2E CLI Parity: Terminal ANSI, Streaming JSON, MCP JSON-RPC 2.0"]
end
subgraph L4 ["Layer 4: Continuous Fuzz Testing"]
F1["Native Go 1.26 Fuzzing (tests/fuzz/css_fuzz_test.go)"]
F2["14,000+ Synthetic CSS Mutations: Zero Panics, Zero OOM, Zero Leaks"]
end
end
L1 --> L2
L2 --> L3
L3 --> L4
-
Layer 1 (Subsystem Units): Validates deterministic lexing, zero-panic parsing, graph cycle detection (
ErrCycleDetected), and traversal recursion budget limits (ErrEvaluationBudgetExceeded). -
Layer 2 (1-SSOT Golden Tri-Corpus): Every static analysis rule is tested against an exhaustive 17-pattern matrix in
tests/correctness/<rule-id>/:- Positive (P1-P5): Obvious, indirect, helper-wrapped, deeply nested, and aliased violations.
- Negative (N1-N5): Valid tokens, explicit ignore directives, third-party libraries, standard HTML, and untokenized custom values (the Banana Test).
- Adversarial (A1-A7): Template literal interpolations, ternary conditionals, spread props, dynamic classes, variable shadowing, and cyclic references.
-
Layer 3 (Monorepo Integration): Validates end-to-end multi-scope token resolution (
:rootvs.dark), upward directory walks, and CLI output rendering intests/token_integration_test.go. -
Layer 4 (Continuous Fuzzing): Employs native Go 1.26 fuzzing (
tests/fuzz/css_fuzz_test.go) over tens of thousands of malformed mutations to guarantee memory safety and crash resilience.
- Deterministic Execution: Pure-function AST visitors without file system or network I/O during evaluation.
- SSOT Token Evidence: Static rules only enforce semantic token replacements that genuinely exist in the project's token dependency graph.
-
1-SSOT Tri-Corpus Assurance: Every rule is validated against a 3-part golden test corpus (
positive/,negative/,adversarial/). -
Canonical Semgrep Identifiers: All rules follow the
<category>.<slug>standard.
A11y (16 rules)
- A11y Overview
a11y.button-type-missinga11y.dialog-missing-ariaa11y.empty-interactivea11y.error-not-announceda11y.form-input-missing-namea11y.form-label-composite-controla11y.form-label-missing-controla11y.img-missing-alta11y.input-cramped-paddinga11y.input-ios-zoom-hazarda11y.keyboard-trap-missing-escapea11y.label-missing-controla11y.missing-focus-ringa11y.placeholder-as-labela11y.touch-target-sizea11y.touch-target-spacing
Browser (12 rules)
- Browser Overview
browser.appearance-native-overridebrowser.chrome-only-apibrowser.date-input-format-assumptionbrowser.experimental-api-no-featuredetectbrowser.firefox-only-apibrowser.hover-only-interactionbrowser.non-passive-scroll-listenerbrowser.obsolete-vendor-prefixbrowser.safari-only-apibrowser.scrollbar-vendor-incompletebrowser.user-agent-sniffingbrowser.webkit-only-api
Cls (16 rules)
- Cls Overview
cls.client-only-hydration-popcls.collapsible-height-jumpcls.dynamic-content-without-reserved-spacecls.dynamic-table-reflowcls.font-display-missingcls.font-import-late-discoverycls.layout-trigger-animationcls.layout-trigger-transitioncls.text-icon-late-reflowcls.unadjusted-font-metriccls.unconstrained-carouselcls.unreserved-ad-containercls.unreserved-fixed-headercls.unsized-embed-framecls.unsized-imagecls.unstable-scrollbar-gutter
Design (1 rules)
Ergonomy (5 rules)
Inp (16 rules)
- Inp Overview
inp.context-re-render-cascadeinp.expensive-render-computationinp.expensive-style-mutationinp.heavy-event-handlerinp.hydration-contentioninp.hydration-heavy-islandinp.large-interaction-layout-scopeinp.layout-thrashinginp.missing-start-transitioninp.missing-touch-actioninp.render-blocking-scriptinp.repeated-state-updateinp.sync-layout-effectinp.unbounded-collection-renderinp.unbounded-effect-depsinp.unyielded-long-task
Lcp (16 rules)
- Lcp Overview
lcp.blocked-critical-fontlcp.client-only-lcp-contentlcp.critical-head-style-bloatlcp.external-font-discovery-delaylcp.heavy-raster-lcp-assetlcp.image-source-density-mismatchlcp.lazy-loaded-lcp-imagelcp.lcp-content-visibility-suppressionlcp.legacy-critical-font-resourcelcp.missing-critical-origin-hintlcp.missing-lcp-image-preloadlcp.oversized-lcp-resource-selectionlcp.preload-font-cors-mismatchlcp.render-blocking-head-scriptlcp.undiscoverable-lcp-imagelcp.unhinted-lcp-image-priority
Mobile (5 rules)
Performance (16 rules)
- Performance Overview
performance.astro-island-boundary-overlapperformance.astro-over-prefetchingperformance.astro-unnecessary-client-directiveperformance.astro-unoptimized-local-imageperformance.react-context-domain-couplingperformance.react-derived-state-in-effectperformance.react-effect-missing-cleanupperformance.react-index-as-keyperformance.react-inline-prop-memoperformance.react-redundant-function-memoizationperformance.react-static-heavy-importperformance.react-unstable-hook-referenceperformance.tailwind-duplicate-arbitrary-rulesperformance.tailwind-duplicate-utility-definitionperformance.tailwind-dynamic-class-concatenationperformance.tailwind-untracked-package-source
Pwa (10 rules)
- Pwa Overview
pwa.apple-meta-missingpwa.icon-maskable-missingpwa.insecure-context-resourcepwa.manifest-missingpwa.manifest-required-fields-missingpwa.pwa-cache-runtime-api-riskpwa.service-worker-missingpwa.service-worker-no-offline-fallbackpwa.service-worker-registrationpwa.start-url-inconsistency
Responsive (18 rules)
- Responsive Overview
responsive.aspect-ratio-overflowresponsive.container-overconstraintresponsive.desktop-only-contentresponsive.dynamic-viewport-inconsistencyresponsive.fixed-width-overflowresponsive.flex-child-overflowresponsive.fractional-width-gap-driftresponsive.grid-min-columnresponsive.horizontal-overflowresponsive.image-overflowresponsive.keyboard-obstructionresponsive.missing-breakpointresponsive.mobile-density-overloadresponsive.mobile-text-overflowresponsive.safe-area-missingresponsive.unwrapped-table-overflowresponsive.viewport-meta-missingresponsive.viewport-unit-leak
Semantic (1 rules)
Theme (32 rules)
- Theme Overview
theme.apply-bloattheme.backdrop-blur-hardcodetheme.chart-color-hardcodetheme.dual-strategy-collisiontheme.dynamic-classtheme.focus-ring-hardcodetheme.gradient-hardcodetheme.hardcode-border-colortheme.hardcode-border-radiustheme.hardcode-colortheme.hardcode-monochrometheme.hardcode-opacity-colortheme.hardcode-shadow-colortheme.hardcode-sizetheme.hardcode-z-indextheme.hydration-theme-mismatchtheme.image-theme-hardcodetheme.important-overridetheme.inline-style-hardcodetheme.meta-theme-color-mismatchtheme.missing-color-schemetheme.missing-token-fallbacktheme.nested-opacity-contrasttheme.no-reduced-motiontheme.primitive-in-componenttheme.pseudo-hardcode-colortheme.shadow-without-border-darktheme.split-theme-statetheme.svg-hardcode-filltheme.token-source-drifttheme.unlayered-token-definitiontheme.unpaired-dark-variant
Ux (20 rules)
- Ux Overview
ux.camouflaged-linkux.competing-primary-ctaux.destructive-action-unconfirmedux.disabled-control-no-explanationux.empty-collection-unhandledux.missing-autofillux.monolithic-form-bloatux.multiline-input-misuseux.nav-overflow-chunkingux.number-input-identity-misuseux.number-input-missing-boundsux.orphaned-error-stateux.radio-overchoiceux.silent-catch-swallowux.spacing-inversionux.spacing-rhythm-driftux.submit-feedback-missingux.unbounded-async-flagux.unconventional-home-linkux.unthrottled-input-handler