✅ Post-Change Validation Workflow
Chạy workflow này sau BẤT KỲ thay đổi nào đến token JSON, CSS, hoặc HTML.
Why this exists: Design systems have many interdependent files (token JSON → CSS variables → HTML docs → showcases). A change in one layer can silently break another. This workflow codifies the validation sequence so nothing slips through.
Quick navigation:
- Need to validate? → Steps
- Got errors? → Xử lý kết quả or Error Decision Tree
- Need report format? → Pipeline Summary Format +
token-reviewer§7 - Adapting to new project? → Project Config
⚠️ PHẢI đọc skills trước khi fix
| Loại violation | Skill BẮT BUỘC đọc | Why |
|---|---|---|
| Hardcode CSS values | token-reviewer § 2 + §7 Compliance Report Template |
Has mapping tables for exact token substitutions |
| bg/fg pairing | component-lifecycle § 3 |
Canonical source for color pairing rules |
| Token architecture | token-governance § 3 |
Reference chain and tier rules |
| Component gaps | component-lifecycle § 1-4 |
Completeness standards |
| DS gap phát hiện khi validate | token-governance §8 Gap Report → HỎI User |
New tokens need approval before creation |
| Showcase CSS naming | new-showcase.md Appendix B — CSS Naming |
Elevation naming, token contract, new value escalation |
| Component/CSS/HTML/Showcase | ux-research §6 Typography + §7 A11y + §5 Component |
Font-size ≥14px (T1), ARIA roles, focus ring, keyboard nav, interaction states |
🚨 GENERATED FILES — KHÔNG BAO GIỜ sửa trực tiếp
Các file trong docs/assets/ là output generated — sẽ bị ghi đè khi pipeline chạy. PHẢI sửa file source gốc:
| Generated file (❌ KHÔNG sửa) | Source of truth (✅ SỬA ở đây) | Script tạo |
|---|---|---|
docs/assets/components.css |
design-system/scripts/docs-template/preview-extras.css |
build-docs.js |
docs/assets/docs.css |
design-system/scripts/docs-template/docs.css |
build-docs.js (copy) |
docs/assets/docs.js |
design-system/scripts/docs-template/docs.js |
build-docs.js (copy) |
docs/assets/variables.css |
design-system/tokens/ |
sync-tokens.js |
docs/components/*.html |
design-system/components md/*.md |
build-docs.js |
design-system/scripts/pipeline-state.json |
Auto-generated by pipeline | run-pipeline.js |
design-system/scripts/ux-cross-ref-state.json |
Auto-generated — knowledge cross-ref accumulator | ux-review.js |
Steps
// turbo-all
🚀 Preferred: Unified Pipeline Runner (1 command)
node design-system/scripts/pipeline/run-pipeline.js --all
Hoặc với smart skip (tự detect file type → skip steps không cần):
node design-system/scripts/pipeline/run-pipeline.js --auto
Khi nào dùng individual steps? Chỉ khi cần debug 1 step cụ thể hoặc re-run từ step N:
node design-system/scripts/pipeline/run-pipeline.js --from=4
Individual Steps (reference)
1. Sync tokens
node design-system/scripts/pipeline/sync-tokens.js --all
2. TW Build (Tailwind CSS compile)
npx @tailwindcss/cli --input design-system/tailwind.css --output design-system/dist/prisma.css --minify
→ Compiles tailwind.css (imports variables.css + @theme) → dist/prisma.css
→ PHẢI chạy sau step 1 (vì TW import variables.css do sync sinh ra)
→ Nếu fail: kiểm tra tailwind.css syntax, @theme block, hoặc variables.css format
3. Build docs
node design-system/scripts/docs/build-docs.js
4. Lint CSS + HTML (incl. bg/fg pairing)
node design-system/scripts/pipeline/lint-css.js --all
→ PHẢI đạt 0 violations (bao gồm cả bg/fg pairing trên CSS classes, inline styles, pseudo-elements)
→ Nếu có bg/fg-pair violations → đọc component-lifecycle/references/token-naming-states.md §2 trước khi fix
→ Format kết quả theo token-reviewer SKILL.md §7 Compliance Report Template
5. UX Review (Knowledge-driven validation + Knowledge Cross-Reference)
node design-system/scripts/pipeline/ux-review.js
→ Validates CSS/HTML against knowledge-rules.json (extracted from ux-research skill + research docs)
→ Inline staleness check: auto-touches knowledge-rules.json timestamp if source files are newer
→ Checks: font-size T1, heading T4, uppercase T9, font-family T5, focus ring F1, ARIA patterns, touch targets R3, viewport R4, reduced motion M1, surface dividers S8/D9, consecutive dividers D2, breathing room D5, divider-between-cards D6, slot anatomy B1, CSS naming
→ Also scans inline style="" attributes in HTML for border-top/bottom divider violations
→ MANDATORY Knowledge Cross-Reference: Scans knowledge/ux-audit-*.md for previous audit findings
→ Recurring Issue Detection: Matches current violations against historical rules — flags issues found in previous audits
→ Severity Escalation: Critical issues open > 7 days → BLOCKER (pipeline FAIL). Warnings open > 14 days → CRITICAL
→ Feedback Loop: Writes findings to ux-cross-ref-state.json — accumulates across pipeline runs, tracks first-seen dates
→ PHẢI đạt 0 critical violations AND 0 blocker escalations
→ Nếu có violations → đọc ux-research skill trước khi fix
6. Verify output (E2E + drift detection + var refs)
node design-system/scripts/pipeline/verify-output.js
→ Full end-to-end check: Token JSON → CSS → HTML roundtrip, structure, coherence
→ Also includes drift checks: content drift, manual edit detection, orphan CSS vars
→ Also checks CSS units (ms/px/unitless) and variable reference integrity
→ PHẢI đạt 0 errors
→ Nếu có lỗi: chạy node design-system/scripts/pipeline/verify-output.js --fix để auto-fix
→ Nếu vẫn lỗi sau --fix: fix thủ công → chạy lại từ step 1
→ Nếu có drift: chạy sync-tokens.js --core trước → chạy lại từ step 1
7. Audit component completeness (auto-maps new components)
node design-system/scripts/pipeline/audit-components.js --auto-map
→ Cross-checks ATOMIC-MAPPING.md ↔ component docs ↔ CSS classes → Auto-map: Nếu phát hiện component mới chưa có mapping, tự tạo entry + inject reference
7b. Showcase + Docs + Style/Theme check (nếu file liên quan bị sửa)
Note: Step 7b kiểm tra thủ công, không nằm trong pipeline runner.
Showcase — nếu file trong showcase/:
☐ Class names theo elevation convention? (ground-/card-/surface-/item-)
☐ Không đặt tên theo business data? (card-account ✅, balance-card ❌)
☐ bg/fg/border dùng token, không hardcode rgba()?
☐ New values dùng --local-{showcase}-* prefix?
☐ Không sửa file trong design-system/tokens/ mà không User approve?
☐ HTML dùng data-slot attributes cho structural slots? (ENF-6)
→ data-slot="card", data-slot="card-header", data-slot="card-content"...
📖 Full rules: new-showcase.md Appendix B — CSS Naming
Docs template — nếu sửa preview-extras.css, components.css, hoặc component-previews.js:
☐ Preview HTML dùng DS component class/token, KHÔNG tự tạo inline component?
☐ Component references đều tồn tại trong DS whitelist (ATOMIC-MAPPING.md)?
☐ Preview HTML có data-slot attributes trên slot elements? (ENF-6)
Style/theme — nếu sửa styles/*.json hoặc themes/*.json:
☐ Component token refs (--comp-*) đều trỏ tới comp đã có spec trong DS core?
☐ Không tạo token cho component chưa tồn tại? (tạo spec trước via component-lifecycle)
Component spec — nếu sửa design-system/components md/*.md:
☐ Component có ## Slot Map (Figma ↔ Code) section? (ENF-6)
☐ Slot names match slot-manifest.json? (ENF-6)
☐ Component có entry trong code-connect.config.json? (ENF-6)
→ Nếu KHÔNG → thêm entry mới
7. Xử lý kết quả
📖 Full decision tree: Error Decision Tree bên dưới
Decision Matrix:
| Outcome | Action | Restart from |
|---|---|---|
| 0 errors, 0 violations | ✅ PASS — production-ready | — |
| TW build fail (step 2) | Check tailwind.css syntax, @theme block |
Step 1 |
| CSS violations (step 4) | Dùng skill token-reviewer để fix |
Step 4 |
| UX violations (step 5) | Dùng skill ux-research để fix |
Step 5 |
| bg/fg-pair violations (step 4) | Dùng skill component-lifecycle § 3 để fix |
Step 4 |
| Verify/drift errors (step 6) | Chạy --fix trước → nếu drift → sync-tokens.js --core |
Step 1 |
| Audit gaps (step 7) | Dùng skill component-lifecycle để bổ sung |
Step 1 |
Error Escalation:
Single violation → Fix with companion skill → BLAST RADIUS CHECK → Re-validate
Multiple violations → Batch fix by file + type → BLAST RADIUS CHECK → Re-validate from Step 1
Structural error → Manual investigation → Re-validate from Step 1
DS gap discovered → Report to User → Wait for approval → Create tokens → Re-validate
🔴 BLAST RADIUS CHECK — BẮT BUỘC sau mỗi fix
Nguyên tắc: Khi fix 1 violation ở file A, cùng violation đó có thể tồn tại ở file B, C, D. KHÔNG BAO GIỜ fix chỉ 1 chỗ rồi dừng. Phải scan TOÀN BỘ project cho cùng pattern.
Quy trình:
1. Fix violation tại file X
2. XÁC ĐỊNH pattern — violation này thuộc loại gì? (font-size, hardcode, ARIA, etc.)
3. GREP toàn bộ project cho cùng pattern:
- font-size violation → grep "font-size-xs" trong TẤT CẢ CSS files
- hardcode violation → grep "px\|rem\|#[0-9a-f]" trong TẤT CẢ CSS files
- ARIA violation → grep tất cả interactive components thiếu role/aria-*
- Token violation → chạy lint-css.js --all (không chỉ file vừa sửa)
4. FIX TẤT CẢ occurrences — batch fix, không fix từng cái
5. RE-VALIDATE toàn bộ → chạy pipeline lại
Ví dụ thực tế:
❌ SAI: Fix .custom-select-option font-size 12px → 14px. Done.
(bỏ sót .dropdown-item cũng 12px)
✅ ĐÚNG: Fix .custom-select-option font-size 12px → 14px.
→ Grep "--font-size-xs" toàn bộ preview-extras.css
→ Phát hiện .dropdown-item cũng dùng xs
→ Fix luôn .dropdown-item
→ Chạy lint-css.js --all
→ Done.
Anti-patterns
| ❌ Don't | ✅ Do | Why |
|---|---|---|
| Skip steps when "it's a small change" | Run all steps from the trigger point | Small changes cause cascading breaks |
| Fix violations without reading the companion skill | Read the skill first, then fix | Prevents wrong token substitutions |
| Auto-modify token JSON when drift is detected | Report proposals to User | Token architecture decisions need human approval |
| Run steps out of order | Follow 1→2→3→4→5→6 sequence | Each step depends on the previous step's output |
| Treat warnings as non-issues | Log warnings, plan fixes | Warnings become errors over time |
| Fix violations one-by-one | Batch fix by file + type | Minimizes review cycles and context switches |
| Fix chỉ file đang sửa, bỏ qua files khác | Blast radius check — grep cùng pattern toàn project | Cùng violation tồn tại ở nhiều file |
| Fix xong 1 chỗ rồi declare done | Chạy lint-css.js --all, không chỉ file vừa sửa | Chỉ validate 1 file = miss violations ở files khác |
Pipeline Summary Format
After running the full 6-step pipeline, summarize with:
PIPELINE SUMMARY:
┌──────────────────────────────┬─────────┐
│ Step │ Result │
├──────────────────────────────┼─────────┤
│ 1. Sync tokens │ ✅ PASS │
│ 2. TW Build │ ✅ PASS │
│ 3. Build docs │ ✅ PASS │
│ 4. Lint CSS/HTML │ ✅ PASS │
│ 5. UX Review │ ✅ PASS │
│ 6. Verify output + drift │ ✅ PASS │
│ 7. Audit components │ ✅ PASS │
└──────────────────────────────┴─────────┘
VERDICT: ✅ ALL PASS — production-ready
Compliance Report format: Use
token-reviewerSKILL.md §7 template. PASS = 0 errors, bg/fg 100%.
📎 Appendix A — Error Decision Tree
Full decision tree for handling validation pipeline results.
Master Flow
START: File changed
│
├─ Determine start step (see Trigger Rules above)
│
▼
┌─────────────────┐
│ Step 1: Sync │──→ ERROR? → Check token JSON syntax → Fix → Restart Step 1
└────────┬────────┘
▼
┌─────────────────┐
│ Step 2: TW Build │──→ ERROR? → Check tailwind.css / @theme → Fix → Restart Step 1
└────────┬────────┘
▼
┌─────────────────┐
│ Step 3: Build │──→ ERROR? → Check template/script → Fix → Restart Step 3
└────────┬────────┘
▼
┌─────────────────────────┐
│ Step 4: Review CSS/HTML │──→ VIOLATIONS?
└────────┬────────────────┘ │
│ ├─ Hardcoded values → Read token-reviewer → Fix → Re-run Step 4
│ ├─ bg/fg pair errors → Read component-lifecycle §3b → Fix → Re-run Step 4
│ └─ Multiple types → Group by file → Fix all → Re-run Step 4
▼
┌─────────────────────────┐
│ Step 5: UX Review │──→ VIOLATIONS?
└────────┬────────────────┘ │
│ ├─ UX rule violations → Read ux-research skill → Fix → Re-run Step 5
│ ├─ ARIA missing → Add required roles/attrs → Re-run Step 5
│ └─ Naming violations → Apply elevation prefix → Re-run Step 5
▼
┌─────────────────────────────────┐
│ Step 6: Verify Output + Drift │──→ ERRORS?
└────────┬────────────────────────┘ │
│ ├─ Auto-fixable → Run --fix → Re-check
│ │ ├─ Fixed → Continue to Step 7
│ │ └─ Still errors → Manual fix → Restart Step 1
│ ├─ Drift detected → Run sync-tokens --core → Restart Step 1
│ └─ Not auto-fixable → Manual fix → Restart Step 1
▼
┌─────────────────────────┐
│ Step 7: Audit Components │──→ GAPS?
└────────┬────────────────┘ │
│ ├─ Missing tokens → Read component-lifecycle → Add → Restart Step 1
│ └─ New component needed → Read token-governance → Ask User → Create
▼
┌─────────────┐
│ ✅ ALL PASS │──→ Pipeline complete → Chain to dev-journal
└─────────────┘
Multi-Error Priority
When multiple steps fail, fix in this order:
- Step 1 (Sync) — fixes here often resolve Step 4–7 issues automatically
- Step 2 (TW Build) — if TW fails, dist/prisma.css is stale
- Step 6 (Verify + Drift) — structural errors block everything downstream
- Step 4 (Lint CSS) — fix remaining CSS violations
- Step 5 (UX Review) — fix UX rule violations
- Step 7 (Audit) — completeness issues are lowest urgency
Why this order? Earlier pipeline stages generate outputs consumed by later stages. Fixing upstream first prevents "chasing ghosts" — errors that disappear once the source is corrected.
Infinite Loop Prevention
If you find yourself restarting from Step 1 more than 3 times:
- Stop — there's likely a systemic issue
- Check script compatibility — are sync-tokens and verify-output using the same format?
- Check for circular references — token A → token B → token A
- Check for manual CSS edits — someone may have edited the generated CSS file directly
- Report to User — explain what's cycling and ask for guidance
DS Gap Discovery During Validation
Gap discovered → Check token-governance §8 (Gap Report)
│
├─ Is it a primitive? → MUST get User approval (new primitives are high-impact)
├─ Is it a semantic token? → Propose to User with rationale
└─ Is it a component token? → Can be created if it follows existing patterns
After User approval:
→ Create token following token-governance rules
→ Restart pipeline from Step 1
→ Log in dev-journal with type "ds-gap"
Emergency Bypass
In rare cases where the pipeline blocks urgent work:
- Document the bypass — create a dev-journal entry explaining why
- Create a follow-up task — "Run full validation and fix issues"
- Never bypass silently — the whole point of this pipeline is to catch issues before they propagate
📎 Appendix B — Project Config
How to adapt the post-change validation workflow to different design system projects.
Default Script Mapping
| Step | Default Path | Purpose |
|---|---|---|
| 1 | design-system/scripts/pipeline/sync-tokens.js |
Token JSON → CSS custom properties |
| 2 | @tailwindcss/cli |
Tailwind compile → dist/prisma.css |
| 3 | design-system/scripts/docs/build-docs.js |
Token data → HTML documentation |
| 4 | design-system/scripts/pipeline/lint-css.js |
CSS/HTML code quality linter (unified) |
| 5 | design-system/scripts/pipeline/ux-review.js |
Knowledge-driven UX validation + staleness |
| 6 | design-system/scripts/pipeline/verify-output.js |
E2E roundtrip + drift detection |
| 7 | design-system/scripts/pipeline/audit-components.js |
Component completeness audit |
CLI Flags
| Script | Important flags |
|---|---|
| sync-tokens.js | --all, --core, --dry-run |
| lint-css.js | --all, --docs, --templates, or pass file path |
| ux-review.js | --scope=docs, --scope=explore, --rules=T1,F1, --fix, --json |
| verify-output.js | --fix, --verbose, --json |
| audit-components.js | --auto-map, --json, --fix-plan |
Project Structure
project-root/
├── design-system/
│ ├── tokens/ # Token JSON source of truth
│ │ ├── primitives/ # Base scale values
│ │ ├── semantic/ # Theme-aware tokens
│ │ ├── components/ # Component-scoped tokens
│ │ └── variables.css # Generated CSS output
│ └── scripts/
│ ├── config/
│ │ └── showcase-config.json # Showcase registry
│ ├── pipeline/ # Build pipeline scripts
│ └── docs/ # Doc generation scripts
├── docs/ # Generated documentation
└── showcase/ # Showcase apps
Adapting
- Different token dir: Update
sync-tokens.jsto point to your token root - No showcases: Steps 1 + 3 can run on a single CSS output
- Monorepo: Run from the package root containing the design system
Adding New Validation Steps
Recommended insertion points:
- After Step 3: Visual regression, accessibility checks
- After Step 5: Performance, bundle size, API compatibility