sailop
blogscanpricing
← Back to blog
February 12, 20267 min read

CI/CD for Design: Catching AI Slop Before It Ships

Integrate design quality checks into your CI/CD pipeline. Catch AI-generated visual defaults in pull requests before they reach production.

You lint your code. You type-check your code. You test your code. But you ship your design unchecked. Every pull request could introduce AI-generated visual defaults and you wouldn't know until someone looks at the page and says "this looks generic." Sailop's CI/CD integration changes that.

The Gap in Your Pipeline

Modern frontend pipelines are thorough about code quality:

  • ESLint catches code patterns and anti-patterns
  • TypeScript catches type errors
  • Prettier enforces formatting
  • Jest/Vitest catches functional regressions

But none of these tools care about what the output looks like. A component can pass every lint rule, every type check, every test, and still produce a visually generic page with blue-500 buttons and Inter font.

This is the gap. Design quality has been a human-review-only concern. And as AI generates more and more frontend code, human reviewers can't catch every transition-all duration-300 ease-in-out that slips in. First, understand what AI slop is and why it matters -- then automate the detection.

sailop check: The Design Linter

The sailop check command works like a linter but for visual patterns:

# Check files with a maximum score threshold
sailop check ./src --max-score 50

# Exit code 0 if all files are below the threshold
# Exit code 1 if any file exceeds the threshold

This is the building block for CI integration. Set a maximum DNA score, and the command fails if any file exceeds it.

# Strict: nothing above 40 (Grade B or better)
sailop check ./src --max-score 40

# Moderate: nothing above 60 (Grade C or better)
sailop check ./src --max-score 60

# Lenient: nothing above 80 (catch only the worst offenders)
sailop check ./src --max-score 80

GitHub Actions Integration

Here's a complete GitHub Actions workflow that checks design quality on every pull request:

# .github/workflows/design-check.yml
name: Design Quality Check

on:
  pull_request:
    paths:
      - 'src/**/*.tsx'
      - 'src/**/*.css'
      - 'src/**/*.html'

jobs:
  sailop-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Sailop
        run: npm install -g sailop

      - name: Run DNA scan
        run: sailop ci ./src --fail-above 60 --format json > sailop-report.json

      - name: Upload report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: sailop-report
          path: sailop-report.json

      - name: Comment on PR
        if: failure()
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const report = JSON.parse(fs.readFileSync('sailop-report.json', 'utf8'));
            const body = `## Sailop Design Check Failed

            DNA Score: **${report.score}/100** (Grade ${report.grade})
            Threshold: 60/100

            | Dimension | Score |
            |-----------|-------|
            | Color | ${report.dimensions.color} |
            | Typography | ${report.dimensions.typography} |
            | Layout | ${report.dimensions.layout} |
            | Animation | ${report.dimensions.animation} |
            | Components | ${report.dimensions.components} |
            | Structure | ${report.dimensions.structure} |
            | Spacing | ${report.dimensions.spacing} |

            Run \`sailop fix ./src --apply\` to auto-fix detected patterns.`;

            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: body
            });

This workflow:

  • Triggers only on PRs that modify frontend files
  • Runs the Sailop CI scanner
  • Fails the check if the DNA score exceeds 60
  • Comments on the PR with a detailed breakdown

Pre-Commit Hook

For faster feedback, add a pre-commit hook that catches AI slop before it even reaches the PR:

# Install the pre-commit hook
sailop hook install

# Or manually add to .husky/pre-commit:
sailop check ./src --max-score 50 --staged-only

The --staged-only flag checks only files that are about to be committed, keeping the hook fast.

// package.json
{
  "scripts": {
    "lint": "eslint src/",
    "typecheck": "tsc --noEmit",
    "test": "vitest run",
    "design-check": "sailop check ./src --max-score 50"
  },
  "lint-staged": {
    "*.{tsx,css,html}": ["sailop check --max-score 50"]
  }
}

sailop ci: Structured Output

The sailop ci command is designed specifically for automation. It outputs structured JSON that other tools can consume:

sailop ci ./src --fail-above 60 --format json
{
  "score": 72,
  "grade": "D",
  "pass": false,
  "threshold": 60,
  "dimensions": {
    "color": 81,
    "typography": 68,
    "layout": 75,
    "animation": 90,
    "components": 65,
    "structure": 58,
    "spacing": 67
  },
  "files": [
    {
      "path": "src/app/page.tsx",
      "score": 72,
      "findings": [
        { "rule": "color-blue-range", "severity": "high", "message": "Primary color in AI blue band (hue 217)" },
        { "rule": "animation-transition-all", "severity": "high", "message": "transition-all detected (use specific properties)" }
      ]
    }
  ],
  "timestamp": "2026-02-12T14:30:00Z"
}

Gradual Adoption

You don't need to enforce a strict score on day one. Here's a gradual adoption strategy:

Week 1-2: Observe

# Run scan without failing, just collect data
sailop ci ./src --format json > baseline.json

Week 3-4: Warn

# Fail only on Grade F (score > 80)
sailop check ./src --max-score 80

Month 2: Moderate

# Fail on Grade D or worse (score > 60)
sailop check ./src --max-score 60

Month 3+: Strict

# Fail on anything below Grade B (score > 40)
sailop check ./src --max-score 40

This lets the team gradually improve scores without blocking all work on day one.

Dimension-Specific Checks

Not every team cares about every dimension. You can run checks on specific dimensions:

# Only check animation patterns (the most common AI tells)
sailop check ./src --dimension animation --max-score 40

# Only check color and typography
sailop check ./src --dimension color,typography --max-score 50

# Ignore structure dimension
sailop check ./src --skip-dimension structure --max-score 50

Integration With Existing Tools

Sailop's CI output works with:

  • GitHub Actions: Native integration via exit codes and JSON output
  • GitLab CI: Same exit code behavior, pipe JSON to artifacts
  • Bitbucket Pipelines: Use the CLI directly in your pipeline scripts
  • Jenkins: Parse JSON output in post-build steps
  • Vercel: Add to build command in vercel.json
// vercel.json
{
  "buildCommand": "sailop check ./src --max-score 60 && next build"
}

What It Catches

In practice, here are the most common findings from CI scans:

  • transition-all duration-300 (Animation, 89% of flagged files)
  • blue/indigo primary color (Color, 73% of flagged files)
  • Inter/system-ui only (Typography, 68% of flagged files)
  • rounded-lg everywhere (Components, 61% of flagged files)
  • 4px-grid-only spacing (Spacing, 57% of flagged files)

These are the patterns that AI-generated code introduces most frequently. For the full catalog, see our definitive list of 90+ AI design patterns to avoid. Catching them in CI means they never reach production.

The Complete Stack

ESLint catches bad code patterns. TypeScript catches type bugs. Tests catch broken behavior. Sailop catches visual homogeneity. Together, they cover the full quality spectrum. For a detailed comparison of Sailop and ESLint, read Sailop vs ESLint: why design needs its own linter. For the complete anti-slop workflow, see our complete guide to anti-AI design.

npm install -g sailop
sailop hook install

Set it up once, catch AI slop forever. Start at sailop.com.

Try Sailop

Scan your frontend for AI patterns. Generate a unique design system. Ship code that looks intentional.

Free scannpm i -g sailop
Share this article
Share on X
Previous
Procedural Design Systems: How Sailop Generates Infinite Palettes
Next
The Future of AI-Assisted Design: Constraints, Not Templates
On this page
The Gap in Your Pipelinesailop check: The Design LinterGitHub Actions IntegrationPre-Commit Hooksailop ci: Structured OutputGradual AdoptionDimension-Specific ChecksIntegration With Existing ToolsWhat It CatchesThe Complete Stack
Sailop 2026All articles