uxskill
Star on GitHub
Language
English 简体中文 繁體中文 日本語 한국어 हिन्दी Bahasa Indonesia Tiếng Việt ไทย العربية Español Français Deutsch Português Русский Türkçe Italiano

## What "closed loop" usually means in marketing

Search for "closed-loop design system" and you'll find a lot of vendor copy claiming it. What they usually mean: a Slack notification when someone deletes a token. A Figma plugin that imports tokens once. A linter that runs in CI and shouts when something breaks.

That's not a closed loop. That's a notification system with extra steps.

A real closed loop has FOUR pieces:

1. A signal: the system did something specific and measurable
2. A memory: that signal is recorded persistently and queryable
3. A read path: the system queries the memory on the next decision
4. A bias: the read result actually changes the next output

Most "AI design tools" have piece 1. Some have 2. Almost none have 3 and 4.

## What ux-skill v3.0 actually does

### 1. The signal

Every `/ux-recommend`, `/ux-design`, `/ux-lint`, `/ux-evolve`, and `/ux-synthesize` call produces a row of structured data. Industry. UI type. Mode picked. Brand anchored. Style chosen. Lint score 0-100. Anti-pattern count by severity. Did the user accept the output? How long did it take?

### 2. The memory

That row is appended to `.ux/decisions.jsonl` in the project, AND to `~/.uxskill/decisions.jsonl` for cross-project memory. JSONL format. Schema locked at `_v: 1`. Column names are a public contract that never gets renamed.

    {"_v": 1, "ts": 1727380123.4, "command": "design",
     "industry": "fintech-payments", "ui_type": "dashboard",
     "mode": "brand_anchor", "picked_brand": "stripe",
     "picked_style": "swiss-grid", "picked_palette": "stripe-cool",
     "lint_score": 92, "lint_high": 0, "lint_med": 1, "lint_low": 3,
     "user_accepted": true, "duration_ms": 1240}

### 3. The read path

When the recommender runs on the next call, before sorting candidates by manifest-based scores, it reads the ledger filtered by `(industry, ui_type)`. It counts how often each candidate's id appears in PRIOR rows where `lint_score >= 80` AND `user_accepted = true`.

### 4. The bias

Each matching prior win adds +5 to that candidate's score. Re-sort. Top entry wins. The same call that previously returned "Bauhaus minimalism" might now return "Swiss editorial" because Swiss has won 3 times in this bucket.

## Cold-start protection

Below 3 priors per bucket, the re-ranker is a no-op. Behaves exactly like v2.0. This prevents the system from "learning" garbage from N=1 noise. It learns slowly, only when the signal is real.

## The privacy contract

The ledger is a local file. Not synced to a cloud. Not analyzed by a vendor. The data is yours and stays on your disk. Three switches you control:

- `UXSKILL_NO_LOG=1` env var disables all writes
- `--no-log` CLI flag has the same effect per-call
- `Scope.PROJECT` writes only to the project ledger, never to the per-user one

## How to see what your install has learned

    uxskill stats --decisions    # JSON aggregate
    uxskill stats --html         # writes .ux/stats.html: open in browser

The HTML dashboard shows: total decisions, lint score median, by-command breakdown, top brands picked, by-industry distribution, accept rate. This is YOUR install's data. No global aggregate. No leaderboard. Just what your work has produced.

## What we deliberately don't track

- Raw user prompts (only the structured fields)
- External user IDs
- Machine fingerprints
- Network or IP info
- Telemetry uploads to any vendor

Nothing leaves your laptop. Ever.

## Why this matters more than another model

The dominant pattern in 2026 is: chuck the brief at a bigger LLM, hope for better output. v3.0 says: keep the same generation logic, but make it CONSULT your history. The next call is always strictly better-informed than the last, even with the same underlying model.

And critically, this approach scales linearly with usage. Every 100 decisions in your ledger sharpens future recommendations for your specific industry + UI-type buckets. After a year of working on fintech dashboards, your install knows exactly which brand combinations ship clean. Without ever sharing that knowledge with anyone else.

## How this compares to vendor "personalization"

SaaS design platforms talk about "AI that learns your style." What they mean: their model is fine-tuned on your design system uploads, your output is sent to their servers, your feedback signals improve their global model.

That's vendor learning, not user learning. The benefit accrues to them.

ux-skill v3.0 inverts this. The learning happens on YOUR machine, in YOUR ledger, biasing YOUR future recommendations. The vendor (Laith) sees none of it. Other users see none of it. No knowledge graph, no embedding store, no third-party. Just a JSONL file on your disk that your local recommender reads.

## Try the loop

    pip install uxskill
    uxskill init

    # Generate something
    uxskill synthesize --industry fintech-payments --tone bold

    # Lint it (writes decision)
    uxskill lint . --score-only

    # Generate again, same brief
    # After 3+ accepted+lint-clean decisions, the bias kicks in
    uxskill synthesize --industry fintech-payments --tone bold

    # See what your install has learned
    uxskill stats --html
    open .ux/stats.html

## Related reads

- The full v3.0 launch · The Brain
- Brand specs are training data, not templates
- A deterministic design engine that learns offline
- The deterministic linter