De-Slop Rules Agents Can Actually Run: A 2026 Audit of 3 Skills
The category: skills that promise to un-slop an agent’s UI
These are Markdown instruction files, not libraries or linters: unslop, unslop-ui (skills/unslop-ui), and unslop-ui-skill.
Each promises to stop an agent shipping generic AI-looking UI. The real question is not taste, it is executability: can an agent execute them without guessing.
Our October 15 measurement of design homogenization counted the symptom across live sites. This post audits the prescriptions — the rule sets agents are told to follow — and asks whether the cure is itself machine-executable.
This audit is based on the published rule files, fetched 2026-11-03 — we did not run any of the three skills on a page.
What “agent-executable” has to mean
An agent cannot execute vibes. It needs a selector it can inspect, a predicate it can test, a priority so it does not flag everything, a sequence with a stop state, and a way to verify its work — a checklist, a script, or an exit code.
We score each tool on those five dimensions, and every score appears as a mark out of 10 in the tool’s own section and again in the scoreboard. Counts below are our own parse of the files as fetched 2026-11-03; stars and push dates are from the GitHub API the same day.
- Selector coverage — does each rule name an artifact an agent can inspect.
- Predicate precision — does it give a pass/fail condition, ideally a number.
- Priority / false-positive control — does it rank by evidence or say what NOT to flag.
- Sequencing — does it impose an order and a stop state.
- Verifiability — can the agent check its own work.
The pattern is the same one our WCAG and APCA contrast linter relies on: a ratio is checkable, “looks muddy” is not.
unslop: the ordered procedure
Unslop by Damir Sokolovsky (@heydamir), licence CC BY 4.0, has 7,320 stars and last push 2026-11-01, per GitHub API, 2026-11-03. Its SKILL.md is 31,327 bytes per the file itself, supported by references/signs.md at 7,038 bytes, tokens.md at 6,494 bytes, visuals.md at 8,306 bytes, effects.md at 4,864 bytes, plus scripts/snapshot.mjs at 6,503 bytes.
This is the only set that runs as a procedure. The file defines an 8-step run — look at the screen, audit, decide how much to change, set direction and STOP for user confirmation, fix in nine passes in order, check, report, optional story video.
The nine passes are fixed: Spacing, Color, Icons, Copy, Type, Layout, Details, Visuals, Motion. The file’s rationale, quoted from SKILL.md in unslop, is: “Spacing comes first because everything else reads differently once the rhythm is right. Copy comes before type and layout because the length of the headline decides its size and where it sits. Visuals and motion come last because they should fit a screen that already works without them.”
Selectivity is explicit. “Vibecoded UI fails in the same predictable ways,” says SKILL.md in unslop, then adds the brake: “Never change a good screen just to make it different.” Direction words banned by the file include “clean, modern, sleek, minimal and premium… because they describe every template.” Our parse of the nine passes finds 117 bullet rules, 27 of them contain a digit.
Predicates are computable, including four reusable helpers: the 4px grid, accent contrast 4.5:1, border opacity 6-10%, icons 16/18px at 1.5 stroke. The file itself also caps content usually at 1440-1600 wide, sets sidebar 240-280px, nav rows 32-36 tall with 2-4 between, radii controls 8-10, cards 12-16, panels 14-20, weights 400 and 500 with 600 rare, and keeps dense mobile previews above 11px.
Verification exists but does not judge. Signs.md, per our parse of signs.md, lists 64 signs in 10 groups, each line sign → fix, plus a 15-item checklist in SKILL.md. Effort is capped by the file: “Render the screen to check it at most three times.” Its two scripts render and record — snapshot.mjs saves a page and a screenshot, story.mjs renders a video — and neither returns a pass or a fail.
Scores: Selector 8/10, Predicate 8/10, Priority 8/10, Sequencing 10/10, Verifiability 7/10. Total 8+8+8+10+7=41/50.
unslop-ui: the false-positive governor with a real scanner
Unslop-ui has 33 stars and last push 2026-08-21, per GitHub API, 2026-11-03. Its SKILL.md is 7,342 bytes per the file itself, with references/tells.md at 13,881 bytes and references/good-defaults.md at 3,710 bytes.
Its claim, reported as the file’s claim not independently verified, is mining ~3.2 million posts across 47 AI and SaaS subreddits (2020 to 2026) plus 3,033 comments from 125 threads. The operating line, from SKILL.md in unslop-ui, is: “A tell is just a default that nobody overrode.”
It offers two modes — Build mode that chooses non-default axes before writing styles, and audit mode — but no ordered passes and no stop gate.
Its strength is priority. It is the only one of the three that publishes weights: 9 tells with share of comments naming them, per tells.md in unslop-ui. Default shadcn/Tailwind look 2.5%, AI purple primary 2.3%, gradients everywhere 2.0%, too many animations 1.1%, rounded corners everywhere 0.8%, dark mode with unprompted neon glow 0.7%, emoji as icons 0.5%, generic sans 0.4%, centered hero plus three cards 0.4% of comments / 1.6% of posts. Umbrellas sit above: cookie-cutter 6.1%, screams AI 6.4%.
Rarer still is its cleared list. “Cleared by the data (do not chase)” in tells.md in unslop-ui explicitly spares mesh/blob/aurora backgrounds as a keyword artifact, bento grids at 0.1%, glassmorphism at 0.2%, dark mode itself, and shadcn/Tailwind themselves. Tell 1’s fix, from the priority table in SKILL.md, is: “Override the theme tokens. Stock defaults are the giveaway, not shadcn itself.” The governance quote, from SKILL.md in unslop-ui, is: “Honesty about this matters: a skill that flags everything trains the user to ignore it. Flag what the data supports, at the weight the data supports.”
And it is the only one of the three that ships something you can execute. scripts/devibe_scan.py, 10,837 bytes, standard library only, is a regex scanner over 14 source extensions — html, css, scss, js, tsx, vue, svelte, astro, mdx and others. It carries 12 rules (4 high, 6 medium, 2 low severity), computes a weighted vibe score (high 3, medium 2, low 1), prints JSON with --json for CI, and exits with the count of HIGH findings, so a pipeline can gate on it. Our parse of its rule list: shadcn default card, AI purple, gradient text, purple-blue gradient, hero three cards, rounded-everything, fade-in animations, neon glow, emoji as icons, generic font, hype copy, stock illustration. When it finds nothing it says so, and states: “Layout and motion tells need eyes too.”
That is a genuine checker, and it is why this tool scores highest on verifiability while scoring lowest on predicates: the severities come from how often a tell is named in the corpus, not from a threshold the page must meet.
Scores: Selector 7/10, Predicate 3/10, Priority 9/10, Sequencing 4/10, Verifiability 9/10. Total 7+3+9+4+9=32/50.
unslop-ui-skill: the catalog, not a procedure
Unslop-ui-skill has 2 stars and last push 2026-06-28, MIT licence, per GitHub API, 2026-11-03. README is 3,989 bytes, TELLS.md is 27,764 bytes, and .claude/skills/no-ai-slop/SKILL.md is 7,432 bytes, per the files themselves.
Our parse finds 158 bullet rules across 9 categories — Typography and fonts, Color and contrast, Backgrounds and surfaces, Layout and page structure, Components and cards, Imagery and photography, Icons and illustration, Copy/microcopy and voice, Motion and interaction — plus Sources. That is the largest count here, and the least runnable.
There are no priority weights, no evidence percentages, no run procedure and no script in the audited files. The README targets Claude Code, Cursor, Windsurf, v0, Lovable, Bolt and promises “plain Markdown skill plus a researched catalog. No install, no dependencies, framework agnostic,” quoted from README in unslop-ui-skill. It summarizes itself as “That is 8 of roughly 100,” quoted from README in unslop-ui-skill.
Sample pairs show the style, all from README in unslop-ui-skill: purple-to-blue gradient called “the #1 AI tell” → one deliberate solid accent; Inter/Geist → a typeface with a point of view; cream #faf8f4 → clean white; grey gray-400/500 body → near-black, WCAG AA; pill floating above hero → let heading lead; three lucide icons in rounded squares → real content; em-dashes in every sentence → spaced hyphens; fade-up-on-everything → sparing motion.
Selectors are concrete nouns an agent can find. Predicates are mostly adjectives. WCAG AA and hex values help, but “deliberate,” “real,” and “sparing” do not compile.
Scores: Selector 7/10, Predicate 4/10, Priority 2/10, Sequencing 1/10, Verifiability 1/10. Total 7+4+2+1+1=15/50.
Scoreboard
No set ships both halves. The 117-rule procedure in unslop totals 41/50 on execution order and numbers but ships no checker; the 12-rule scanner in unslop-ui is the only runnable check here, and its parent skill has no pass order at all. The 158-rule catalog in unslop-ui-skill, the largest rule set of the three, totals 15/50.
| Tool | Selector coverage | Predicate precision | Priority / false-positive control | Sequencing | Verifiability | Total /50 | One-line verdict |
|---|---|---|---|---|---|---|---|
| unslop | 8/10 | 8/10 | 8/10 | 10/10 | 7/10 | 41/50 | Only end-to-end runnable procedure |
| unslop-ui | 7/10 | 3/10 | 9/10 | 4/10 | 9/10 | 32/50 | Only runnable scanner, no procedure |
| unslop-ui-skill | 7/10 | 4/10 | 2/10 | 1/10 | 1/10 | 15/50 | Large quarry with no execution order |
Counter-evidence, stated precisely: one of the three ships a checker, and it is a source scanner. devibe_scan.py regexes the code you wrote, so it cannot see a computed contrast ratio, the rendered font size, or the hue of an accent after the cascade and the CSS variables resolve. It also cannot see layout or motion, which its own output admits. The other two repos ship no check at all. So “computable” here means a rule can be re-expressed as a check, and only one of the three has taken that step.
What none of them can decide
Taste stops where character starts. All three can police defaults, but none can supply point of view.
Unslop says it best, quoted from SKILL.md in unslop: “The difference between slop and craft is where the richness goes. Slop spreads color and effects over the chrome… Craft keeps the chrome quiet and puts the richness into one or two moments of content that people remember.”
That “one or two moments” rule is wise and uncomputable. So is the headline-transplant test: if your hero headline fits another product unchanged, no grid, contrast, or icon fix saves it. Agents need a human to choose the moment.
The render-layer rule a linter can run
DESLOP-001 is the layer devibe_scan.py cannot reach. The scanner reads source; DESLOP-001 reads computed styles and DOM text of the rendered page, which is where contrast, resolved font sizes and final accent colours exist. The em-dash density threshold and the hue band are our operationalization, not vendor values — the skills name the tells, we chose numbers so a machine can test them.
RULE deslop-001 — "render-layer de-slop subset" (complements source-level devibe_scan.py)
inputs: computed styles + DOM text of the rendered page
for each element E with visible text:
if computed font-family(E) in {Inter, Geist, Roboto, system-ui, -apple-system, Segoe UI, Helvetica Neue, Arial} -> flag DEFAULT_FONT(E)
if computed font-size(E) < 11px -> flag SUB_11PX(E)
if computed background-image(E) is a linear-gradient AND (color(E) or -webkit-text-fill-color(E) is transparent) -> flag GRADIENT_TEXT(E)
if E is body-size copy AND contrastRatio(color(E), effectiveBg(E)) < 4.5 -> flag LOW_CONTRAST(E)
for each text node T:
if count(T, "—") > 1 per 300 chars -> flag EMDASH_DENSITY(T) # our threshold
accent = most-saturated non-neutral computed color in the first screenful
if hue(accent) in [248, 292] AND saturation(accent) > 0.4 -> flag AI_PURPLE_PRIMARY # our band, ours not the corpus
NON-FLAG LIST (never raise): mesh/blob/aurora backgrounds, bento grids, glassmorphism, dark mode itself, shadcn or Tailwind per se, animation count
RESULT: fail if any flag; report flag + rule id + selector path.
UNDECIDABLE: character / point of view; the "one or two moments" of richness; whether a headline could fit another product; whether a purple gradient is a deliberate brand moment.
Run it in CI as fail-if-any-flag with the selector path, next to devibe_scan.py rather than instead of it: the source pass catches theme tokens and default classes before the build, the render pass catches what survived compilation. Four of its checks — contrast, sub-11px type, computed gradient text, and the computed accent hue — are the ones a source regex structurally cannot make.
The separate rule set is what makes it different from a checklist: a checklist asks a human to look, a predicate asks the build to answer. Our eight computable checks on a live URL follow the same shape.
FAQ
Should agents load the largest rule set?
No. Size hurts without order. The 158-rule catalog scored 15/50 in our parse because it lacks weights, sequence, and verification. Load the 117-rule procedure that tells the agent what to do first, when to stop, and how to check.
Which of these three can an agent run today?
One file. scripts/devibe_scan.py in unslop-ui is a standard-library Python scanner with 12 weighted rules, JSON output, and an exit code equal to the number of high-severity findings. Nothing else in the three repos executes; unslop’s two scripts render screenshots and video, and they judge nothing.
Why keep unslop-ui if it scored only 32/50?
Because it holds the two artifacts the others lack. Its scanner is the only runnable check in the category, and its weighted tells plus “cleared by the data” list are the only false-positive control. Graft its cleared list and its severities onto unslop’s procedure.
Can DESLOP-001 replace human design review?
No. It catches mechanical defaults a source scan misses — resolved low contrast, sub-11px type, computed gradient text, and a purple accent on the rendered page. It cannot judge voice, story, imagery choice, or whether richness lands in one memorable moment versus scattered chrome.
What is the fastest CI integration?
Run devibe_scan.py on the source tree and DESLOP-001 on the rendered DOM, failing on any flag with rule ID and selector path. Keep unslop’s checklist for the visual passes. Review undecidable brand and headline calls by hand.
The Bottom Line
Winner unslop at 41/50, the only set an agent can run end to end as written. unslop-ui at 32/50 holds the category’s only executable check and its only false-positive control, and its scanner is source-level only. unslop-ui-skill at 15/50 is a quarry, not a procedure. The gap the three leave is the render layer: load unslop’s procedure, graft on unslop-ui’s cleared list and severities, and run DESLOP-001 where the CSS has already resolved.
How This Guide Was Built
We fetched the three repos 2026-11-03, parsed SKILL.md, signs.md, tells.md, TELLS.md, their reference files and their scripts directories, and scored each dimension 0-10 against inspectable selectors and numeric predicates. Stars and push dates came from the GitHub API 2026-11-03. One correction belongs in the record: our first pass read only the Markdown files and scored unslop-ui 3/10 on verifiability; opening scripts/ turned up devibe_scan.py, a working 12-rule scanner, and the score moved to 9/10. No pages were generated and no skill was executed; DESLOP-001’s em-dash and hue thresholds are our own operational choices, not vendor values.
