cursordoctrine 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL.md +113 -0
- package/LICENSE +21 -0
- package/README.md +86 -0
- package/bin/cli.mjs +413 -0
- package/linux/USER-RULES.md +12 -0
- package/linux/doctrine.md +172 -0
- package/linux/hooks/anti-slop-audit.sh +163 -0
- package/linux/hooks/anti-slop.md +56 -0
- package/linux/hooks/final-review.md +52 -0
- package/linux/hooks/final-review.sh +99 -0
- package/linux/hooks/hook-common.sh +120 -0
- package/linux/hooks/minimal-edit-audit.sh +112 -0
- package/linux/hooks/permission-gate.sh +75 -0
- package/linux/hooks/post-tool-use.sh +53 -0
- package/linux/hooks/self-review-trigger.sh +56 -0
- package/linux/hooks/self-review.md +48 -0
- package/linux/hooks/subagent-stop-review.sh +93 -0
- package/linux/hooks.json +64 -0
- package/linux/inject-doctrine.sh +31 -0
- package/package.json +40 -0
- package/skills/anti-slop/SKILL.md +267 -0
- package/skills/anti-slop/scripts/scan_slop.py +986 -0
- package/windows/USER-RULES.md +12 -0
- package/windows/doctrine.md +172 -0
- package/windows/hooks/anti-slop-audit.ps1 +182 -0
- package/windows/hooks/anti-slop.md +56 -0
- package/windows/hooks/final-review.md +52 -0
- package/windows/hooks/final-review.ps1 +105 -0
- package/windows/hooks/hook-common.ps1 +84 -0
- package/windows/hooks/minimal-edit-audit.ps1 +116 -0
- package/windows/hooks/permission-gate.ps1 +98 -0
- package/windows/hooks/post-tool-use.ps1 +46 -0
- package/windows/hooks/self-review-trigger.ps1 +83 -0
- package/windows/hooks/self-review.md +48 -0
- package/windows/hooks/subagent-stop-review.ps1 +89 -0
- package/windows/hooks.json +64 -0
- package/windows/inject-doctrine.ps1 +58 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: anti-slop
|
|
3
|
+
description: >-
|
|
4
|
+
Finds and deletes AI slop from a change OR a whole codebase — premature
|
|
5
|
+
abstractions (Factory/Repository/Mediator/CQRS/Event-Sourcing/DDD), unnecessary
|
|
6
|
+
dependencies, redundant comments, happy-path-only code, superficial tests /
|
|
7
|
+
test theater, type escapes (as any / @ts-ignore / type: ignore), swallowed
|
|
8
|
+
errors (empty catch, except: pass), prompt residue ("in a real app", banner
|
|
9
|
+
comments, emoji in code), cargo-cult patterns, accidental complexity,
|
|
10
|
+
hallucinated requirements (unrequested features / scope creep), framework
|
|
11
|
+
slop (React useEffect hell, Astro hydration bloat, Tailwind class soup,
|
|
12
|
+
SELECT *, ORM include pyramids, boolean traps, guard-chain defensive
|
|
13
|
+
inflation, async wrapper mania), and CLONE PROLIFERATION / duplicate helpers
|
|
14
|
+
(20 copies of isRecord, DRY violations,
|
|
15
|
+
knowledge duplication) — organized as twelve failure classes, while preserving
|
|
16
|
+
the behaviour the user actually asked for. Use when the user says remove AI
|
|
17
|
+
slop, de-slop, clean up the slop, /anti-slop, "this is slop", review the whole
|
|
18
|
+
codebase for slop, find duplicate or clone functions, or asks to strip
|
|
19
|
+
over-engineering, premature abstraction, cargo cult, redundant comments, or
|
|
20
|
+
duplicate utilities.
|
|
21
|
+
metadata:
|
|
22
|
+
layer: active-cleanup
|
|
23
|
+
pairs-with: minimal-editing, anti-slop-hook
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# Anti-Slop
|
|
27
|
+
|
|
28
|
+
Active counterpart to the `afterFileEdit` anti-slop **hook**. The hook only
|
|
29
|
+
*advises* after each edit; this skill does a deliberate sweep that **removes**
|
|
30
|
+
the slop. Same detectors — but here you fix, you don't flag.
|
|
31
|
+
|
|
32
|
+
Slop = code that runs but should not ship. Think in **failure classes**, not
|
|
33
|
+
individual smells — every finding belongs to one of twelve:
|
|
34
|
+
|
|
35
|
+
| Class | Signal | Names it goes by |
|
|
36
|
+
|-------|--------|------------------|
|
|
37
|
+
| **Structural** | More architecture than business logic. | Premature Abstraction/Generalization, Abstraction Debt, Overengineering, Architecture Astronautics, Indirection Hell, Wrapperitis, Layer Proliferation, Enterprise FizzBuzz |
|
|
38
|
+
| **Semantic** | Code works but no longer matches the problem. | Semantic/Requirement Drift, Intent Erosion, Spec Divergence, Hidden Assumptions |
|
|
39
|
+
| **Complexity** | Every change feels expensive. | Boilerplate Inflation, Complexity Creep, Configuration Sprawl, Cyclomatic Inflation, Cognitive Complexity |
|
|
40
|
+
| **Duplication** | One bug fix = five edits. | Copy-Paste Programming, Clone Proliferation, Knowledge/Logic Duplication, Divergent Duplication, Helper Hell, Micro-Abstraction Spam, Semantic Density Collapse, Generated-Code Fingerprints |
|
|
41
|
+
| **Dependency** | More package management than product. | Dependency Bloat/Hell, Ghost Dependencies, Transitive Explosion, Supply-Chain Bloat |
|
|
42
|
+
| **Testing** | 90% coverage, 0% confidence. | Test Theater, Snapshot Abuse, Mock Hell, Assertion Poverty, Coverage Worship |
|
|
43
|
+
| **Type-System** | The types exist but nobody trusts them. | Any-Driven Development, Stringly Typed Design, Type Erosion, Type Escapes, Unsafe Casting |
|
|
44
|
+
| **API** | Nobody knows how to use it correctly. | Leaky Abstractions, API Surface Inflation, Parameter Explosion, Boolean Trap |
|
|
45
|
+
| **State** | Bugs appear from unrelated changes. | Mutation Soup, Temporal Coupling, Hidden Side Effects, Shared Mutable State, State Explosion |
|
|
46
|
+
| **Performance** | Works in demos, collapses at scale. | N+1 Queries, Algorithmic Waste, Incidental Allocation, Render Thrashing, Cache Cargo-Culting |
|
|
47
|
+
| **Documentation** | Docs actively mislead. | Comment Debt, Documentation Drift, Generated Doc Noise, Stale Examples |
|
|
48
|
+
| **AI-Specific** | Looks professional; nobody can say why it exists. | Hallucinated Architecture/Dependencies/APIs, Defensive Code Inflation, Scaffold Explosion, Refactor Cascades, Synthetic Abstraction, Prompt Residue, Context Drift |
|
|
49
|
+
|
|
50
|
+
The governing question, asked of every survivor: **every new file, dependency,
|
|
51
|
+
abstraction, layer, pattern, interface, hook, provider, service, context,
|
|
52
|
+
middleware, migration, component, type, and configuration must justify its
|
|
53
|
+
existence with a measurable reduction in complexity elsewhere.** What cannot
|
|
54
|
+
answer is slop — most AI slop survives because nobody asks. The senior-review
|
|
55
|
+
form of the question: *what requirement forced this abstraction into
|
|
56
|
+
existence?* AI rarely has an answer.
|
|
57
|
+
|
|
58
|
+
## Framework failure modes (the vibe-coding stack)
|
|
59
|
+
|
|
60
|
+
Slop is framework-dependent — a React anti-pattern does not exist in SQL. The
|
|
61
|
+
classes above specialize per stack; *(scanner)* marks mechanically seeded ones:
|
|
62
|
+
|
|
63
|
+
- **TypeScript** — any leakage / `as unknown as` cascades *(scanner)*; fake
|
|
64
|
+
type safety (types exist, runtime validation at boundaries doesn't);
|
|
65
|
+
interface explosion (`UserDTO`/`UserResponseDTO`/`UserViewDTO` for one
|
|
66
|
+
entity); generic abuse (`<T extends Record<string, any>>`) where plain types work.
|
|
67
|
+
- **React** — useEffect hell for state synchronization (compute it, or use the
|
|
68
|
+
right primitive); derived state stored in useState instead of computed;
|
|
69
|
+
prop-drilling chains; everything-in-Context; component fragmentation
|
|
70
|
+
(`Button` + `ButtonIcon` + `ButtonLabel` + `ButtonWrapper` for no reason);
|
|
71
|
+
hooks generating hooks.
|
|
72
|
+
- **Astro** — island explosion (50 where 3 are needed); `client:load`
|
|
73
|
+
everywhere when `client:visible` / `client:idle` / zero JS would do; SSR for
|
|
74
|
+
static content; the page that accidentally became a React SPA.
|
|
75
|
+
- **Node** — Controller/Service/Repository/Manager/Provider stacks for CRUD;
|
|
76
|
+
pointless async wrappers (`await Promise.resolve`, async promise executors)
|
|
77
|
+
*(scanner)*; 30-deep middleware chains; custom error hierarchies nobody
|
|
78
|
+
catches; singletons as globals.
|
|
79
|
+
- **SQL / Postgres** — N+1 queries; `SELECT *` in checked-in SQL *(scanner)*;
|
|
80
|
+
premature AND missing indexes (both are "nobody measured"); 20-table join
|
|
81
|
+
monsters; JSONB as a schema escape hatch (`data JSONB` for everything);
|
|
82
|
+
migration spam; schema drift from business reality.
|
|
83
|
+
- **Supabase** — RLS policies nobody can explain; trusting the client with
|
|
84
|
+
security; RPC proliferation (hundreds of tiny functions); auth state
|
|
85
|
+
duplicated outside supabase-js; storage permissions re-implemented in code.
|
|
86
|
+
- **Tailwind** — 200+ character class soup *(scanner)*; magic values
|
|
87
|
+
(`w-[347px]`) *(scanner)*; the same class string pasted everywhere instead of
|
|
88
|
+
one extracted primitive.
|
|
89
|
+
- **ORM (Prisma/Drizzle)** — `include` nested five levels deep; nobody reads
|
|
90
|
+
the generated SQL; every relationship modeled twice; ORM worship that
|
|
91
|
+
ignores what the database actually does.
|
|
92
|
+
- **API** — boolean traps (`createUser(true, false, true)`) *(scanner)*; god
|
|
93
|
+
endpoints (`/api/data` does everything); more DTOs than entities; v1–v4 all
|
|
94
|
+
alive forever.
|
|
95
|
+
- **AI-specific TS/React** — deepening guard chains (`if (!data) return; if
|
|
96
|
+
(!data.user) return;` — the fix is `?.`) *(scanner)*; fallback hell
|
|
97
|
+
(`a ?? b ?? c ?? ""` everywhere); scaffold explosion (hooks/ utils/ helpers/
|
|
98
|
+
services/ providers/ adapters/ before any business logic exists);
|
|
99
|
+
hallucinated extensibility (`UserFactory`/`UserRegistry`/`UserStrategy` for
|
|
100
|
+
one user type).
|
|
101
|
+
|
|
102
|
+
## The one rule that outranks everything
|
|
103
|
+
|
|
104
|
+
**Never delete the behaviour the user asked for.** Slop is what got added *on
|
|
105
|
+
top* of the task — speculative layers, drive-by abstractions, filler. If
|
|
106
|
+
removing something would change what the feature does, it is not slop: leave it.
|
|
107
|
+
When unsure whether something is slop or intent, **leave it and say so** — never
|
|
108
|
+
guess-delete.
|
|
109
|
+
|
|
110
|
+
## Workflow
|
|
111
|
+
|
|
112
|
+
Track these phases (TodoWrite on Cursor, if available):
|
|
113
|
+
|
|
114
|
+
1. **Scope** — decide what to clean: the **whole codebase** (`--all` — the
|
|
115
|
+
default for a "review/clean the codebase" request), a change in progress (the
|
|
116
|
+
diff), or specific files the user named. State SCOPE in one line. Do not
|
|
117
|
+
wander outside it.
|
|
118
|
+
2. **Scan** — get the deterministic inventory first. Pick the mode:
|
|
119
|
+
```
|
|
120
|
+
python scripts/scan_slop.py --all --root . # WHOLE codebase + duplication (recommended)
|
|
121
|
+
python scripts/scan_slop.py --root . # only a change in progress (diff vs HEAD)
|
|
122
|
+
python scripts/scan_slop.py src/foo.ts ... # specific files
|
|
123
|
+
```
|
|
124
|
+
`--all` is the one that reviews the *entire current codebase* and runs the
|
|
125
|
+
cross-file **duplication analysis** (clones / DRY — see below); it is what you
|
|
126
|
+
want for "check what the codebase needs". Explicit paths audit only those files
|
|
127
|
+
and **suppress dead-helper / single-use analysis** (reference counts need the
|
|
128
|
+
whole tree). Diff mode is **silent on a clean tree** by design (nothing to vet).
|
|
129
|
+
Use `python3` if that is your platform's launcher. Resolve `scripts/` against
|
|
130
|
+
this skill's own directory. Add `--gate` to fail CI when slop is found (works
|
|
131
|
+
with `--format json`; the size-only "substantial change" note never gates). If
|
|
132
|
+
the script cannot run, do the detection by hand — it is only `git` plus the
|
|
133
|
+
regexes below. The scanner is deliberately narrow (high precision): it seeds
|
|
134
|
+
deterministic slop. Whether or not it finds anything, still walk the taxonomy
|
|
135
|
+
— most slop is semantic and never shows up in a regex.
|
|
136
|
+
3. **Delete** — walk the taxonomy table below. For each hit: fix it, don't
|
|
137
|
+
report it line-by-line.
|
|
138
|
+
4. **Verify** — re-run the scanner (expect clean), re-read the diff, confirm
|
|
139
|
+
behaviour is unchanged and the diff got *smaller*. Then trace every remaining
|
|
140
|
+
addition back to the user's request — anything you cannot trace is a
|
|
141
|
+
hallucinated requirement: delete it or ask. Run the project's tests if
|
|
142
|
+
behaviour-bearing code moved.
|
|
143
|
+
5. **Report** — short summary: what slop was removed, what was left and why.
|
|
144
|
+
|
|
145
|
+
## Taxonomy → fix action
|
|
146
|
+
|
|
147
|
+
Walk every row. Rows tagged *(scanner)* are seeded mechanically by
|
|
148
|
+
`scan_slop.py`; the rest need your judgement.
|
|
149
|
+
|
|
150
|
+
| Slop | How to spot it | Fix |
|
|
151
|
+
|------|----------------|-----|
|
|
152
|
+
| **Unnecessary dependency** *(scanner)* | new entry in package.json / requirements / pyproject / Cargo.toml / go.mod … | Remove it; use the stdlib or an existing dep. Keep only if it clearly earns its place. |
|
|
153
|
+
| **Premature abstraction / Abstraction Debt** *(scanner)* | new `*Factory` / `*Repository` / `*Mediator` / `*Strategy` / `*Builder` / `*Wrapper` / `*Orchestrator` / base class / interface, or CQRS / Event-Sourcing / DDD / Hexagonal layering with fewer than 2–3 real call sites *today* | Delete the layer; inline the direct code. "For future flexibility" is not a present problem. |
|
|
154
|
+
| **Redundant comments** *(scanner)* | a comment that restates the next line (`// increment i`, `# return the result`) | Delete it. Keep only comments that explain WHY. |
|
|
155
|
+
| **Type escapes** *(scanner)* | `as any`, `: any`, `@ts-ignore` / `@ts-nocheck`, `# type: ignore`, unsafe casts that silence the checker | Fix the type, not the checker. If a boundary is truly untypable, isolate ONE typed adapter instead of spraying `any`. |
|
|
156
|
+
| **Swallowed errors / Defensive inflation** *(scanner)* | empty `catch {}`, `.catch(() => {})`, bare/broad `except: pass`; try/catch wrapping that only hides failures | Let it fail loudly or handle it meaningfully. Delete catch-alls that exist to suppress. |
|
|
157
|
+
| **Happy-path only** | no handling for the null / empty / zero / boundary / error inputs the task implies | Add the missing edge-case handling. This is the one row where you ADD code. |
|
|
158
|
+
| **Hallucinated requirements** | features, options, config flags, endpoints, CLI args, or "nice to have" handling that no user message asked for and no existing code requires — walk the diff and trace every addition back to the request | Delete it. If you genuinely believe it's needed, ASK first — never ship unrequested scope. |
|
|
159
|
+
| **AI verbosity residue / Prompt residue** *(scanner)* | placeholder phrases (`in a real app`, `for production use`, `this is a simplified`, `TODO: implement actual`), emoji in code or log output, decorative banner walls (`// ===== HELPERS =====`), leftover debug prints | Delete on sight. None of these survive a human review. |
|
|
160
|
+
| **Duplicated logic** | new code mirrors something already in the repo | Delete the copy; call the existing function. Grep before you keep it. |
|
|
161
|
+
| **Clone proliferation / DRY / Knowledge duplication** | `--all` reports the same function name in ≥2 files, or identical bodies under different names (`isRecord` / `isObject` / `isPlainObject`) | Keep ONE canonical definition; re-point imports; delete the copies. One source of truth per concept. |
|
|
162
|
+
| **Utility explosion / Helper Hell / Fingerprints** | a swarm of tiny `is*` / `assert*` / `safe*` one-liners; fingerprints (`isRecord`, `safeParse`, `sleep`, `retry`, `assertNever`) | Inline single-use micro-helpers; consolidate genuinely shared ones into one module. |
|
|
163
|
+
| **Ignored conventions** | style / naming / structure / error-handling differs from the file's neighbours | Rewrite to match the surrounding code. |
|
|
164
|
+
| **Accidental complexity** | indirection / generics / config a junior can't read in 30s | Flatten to the simplest form that works. |
|
|
165
|
+
| **Superficial tests / Test theater** | the test asserts "it runs", mirrors the implementation, or cannot fail; literal tautologies (`expect(true).toBe(true)`, `assert True`) *(scanner)*; snapshot-everything, mocks of mocks, assertion poverty | Rewrite to assert real outcomes and the edge cases; delete tautological tests. |
|
|
166
|
+
| **API slop** | boolean traps (`fn(true, false)`), 5+ positional params, internals leaking through signatures, three names for one concept | Options object / named params; collapse the surface; one name per concept. |
|
|
167
|
+
| **State slop** | shared mutable module state, side effects hidden in getters, order-dependent calls (temporal coupling) | Localize state, make effects explicit, inject dependencies. |
|
|
168
|
+
| **Performance slop** | queries/IO inside loops (N+1), per-call allocation in hot paths, speculative caches nobody measured | Move IO out of loops; measure before caching; delete speculative caches. |
|
|
169
|
+
| **Documentation drift** | comments/docs describing behavior the code no longer has; stale examples that do not run | Fix or delete. Wrong docs are worse than no docs. |
|
|
170
|
+
| **Cargo cult / Semantic Density** | a pattern copied without its reason; you cannot state WHY it is there | Remove what you cannot justify. A shape you have seen ≠ a shape you need. |
|
|
171
|
+
| **Architectural violation / drift** | reaches across layers, business logic in the wrong place, breaks a project constraint — or **drift**: new top-level dirs, modules, or structural patterns that did not exist before this session | Move it to the right layer or revert to the established pattern. Structure changes need explicit user intent, not model initiative. |
|
|
172
|
+
|
|
173
|
+
### Detection regexes (for scanning by hand — the scanner automates all of these)
|
|
174
|
+
|
|
175
|
+
- Premature abstraction: `\b(class|interface|struct|trait|protocol)\s+[A-Z]\w*(Factory|Repository|Mediator|Strategy|Singleton|Facade|Builder|Visitor|Decorator|Wrapper|Orchestrator)\b`, plus `\b(CQRS|Event[\s-]?Sourcing|Domain[\s-]?Driven|Aggregate Root|Bounded Context|Hexagonal Architecture|Onion Architecture)\b`.
|
|
176
|
+
- Redundant comment: a `//`, `#`, or `*` line that restates the adjacent code verb-for-verb.
|
|
177
|
+
- New dependency: an added line in a dependency manifest declaring `name → version` (manifest metadata like `"version":` / `"node":` is exempt).
|
|
178
|
+
- Verbosity residue: `\b(in a real (app|application|world|scenario)|for production use|this is a simplified|TODO:? implement actual|replace (this )?with your)\b` (case-insensitive); emoji in source (`[\u2600-\u27BF\U0001F300-\U0001FAFF]`); banner walls `^\s*(//|#|/\*)\s*[=*#]{5,}` (`# ----` dividers are a human convention, not residue).
|
|
179
|
+
- Type escapes: `as any`, `as unknown as`, `[,:<]\s*any\b`, `any[]`, `@ts-(ignore|nocheck)` (`@ts-expect-error` is the sanctioned form — leave it); Python `#\s*type:\s*ignore`.
|
|
180
|
+
- Swallowed errors: `catch {}` / `catch (e) {}` empty on one line, `.catch(() => {})` / `.catch(() => null)`, bare `except:` or `except Exception:` followed by `pass` (`except ImportError: pass` is a legitimate idiom). Multi-line catch blocks holding only a comment need your judgement.
|
|
181
|
+
- Tautological tests: `expect(<literal>).toBe(<same literal>)`, `assert True`, `assertTrue(true|True)`, `assert(true)`.
|
|
182
|
+
- Async wrappers: `await Promise.resolve(`, `new Promise(async`.
|
|
183
|
+
- Guard chains: consecutive `if (!x) return` lines where each test deepens the previous (`!data` → `!data.user`) — the fix is optional chaining.
|
|
184
|
+
- Boolean traps: two adjacent literal booleans in a call argument list (`fn(a, true, false)`); array literals exempt.
|
|
185
|
+
- SELECT star: `\bSELECT\s+\*` in `.sql` files (`--` comment lines exempt).
|
|
186
|
+
- Tailwind: `class=` / `className=` strings ≥200 chars; arbitrary values ≥100px (`w-[347px]`).
|
|
187
|
+
- Hallucinated requirements have no regex — they are the diff-vs-request comparison in Verify. Same for architecture drift: compare the tree/imports against what existed at session start (`git diff --stat`, new dirs). Semantic, State, API, and Performance slop are judgement rows: no regex can see intent drift or temporal coupling without lying about confidence.
|
|
188
|
+
|
|
189
|
+
### Review lens — score the survivors
|
|
190
|
+
|
|
191
|
+
When judging what the regexes cannot see, score against: **semantic density**
|
|
192
|
+
(business value per line), **change surface area** (files touched per simple
|
|
193
|
+
change), **traceability** (intent → implementation time), **locality**
|
|
194
|
+
(understandable without opening 20 files), **dependency cost**, **abstraction
|
|
195
|
+
ROI** (value created ÷ complexity introduced), **architectural compression**
|
|
196
|
+
(smallest architecture that solves the problem), **blast radius** (what one
|
|
197
|
+
change can break), **cognitive load**, **intent preservation** (implementation
|
|
198
|
+
vs requirements), **file proliferation** (files added per feature),
|
|
199
|
+
**abstraction pressure** (abstractions with fewer than two real
|
|
200
|
+
implementations), **indirection depth** (clicks to find the implementation),
|
|
201
|
+
**state count** (mutable states per feature), **hydration cost** (islands vs
|
|
202
|
+
actual interactivity), **SQL efficiency** (queries per page render). Code that
|
|
203
|
+
scores badly on two or more is slop even though no regex caught it.
|
|
204
|
+
|
|
205
|
+
## Duplication / clones (whole-codebase)
|
|
206
|
+
|
|
207
|
+
`scan_slop.py --all` runs a cross-file analysis a per-diff view cannot — the core
|
|
208
|
+
of a full-codebase de-slop:
|
|
209
|
+
|
|
210
|
+
- **Clone proliferation** — same function name in ≥2 files (the "20 copies of
|
|
211
|
+
`isRecord`" problem).
|
|
212
|
+
- **Knowledge duplication** — identical bodies under different names
|
|
213
|
+
(`isRecord` / `isObject`); one concept scattered, so one conceptual change
|
|
214
|
+
becomes N edits (Divergent Change).
|
|
215
|
+
- **Generated-code fingerprints** — `isRecord`, `safeParse`, `sleep`, `retry`,
|
|
216
|
+
`assertNever` recurring at statistically abnormal rates.
|
|
217
|
+
- **Micro-abstraction load** — the share of tiny `is*`/`assert*`/`safe*` helpers
|
|
218
|
+
(Helper Hell / Semantic Density Collapse).
|
|
219
|
+
|
|
220
|
+
Fix: for each group pick ONE canonical definition (or inline a single-use
|
|
221
|
+
helper), re-point every import, delete the rest. Optimise for *knowledge
|
|
222
|
+
management*, not token volume — one source of truth per concept.
|
|
223
|
+
|
|
224
|
+
## Automatic final review
|
|
225
|
+
|
|
226
|
+
The `stop` hook (`anti-slop-final-review.ps1`) fires after the agent finishes
|
|
227
|
+
an implementation that edited files: it returns a `followup_message` Cursor
|
|
228
|
+
auto-submits, so the model re-audits everything it changed this session and
|
|
229
|
+
removes slop it introduced — one bounded pass.
|
|
230
|
+
|
|
231
|
+
## Hard constraints
|
|
232
|
+
|
|
233
|
+
- Preserve requested behaviour (the rule above) — this outranks every fix.
|
|
234
|
+
- Smallest diff: removing slop should *shrink* the change, not reshape working
|
|
235
|
+
code you never touched.
|
|
236
|
+
- Match the file's existing conventions whenever you rewrite.
|
|
237
|
+
- At most a couple of passes per file, then stop — don't thrash.
|
|
238
|
+
- This is a *quality* sweep, not a bug hunt. Correctness/security is the
|
|
239
|
+
self-review trigger's job; don't duplicate it here.
|
|
240
|
+
|
|
241
|
+
## Report template
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
=== Anti-Slop Sweep ===
|
|
245
|
+
Scope: {diff | files}
|
|
246
|
+
Removed:
|
|
247
|
+
- {N} premature abstraction(s): {names}
|
|
248
|
+
- {N} unnecessary dependency(ies): {names}
|
|
249
|
+
- {N} redundant comment(s)
|
|
250
|
+
- {duplication inlined / tests hardened / edge cases added / complexity flattened}
|
|
251
|
+
Left (with reason): {intent-bearing items deliberately not touched}
|
|
252
|
+
Diff: {before} → {after} lines. Tests: {pass | n/a}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Cursor setup
|
|
256
|
+
|
|
257
|
+
| | |
|
|
258
|
+
|--|--|
|
|
259
|
+
| Install path | `~/.cursor/skills/anti-slop/` |
|
|
260
|
+
| Invoke | `/anti-slop`, or "remove the AI slop" |
|
|
261
|
+
| Scanner | `python scripts/scan_slop.py --all` |
|
|
262
|
+
| Final review | automatic via `stop` hook |
|
|
263
|
+
|
|
264
|
+
The scanner is stdlib-only and needs Python 3.9+. Pairs with the **anti-slop
|
|
265
|
+
hook** (advisory, per edit), the **stop hook** (auto final review), and
|
|
266
|
+
**minimal-editing** (smallest-diff). This skill is the active "delete it now"
|
|
267
|
+
layer those only nudge toward.
|