ADR Plan + Migration Plan
Two related artifacts in one document. The ADR plan lists architectural decision records to write, in priority order. The migration plan describes the step-by-step transition from v0.1.0 to v1.0.
Part 1 — ADR plan
Status of existing ADRs
- ADR-0001 — Brand seeds outrank algorithmic stops ✅
- ADR-0002 — Status color symmetry ✅
- ADR-0003 — Patterns over tokens ✅
- ADR-0004 — Component delivery model ✅
- ADR-0005 — Token group lifecycle (added during Phase 2 close) ✅
New ADRs to write (in execution order)
ADR-0006 — Component classification by functional role
Documents the four-layer model (Foundations / Elements / Blocks / Sections), the decision tables for layer assignment, and the rationale for treating Avatar as Foundation, Tabs as Element, Alert as Element. References Section 1 + 2 quiz decisions.
Estimated length: 800-1000 words. Priority: critical (foundational architectural decision).
ADR-0007 — Modifier system as cross-cutting layer
Documents the 7 modifier categories, the variants vs modifiers syntactic split (BEM vs data-attributes), namespace separation rule, selective inheritance (rhythm + motion inherit, others don't), applicability matrix as JSON, custom modifier extension API.
Estimated length: 1200-1500 words. Priority: critical.
ADR-0008 — Token tier strict separation
Documents the three-tier model with the explicit rule that components never read foundations directly. Lint enforcement, naming conventions, theme-tier responsibility. References Section 8 quiz decisions.
Estimated length: 800-1000 words. Priority: critical.
ADR-0009 — Semantic typography naming
Documents the rejection of abstract sizes (xl, l, m, s) in favor of role-based naming (hero, statement, title, lead, regular, support). Includes the full token inventory and fluid scaling rule for display sizes. References Section 8 Q8.7.
Estimated length: 600-800 words. Priority: high.
ADR-0010 — Overlays as their own layer
Documents the decision to keep overlays as a discoverable category despite the conceptual elegance of "overlay as mode". File structure, documentation hierarchy, AGENTS.md organization. References Section 6 Q6.1.
Estimated length: 500-700 words. Priority: medium.
ADR-0011 — Iconography as pluggable packs
Documents the rejection of bundled icon library in favor of canonical name registry + adapter API. Default pack (Phosphor), pack switching, CSS mask-image rendering, documentation focus on icon selection principles.
Estimated length: 800-1000 words. Priority: medium.
ADR-0012 — Effects (CSS) vs Shaders (WebGL) split
Documents the two-tier visual enhancement system: CSS-only effects in core (grain, glow, ring, noise, blur), WebGL shaders in opt-in @malevich/shaders package. Explicit fallback contract, progressive enhancement philosophy.
Estimated length: 600-800 words. Priority: low (forward-looking, v2.0 scope).
ADR-0013 — Form subsystem separation
Documents Form-button + Form-divider + Field-group as distinct from generic Button + Divider. Rationale: form context constrains design; separation keeps generic components aesthetically free. References Section 3 Q3.18, Q3.19.
Estimated length: 600-800 words. Priority: medium.
ADR-0014 — Carousel scope discipline
Documents what Carousel ships in v1.0 (scroll-snap, pagination, prev/next) and what doesn't (auto-play, loop, fade, vertical). Why scope was narrowed for v1.0 reliability. References Section 4 Q4.4.
Estimated length: 400-600 words. Priority: low.
ADR-0015 — Card composition pattern
Documents the hybrid approach: one Card, semantic HTML tags (<article>, <aside>, <div>), data-pattern hints, named slots. Rejection of BlogCard/ProductCard/MetricCard multiplication. References Section 4 Q4.1.
Estimated length: 700-900 words. Priority: medium.
ADR writing schedule
- Pre-v0.2.0 (now): ADR-0006, 0007, 0008 (the three critical ones — they enforce the refactor)
- During v0.2.0: ADR-0009, 0013, 0015 (medium priority, support migration)
- During v1.0: ADR-0010, 0011, 0014 (medium-low, document implementation choices)
- Before v2.0: ADR-0012 (forward-looking for shaders)
Total: 10 new ADRs. With existing 5, the project will have 15 ADRs by v1.0 release.
Part 2 — Migration plan v0.1.0 → v1.0
Migration philosophy
We have no external users. Breaking changes are OK. The migration is internal-only and can be aggressive.
But we have ~150 tests we don't want to lose, and ~10 components with real implementation we don't want to rewrite from scratch. The migration preserves implementation while restructuring.
Migration phases
Phase M-1 — Documentation freeze (1-2 hours)
Before any code changes, capture the current state:
- Tag current main as
v0.1.0-baseline(already done — tag v0.1.0 exists) - Snapshot
packages/components/src/file structure - Snapshot
tokens/{foundations,semantic,component-specific}.json - Snapshot existing test names and counts
- Document current modifier usage (
.t-*tweaks, current data-attributes)
This baseline is reference for verifying migration completeness.
Phase M-2 — Architectural ADRs (4-8 hours)
Write ADR-0006, ADR-0007, ADR-0008 (the three critical ones). These ADRs:
- Are reviewed before code changes
- Become the spec for migration codemods
- Get linked from migration scripts
Output: 3 ADR files committed to llm-wiki/decisions/.
Phase M-3 — Token system migration (8-16 hours)
Most invasive change. Done first because everything else depends on it.
- Rewrite
packages/core/tokens/foundations.jsonwith proper nested structure (color/space/radius/shadow/font/duration/easing categories) - Rewrite
packages/core/tokens/semantic.jsonwith semantic groups (color.text, color.surface, color.border, etc.) - Update
packages/core/src/build.tsto emit flat CSS variables from nested JSON - Update
packages/core/src/types.tswith new type definitions - Update
packages/core/src/resolve.tsfor alias resolution in new structure - Update token tests to match new structure
- Run codemod over all component CSS to rename existing token references to new names
- Verify all components still compile and tests pass
Codemod script: scripts/migrate-tokens-v01-to-v1.mjs that:
- Reads mapping from
migration/token-rename-map.json - Walks all
*.cssfiles - Replaces old token names with new ones
- Reports any unmapped references for manual review
Phase M-4 — Modifier system rename (4-8 hours)
- Rename "tweak" → "modifier" throughout codebase
- Rename "treatment" category → "effect" in design vocabulary
- Rename
.t-prefix to data-attribute approach- Example:
.button.+glow-hover(already migrated to.button.t-glow-hover) becomesdata-effect="glow"on hover variant
- Example:
- Create
modifiers/applicability.jsonwith initial component → modifier mapping - Update existing component CSS to declare modifier namespaces (
--{component}-surface-*,--{component}-effect-*) - Update existing components to consume modifier variables correctly
Codemod script: scripts/migrate-modifiers-v01-to-v1.mjs for class renames and CSS variable namespace updates.
Phase M-5 — Component layer reorganization (8-16 hours)
File system moves with import path updates:
Move Avatar:
- From:
packages/components/src/elements/avatar/ - To:
packages/components/src/foundations/avatar/ - Update: All imports referencing avatar
- Update:
packages/components/src/index.tsexports - Update: docs site sitemap (when docs rebuilt)
- From:
Move Tabs:
- From:
packages/components/src/blocks/tabs/ - To:
packages/components/src/elements/interactive/tabs/ - Update: All imports, exports, runtime registrations
- From:
Move Alert:
- From:
packages/components/src/blocks/alert/ - To:
packages/components/src/elements/display/alert/ - Update: All imports, exports
- From:
Reorganize remaining Elements into sub-categories:
packages/components/src/elements/interactive/(Button, Tabs)packages/components/src/elements/form/(Input, Checkbox)packages/components/src/elements/display/(Badge, Alert)
Update tests to match new file paths (test imports)
Verify all 109 tests still pass after reorganization
Codemod script: scripts/migrate-component-layout-v01-to-v1.mjs for git mv operations and import path updates.
Phase M-6 — Lint rule additions (4-6 hours)
- Implement
no-foundation-direct-referencestylelint rule in@malevich/lint - Implement
modifier-namespace-checkstylelint rule - Fix existing
no-raw-valuesSafari border shorthand 1px detection bug - Fix stylelint v16 deprecation (
context.fix→ fix callback) - Update lint tests for new rules
- Run lint over all component CSS — fix any violations introduced by migration
- Run full test suite — ensure 0 regressions
Phase M-7 — Component documentation update (8-16 hours)
For each of the 10 v0.1.0 components:
- Update
<name>.docs.mdwith new architectural model references - Create sibling
<name>.agents.mdwith:- When to use / when not to use
- Required HTML
- Variants + modifiers applicability
- Tokens consumed (by tier)
- Token-to-component mapping (critical Q8.7-derived addition)
- Common mistakes agents make
- Update
_visual-reference.htmlif any variant changed - Update component-level CSS comments referencing new principle numbers
Phase M-8 — Migration verification (2-4 hours)
- Full test suite run — must pass 100% (no regressions from baseline 109 tests)
- Lint run — must pass with all new rules
- Build run — all packages must build cleanly
- Manual smoke test — checkout sample app, render every component, verify visually
- Tag as v0.2.0 with comprehensive release notes
Migration deliverables
After M-1 through M-8:
- ✅ All v0.1.0 components functionally identical, but in new locations
- ✅ Token system in new tier structure
- ✅ Modifier system formalized with namespace separation
- ✅ Lint rules enforce new architecture
- ✅ Codemods available for any future similar migration
- ✅ 3 critical ADRs (0006, 0007, 0008) document decisions
- ✅ Tag v0.2.0 marks migration complete
Total estimated time: 40-60 hours of focused work. Realistically 1-2 weeks of evenings.
Migration risks and mitigations
| Risk | Mitigation |
|---|---|
| Token rename breaks component CSS | Comprehensive codemod with --dry-run mode, manual review |
| Import path changes break tests | Sequential phases, full test suite after each phase |
| Modifier namespace conflict in cascade | Lint rule catches at build, before runtime |
| Lost work if migration goes wrong | Tag v0.1.0-baseline as safe restore point |
| Documentation drift during migration | Update docs.md + agents.md in same commits as code |
Migration parallelization
Can be parallelized in CC sessions:
- Track A: Phase M-3 (token migration) — independent
- Track B: Phase M-4 (modifier rename) — can start after M-3 token rename is mid-way
- Track C: Phase M-5 (component moves) — independent, can start after M-3
- Track D: Phase M-6 (lint rules) — independent
Phases M-7 and M-8 must be sequential (after all migrations) and not parallelizable.
Part 3 — Post-migration: v1.0 implementation plan
After v0.2.0 ships (migration complete), v1.0 work begins. This is 43 net-new components plus documentation site rebuild.
v1.0 implementation phases
Phase V-1 — Foundations completion (40-60 hours)
Build Icon (with pack system), Divider, Spinner, Skeleton, Dots, Image. Avatar already migrated. Typography already exists as classes (extend with display.hero/statement/title fluid sizes + semantic role naming).
Phase V-2 — Form subsystem (60-80 hours)
Build Field-group, Label, Textarea, HelperText, Error, Select (native styled), Radio-group, Checkbox-group, Form-button, Form-divider. This is one cohesive subsystem; ship together.
Phase V-3 — Remaining Interactive + Display Elements (40-60 hours)
Build Button-group, Switch, Toggle, Kbd. Update Button to 5 variants. Build Tag, Tags-group, Avatar-group, Code (inline).
Phase V-4 — Blocks (60-80 hours)
Build Accordion, Carousel (minimal scope), Breadcrumb, Code block, Quote block, State (4 variants). Card already exists; update with semantic-tag + data-pattern approach.
Phase V-5 — Layout Sections (40-60 hours)
Build Block, Split, Grid, Stack layouts. These are CSS-heavy, JS-light. Container query and viewport query architecture is the focus.
Phase V-6 — Ready Sections (60-80 hours)
Build Hero (with patterns), CTA, Site-header (with shape/surface/background/behavior modifiers), Site-footer. Site-header is most complex — many modifier combinations.
Phase V-7 — Overlays expansion (40-60 hours)
Build Sheet, Popover (with Floating UI), Toast, Notifications. Dialog + Tooltip already exist. Integrate Floating UI as runtime dependency.
Phase V-8 — Icon packs (20-40 hours)
Build @malevich/icons-default (Phosphor adapter), @malevich/icons-lucide, @malevich/icons-tabler. Document canonical name registry and pack adapter API.
Phase V-9 — Documentation site rebuild (80-120 hours)
Vanilla Astro + MDX. All 53 component pages. Foundations + playbook + decisions + examples sections. Theme switcher. Code tabs with AGENTS.md. Sandbox iframes. Cloudflare Pages deployment.
This is the largest single phase. Can be split into sub-tracks (scaffold + theme, content collections, component pages, foundations pages, deployment).
Phase V-10 — Tooling polish (20-30 hours)
@malevich/cli for project scaffolding. Stylelint rules for tier-respect. Build pipeline upgrades. AGENTS.md auto-generation from applicability matrix.
Total v1.0 estimated time: 460-670 hours after v0.2.0 migration. This is months of work for one developer; with CC parallel sessions and Figma reference, achievable in 3-4 months.
Migration vs new work — what unblocks what
The migration (v0.2.0) unblocks v1.0 component work. Without the new architecture in place, building new components produces code in the old model.
Within v0.2.0, the order matters:
- Token migration → unblocks modifier work
- Modifier rename → unblocks lint rules
- Component moves → independent
- Lint rules → blocks lint testing
Within v1.0, phases are mostly independent. Foundations (V-1) is the only phase that blocks others — Icon system must work before Site-header can use icons, etc.
The full chain:
- ADRs 0006-0008 → token migration → modifier rename → component reorganization → lint rules → tests pass → tag v0.2.0
- Then: V-1 Foundations → can start V-2 form, V-3 interactive, V-4 blocks in parallel
- V-5 Layout → can start V-6 ready sections, V-7 overlays in parallel
- V-9 docs site can start any time after V-1 (use existing components as scaffolding examples)
Going live
v0.2.0 release: Tag, write release notes referencing migration, push to GitHub. No public announcement (we're not public yet).
v1.0 release: Big bang launch. Documentation site live at malevich.design (transitioned from malevich.oleg.design). Manifesto publication. HN/Reddit/Twitter posts. Designer outreach. Ukrainian media outreach (cultural anchor story).
Pre-v1.0 development stays private. The architectural decisions in this document are sufficient to start building without consulting the public.