Skip to content
Back to skills

Frontend Anti Slop

ASecurity

This skill should be used when auditing React/Next.js source for Hallmark-adapted anti-AI-slop patterns via a deterministic Tailwind/JSX scanner.

  • 16 stars
  • 0 votes
  • 1 copy
  • 12 views
  • Added May 27, 2026
data-aigobashreactnextjsgitfrontend

Works with

  • claude code
  • cli

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned September 24, 2026

npx -y skills add jikig-ai/soleur --skill frontend-anti-slop --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Frontend Anti Slop?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Frontend Anti Slop
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jikig-ai-frontend-anti-slop/badge)](https://www.skillsdirectory.com/skills/jikig-ai-frontend-anti-slop)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: frontend-anti-slop
description: This skill should be used when auditing React/Next.js source for Hallmark-adapted anti-AI-slop patterns via a deterministic Tailwind/JSX scanner.
version: 1.0.0
---

<!-- grok-harness-invoke:start -->
**Grok Build (`plugins/soleur/lib/harness.ts` `invokeSkill()`):** Read this SKILL.md in this process and run it to completion. A one-segment `soleur:<name>` in this document names a SKILL — on Grok Build, Read `plugins/soleur/skills/<name>/SKILL.md` in this process; it is not a nested tool_use. A multi-segment id such as `soleur:<domain>:<name>` names an AGENT: spawn it, never Read it, and on Grok Build spawn_subagent takes the id with its colons replaced by hyphens (`agentIdToGrokSubagentType`). **Claude Code:** Skill tool for a skill (`soleur:<name>`), Task tool with `subagent_type` for an agent. Forbidden is executing a subset, not the Read.
<!-- grok-harness-invoke:end -->

# frontend-anti-slop

A deterministic source-static audit for React/Next.js components that flags AI-default visual and microinteraction patterns adapted from [Nutlope/hallmark](https://github.com/Nutlope/hallmark) (MIT). v1 ships 18 Tier 1 ripgrep gates over `apps/web-platform/{app,components}/**/*.{tsx,jsx,css}`, `apps/web-platform/server/**/*.{ts,tsx}`, and the Eleventy docs site. v1.5 (post-calibration) adds a Tier 2 LLM-judgment reviewer agent for the ~12 gates regex cannot resolve.

> **Attribution.** Rule set and anti-pattern names adapted from Hallmark (Together AI, MIT). Verbatim license at [`/LICENSES/hallmark.MIT.txt`](../../../../LICENSES/hallmark.MIT.txt); upstream stanza in [`/plugins/soleur/NOTICE`](../../NOTICE).

## When this skill fires

- Invoked by `soleur:review` when a PR touches `apps/web-platform/(app|components)/.*\.(tsx|jsx|css)$`. See `plugins/soleur/skills/review/SKILL.md § Anti-slop Scanner Hook`.
- Manual: `soleur:frontend-anti-slop --paths <files-or-dirs> [--dry-run|--json] [--rule <ID>]`.

The scanner is **non-blocking by design** — exit code is 0 regardless of finding count. v1 ships in calibration mode: findings surface in PR review output for operator review, no auto-filing to GitHub issues. Calibration unlocks v1.5 (auto-file + Tier 2 agent) at ≤ 10% FP rate over ≥ 20 findings ≥ 2 weeks.

## Invocation

```bash
# Default — scans staged + modified frontend files vs. the index.
bun run plugins/soleur/skills/frontend-anti-slop/scripts/tier1-scan.ts

# Explicit paths (files or directories).
bun run plugins/soleur/skills/frontend-anti-slop/scripts/tier1-scan.ts \
  --paths apps/web-platform/components/ui/ --json

# Single rule.
bun run plugins/soleur/skills/frontend-anti-slop/scripts/tier1-scan.ts \
  --paths apps/web-platform/components/ --rule GRADIENT-TEXT --json
```

Skill tool form:

```text
Skill(skill: "soleur:frontend-anti-slop")
Skill(skill: "soleur:frontend-anti-slop", args: "--paths apps/web-platform/components/ui/ --json")
```

## Scope

| In scope (v1) | Out of scope |
|---|---|
| `apps/web-platform/(app|components)/**/*.{tsx,jsx,css}` | Other apps in the monorepo (`web-platform-docs`, infra apps) |
| `apps/web-platform/server/**/*.{ts,tsx}` (email/HTML templates) | App-code remediation of pre-existing findings (forward-gate only) |
| 18 deterministic Tier 1 gates (regex-only) | Tier 2 LLM-judgment gates (deferred to v1.5) |
| Source-static analysis | Rendered-DOM / screenshot analysis (that's [`soleur:ux-audit`](../ux-audit/SKILL.md)) |
| JSON output matching [`finding.schema.json`](../ux-audit/references/finding.schema.json) | Auto-filing GitHub issues |
| `<!-- anti-slop:disable RULE_ID reason="..." -->` per-file overrides | AST-based gates (CARD-IN-CARD, focus states) — v1.5 with ts-morph |

## Rule set

The 18 Tier 1 gates live in [slop-rules.md](./references/slop-rules.md) as a parsed Markdown table. Each row: `id`, `tier`, `category`, `hallmark_gate`, `severity`, `pattern`, `message`, `suggested_fix`. The scanner filters to `tier === 1` and runs each `pattern` regex line-by-line over target files.

React/Tailwind code examples for each rule live in [anti-patterns.md](./references/anti-patterns.md).

### Brand rules (blocking)

Three `brand`-category gates ship alongside the Hallmark-derived anti-slop rules: BRAND-RAW-HEX (high), BRAND-WHITE-ON-GOLD (high), BRAND-NONZERO-CORNER (medium). Unlike the advisory anti-slop findings, a finding whose originating rule is `category: brand` **and** `severity: high` makes the scanner **exit non-zero (blocking)** — it is a required-fix gate, not calibration-mode triage. Brand `medium` findings and all non-brand `anti-slop` findings stay advisory (exit 0). The emitted Finding always serializes `category: "anti-slop"`; the `brand` discriminator lives only on the Rule, so `--json` output stays conformant to `finding.schema.json`.

BRAND-RAW-HEX ("use a wired design token, not a literal color") is **project-agnostic** — Soleur users adopting this scanner should keep it as-is, but re-base BRAND-WHITE-ON-GOLD / BRAND-NONZERO-CORNER on their own `brand-guide.md` palette and wired token file rather than the hardcoded Soleur gold identity.

Findings emit as JSON conforming to `finding.schema.json`:

```json
{
  "route": "",
  "selector": "<file-path>#<RULE-ID>",
  "category": "anti-slop",
  "severity": "high",
  "title": "<rule message> (rule <ID>)",
  "description": "<rule message>. Detected at <path>:<line>.",
  "fix_hint": "<rule suggested_fix>",
  "screenshot_ref": "/tmp/anti-slop/no-screenshot.png"
}
```

The `selector` overload (`<file>#<RULE-ID>`) reuses the existing `soleur:ux-audit` dedup hash (`sha256("route|selector|category")`) without a `Finding` interface change — see plan §"Research Reconciliation #2".

## Per-file rule disable

To intentionally use a flagged pattern (designer-mandated gradient, brand-specific font), add a comment in the source file:

```tsx
{/* anti-slop:disable GRADIENT-TEXT reason="brand-mandated marketing hero gradient" */}
<h1 className="bg-clip-text text-transparent bg-gradient-to-r from-soleur-accent-gradient-start to-soleur-accent-gradient-end">
  ...
</h1>
```

Disable comments work in JSX comment form (`{/* ... */}`), HTML-comment form (`<!-- ... -->`), or CSS-comment form (`/* ... */`) — the scanner matches the literal `anti-slop:disable <RULE_ID>` substring.

## Calibration mode

v1 ships in calibration mode (no auto-filing). The promotion gate to v1.5 (auto-file + Tier 2 agent):

- ≥ 20 findings logged over ≥ 2 weeks of dogfood
- ≤ 10% operator-confirmed false-positive rate

The follow-up issue filed at merge tracks the calibration window. v1.5 picks up when the gate trips.

Files in this skill

  • SKILL.md4.6 KB
  • references/anti-patterns.md5.6 KB
  • references/slop-rules.md7.2 KB
  • scripts/tier1-scan.ts12.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.