Configure the ai-slop plugin for a consumer repository: exemption paths for documents that legitimately need em dashes, excluded paths, AI-vocabulary word-list tuning, and per-rule thresholds, written to the team layer .claude/ai-slop.json with the user's confirmation. Use when: 'set up ai-slop', 'configure slop detection', 'exempt this doc from the em-dash rule', 'tune the slop thresholds'.
Installs into .claude/skills of the current project.
Are you the author of Setup?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/melodic-software-setup-a85c4923)
---
description: "Configure the ai-slop plugin for a consumer repository: exemption paths for documents that legitimately need em dashes, excluded paths, AI-vocabulary word-list tuning, and per-rule thresholds, written to the team layer .claude/ai-slop.json with the user's confirmation. Use when: 'set up ai-slop', 'configure slop detection', 'exempt this doc from the em-dash rule', 'tune the slop thresholds'."
argument-hint: "[check|apply]"
user-invocable: true
disable-model-invocation: true
shell: bash
---
## Pre-computed context
`check`'s config resolve ran at load time. The detector's `--show-config` output below names the
layer supplying each effective value; `(detector unavailable)` means it did not run:
!`"${CLAUDE_PLUGIN_ROOT}/skills/audit/scripts/detect.sh" --show-config 2>/dev/null || echo "(detector unavailable)"`
When it reads `(detector unavailable)` or `[shell command execution disabled by policy]`, run the
detector's `--show-config` via Bash or read the three layers directly.
## Purpose
The ai-slop detector ships neutral defaults. A consumer repo declares its own exemptions and
tuning in `.claude/ai-slop.json`, resolved per the config-cascade convention: user-global
(`~/.claude/ai-slop.json`), team (`.claude/ai-slop.json`, tracked), local overlay
(`.claude/ai-slop.local.json`, gitignored). Later layers refine earlier ones per key.
## Keys
| Key | Type | Meaning |
|---|---|---|
| `excluded_paths` | glob list | Files the audit never scans |
| `em_dash_allowed_paths` | glob list | Documents exempt from the zero-tolerance em-dash rule |
| `vocab_add` | word list | Additions to the AI-vocabulary list |
| `vocab_remove` | word list | Removals from the AI-vocabulary list |
| `phrase_add` | ERE fragment list | Additions to the model-era phrase roster (`rule-model-era-phrases`); whole fragments, spaces allowed, apostrophes spelled `.` |
| `phrase_remove` | ERE fragment list | Removals from the shipped phrase roster, matched verbatim against the shipped fragments |
| `disabled_rules` | rule slugs | Rules the audit skips entirely (reported as disabled) |
| `thresholds` | map | Per-rule density thresholds: `ai_vocabulary`, `copulative_avoidance` (matches per 1000 words; density rules also need at least 3 matches) |
| `_comment` | string | Free-text rationale for the choices in this file. Read by nobody; JSON has no comment syntax, and a config that disables a rule without recording why is the drift this skill exists to catch. Not drift, so do not flag it as an unknown key |
## check (default, read-only)
Report the current state and change nothing:
1. Read the pre-computed `--show-config` output (it names the layer supplying each value), or read
the layers directly when it is unavailable; report which layer wins each key and which layers are
absent.
2. Flag drift: unknown keys, an em-dash threshold key (the rule is zero-tolerance by design, and
per-document exemption via `em_dash_allowed_paths` is the supported mechanism), globs that
match nothing, a `disabled_rules` slug that names no shipped rule, a `phrase_add` fragment
that is not a valid ERE (the detector skips it with a stderr note; surface it here as
drift), or a `phrase_remove` fragment matching no shipped phrase.
3. End with what `apply` would change, if anything was flagged.
## apply
Everything `check` does, then the confirmed write:
1. Interview the user for what they want changed. For em-dash exemptions, ask for the documents
that genuinely require em dashes; the default posture is that most work does not.
2. Write ONLY the team layer (`.claude/ai-slop.json`), showing the diff and getting explicit
confirmation before writing. Never write the user-global or overlay layers on the user's
behalf; name them as options the user edits themselves.
3. Re-run `--show-config` via Bash (the pre-computed output predates the write) and report the
new effective state. Then run the tracked-file pair on
the written team file: `git check-ignore -v .claude/ai-slop.json` reports no match (a match is
FAIL with the pattern) AND `git ls-files --error-unmatch .claude/ai-slop.json` exits 0
(non-zero right after a fresh write means "written but untracked: commit it to share with the
team", never success).