slopbrick 0.11.2 → 0.15.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/README.md CHANGED
@@ -1,902 +1,209 @@
1
1
  # slopbrick
2
2
 
3
- > **The AI-coding-agent drift detector.** Stops the `zustand + redux in the same project`, the three-modal-systems, the off-scale `p-[13px]`, the hardcoded `sk-...` keys, and the `expect(x).toBeDefined()` tests that no one wrote and no one will run. Run `npx slopbrick` and get a single Repository Coherence score (0–100) with per-rule precision/recall so you know which findings to fix and which to ignore. Add the MCP server and your AI agent reads your existing patterns before it writes new ones.
3
+ > **AI agents forget your architecture. Every session starts fresh.**
4
+ >
5
+ > SlopBrick gives your codebase persistent structure — so agents follow your
6
+ > patterns instead of reinventing them.
7
+
8
+ The fix is one command: `npx slopbrick scan` writes
9
+ `.slopbrick/{inventory.json, constitution.json, health.json, structure.md}`.
10
+ The next time your AI agent writes a file — Claude Code, Cursor,
11
+ Copilot, Aider — it reads `.slopbrick/structure.md` instead of re-parsing
12
+ the AST. **100–1000× faster** on the agent integration, and the
13
+ agent's first suggestion matches what the project already uses, not
14
+ what the LLM trained on.
4
15
 
5
- **The problem.** AI coding assistants write logic well, but they drift. Every project ends up with three button variants, a hardcoded API key, inline styles next to Tailwind utilities, and a test file full of `expect(x).toBeDefined()`. The drift isn't the agent's fault — it's that the agent doesn't know your conventions. Existing linters catch syntax; nothing catches "you just invented a fourth modal system when this repo already has three."
6
-
7
- **What this does.** `slopbrick` extracts the canonical patterns from your codebase (state lib, form lib, modal system, API client, data-fetching), enforces a declared Constitution at PR time, and exposes the pattern inventory to AI agents via MCP (`slop_suggest`) so they reuse what's there instead of inventing new patterns. The headline Repository Coherence score (0–100) is a proof that the Constitution is being followed — but the actual moat is the Constitution + Pattern Inventory itself, not the number.
8
-
9
- ## What an AI agent gets from `slop_suggest` (the primary entry point)
10
-
11
- The MCP tool `slop_suggest` returns, in one call:
12
-
13
- - **Existing patterns** — the canonical modal, button, API client, state library, data-fetching library the project already uses.
14
- - **Do-not-create list** — explicit `constitution.forbidden` packages + canonical patterns not to duplicate.
15
- - **Top issues by rule** — what to fix first in the changed files.
16
- - **Hot files by issue count** — where the slop is concentrated.
17
- - **Composite Repository Health** — the headline 0-100 score.
18
-
19
- > **Call this BEFORE writing new code so the agent reuses existing patterns instead of duplicating them.**
20
-
21
- `src/mcp/tools.ts:69-81`. The MCP server is one command: `slopbrick mcp`.
22
-
23
- ## Headline 5-bucket score (compressed from 13 subscores)
24
-
25
- The full diagnostic surface is 13 subscores. The user-facing surface is 5 buckets:
26
-
27
- | Bucket | What it measures | One-line question | v4.1 calibration |
28
- |--------|------------------|-------------------|------------------|
29
- | **Architecture Consistency** | Cross-file pattern duplication + token usage + component reuse | "Are components and patterns consistent?" | 8 USEFUL rules, top signal: Pattern Fragmentation |
30
- | **AI Slop Signal** | Ghost defensive code, debug logs, unused state, missing auth, hardcoded secrets | "Does this look like AI wrote it?" | 18 USEFUL rules with measured P/R/FPR |
31
- | **Security** | Hardcoded secrets, dangerous CORS, unsafe HTML, SQL concat, missing auth | "Are there security holes?" | 4 USEFUL, 3 INVERTED |
32
- | **Delivery Quality** | Test quality, business-logic coherence, docs freshness | "Can the team ship safely?" | 4 PASS, 3 INVERTED |
33
- | **Codebase Health** | DB schema, design-token drift, product consistency | "Will this codebase hold up at scale?" | 5 INVERTED/DORMANT — calibration pending |
34
-
35
- `Repository Health` (the composite) = `0.25 × Architecture + 0.30 × AI Slop + 0.25 × Security + 0.10 × Delivery + 0.10 × Codebase`.
36
-
37
- The 13-subscore diagnostic surface remains available behind `slopbrick scan --format json` and `--format detailed` for the calibration / power-user audience.
38
-
39
- ## Why this works (calibration evidence, v4.1)
40
-
41
- The rules are calibrated against a balanced 1:1 corpus:
42
-
43
- - **95,467 human-written frontend files** — 39 production repos (mui 16k, supabase 6.8k, antd 5.5k, storybook 3.5k, react-spectrum 3.3k, refine 6.3k, appsmith 5.5k, heroui 2.1k, …) + 54,980 from `ai-slop-baseline`.
44
- - **76,981 AI-generated frontend files** — 50 existing repos + **100 NEW shallow-cloned vibe-coded repos** (Claude Code, Cursor, Lovable, Bolt, gpt-pilot, v0, BloopAI, tldraw) in `corpus-expansion/positive/vibe-coded/`.
45
-
46
- The form engineers actually trust, per-rule (full table in [`docs/research/v4-per-rule-pr-fpr.md`](./docs/research/v4-per-rule-pr-fpr.md)):
47
-
48
- > `security/missing-auth-check` fires on **0.63% of AI files** and **0.04% of human files**. When it fires, **92% of the time the file is AI**.
49
-
50
- Top 5 AI signals (v4.1 P/R/FPR):
51
-
52
- | Rule | Precision | Lift | Verdict |
53
- |------|----------:|-----:|---------|
54
- | `logic/ghost-defensive` (dead `if (x) return` guards) | 94.74% | 22.5× | USEFUL |
55
- | `security/missing-auth-check` (auth bypass) | 92.47% | 15.3× | USEFUL |
56
- | `logic/math-console-log-storm` (debug logs everywhere) | 89.84% | 11.0× | USEFUL |
57
- | `logic/zombie-state` (unused `useState`) | 83.33% | 6.2× | USEFUL |
58
- | `test/duplicate-setup` (`beforeEach` copy-paste) | 70.97% | 3.1× | USEFUL |
59
-
60
- The 18 USEFUL rules have **per-file P/R/FPR thresholds** in `tests/integration/calibration-expanded.test.ts` that fail CI when the signal drifts. See [`docs/research/calibration-report-2026.md`](./docs/research/calibration-report-2026.md) for the full calibration trajectory (v1 ratio → v3 ratio → v4 ratio → **v4.1 P/R/FPR**).
61
-
62
- ## For humans
63
-
64
- - `slopbrick scan` in CI gates PRs on `slopIndex` and the Constitution.
65
- - `slopbrick pr` scores the PR itself, weighted by severity.
66
- - `slopbrick architecture` is the headline consistency number.
67
- - `slopbrick security` is the categorical security gate.
68
- - `slopbrick test` / `business-logic` / `patterns` / `db` are specialised subcommands.
69
- - `slopbrick drift` exits 1 on any Constitution violation.
70
- - `slopbrick --format json` exposes the 13-subscore diagnostic surface + per-rule P/R/FPR for the calibration audience.
71
-
72
- ## For AI agents
73
-
74
- Install the MCP server (`@slopbrick/mcp`), then call `slop_suggest` before writing new code. The agent never has to guess what's already in the codebase.
75
-
76
- ## What it does not do
77
-
78
- It does **not** detect whether a human or AI wrote the code. It surfaces patterns that AI generates disproportionately (4 modal systems, exposed `NEXT_PUBLIC_OPENAI_API_KEY`, `if (NODE_ENV === 'development') return true`), and enforces the constitution the project has declared.
79
-
80
- ---
81
-
82
- ## 13-score diagnostic surface (for the calibration audience)
83
-
84
- The headline 5-bucket score is a compression of 13 subscores. The full surface is what `slopbrick scan --format json` returns, and what the [`tests/integration/calibration-expanded.test.ts`](./tests/integration/calibration-expanded.test.ts) test guards against drift.
85
-
86
- **Tier 1 — Deterministic (Constitution enforcement):**
87
-
88
- | Score | Shape | Use it for |
89
- |-------|-------|------------|
90
- | **Slop Index** | 0–100 | Frontend lint quality (composite) |
91
- | **Architecture Consistency** | 0–100 | Cross-file pattern duplication |
92
- | **AI Security Risk** | `low` / `medium` / `high` / `critical` | AI-induced security failures |
93
- | **Constitution drift** | pass / fail | Imports that violate the declared stack |
94
- | **Design-token drift** | inline violations | Spacing/radius off declared scales |
95
- | **Pattern Fragmentation** | 0–100 | How many competing patterns per category (modal / auth / state / api / …) — *the input to `slop_suggest`'s `doNotCreate` list* |
96
- | **PR Slop Score** | integer | One number per PR, weighted by severity |
97
-
98
- **Tier 2 — Heuristic (specialised subcommands):**
99
-
100
- | Score | Shape | Use it for |
101
- |-------|-------|------------|
102
- | **Test Quality** | 0–100 | AI test smells |
103
- | **Business Logic Coherence** | 0–100 | Pricing precision, validation completeness |
104
- | **Documentation Freshness** | 0–100 | Stale READMEs, drift between docs and code |
105
- | **Database Health** | 0–100 | Missing indexes, N+1, soft-delete inconsistencies |
106
-
107
- **Tier 3 — Derived (dashboards):**
108
-
109
- | Score | Shape | Use it for |
110
- |-------|-------|------------|
111
- | **Repository Health** | 0–100 | Weighted average of the 5 buckets |
112
- | **AI Maintenance Cost** | $/month | $ cost of fixing the issues, given velocity |
113
- | **AI Debt band** | A / B / C / D / F | Letter grade from the above two |
114
-
115
- ---
116
-
117
- ## What's new in 0.7.0
118
-
119
- > **Repository Constitution Engine for AI Coding Agents.** The moat is the Constitution. Everything else is a score that proves it's being followed.
120
-
121
- 0.7.0 is the **Constitution-first release** — three new specialised subcommands (`test`, `business-logic`, `patterns`), a one-number-per-PR score (`pr`), the `forbidden` deny-list for explicit "never use this", and the rename from `conventions` to `constitution` everywhere.
122
-
123
- The 0.6.x series built the foundation. The 0.7.x series turns the Constitution from a config field into a working contract — AI agents that read it via MCP (`slop_suggest`) and humans that enforce it via PR gates.
124
-
125
- **What landed in 0.7.0:**
126
-
127
- - `slopbrick pr` — one weighted number per PR, gates on `--threshold`
128
- - `slopbrick test` — Test Quality score (0–100) + 4 `test/*` rules
129
- - `slopbrick business-logic` — Business Logic Coherence score (0–100) + 8 rules
130
- - `slopbrick patterns` — Pattern Fragmentation score (0–100), 8 categories
131
- - `constitution.forbidden` — explicit deny-list (e.g. `['moment', 'lodash']`)
132
- - `conventions` → `constitution` rename across config, types, MCP tool names, report columns
133
-
134
- ### 0.6.0 – 0.6.4 recap (the foundation)
135
-
136
- 0.6.0 was the engine re-architecture. The 0.6.1 – 0.6.4 patch series shifts the framing from "AI slop detector" to **repository coherence engine** — the same scanner, now with three new scores, MCP tools so AI agents check before they PR, and eight security rules for AI-induced failures.
137
-
138
- Five orthogonal scores, all in `slopbrick scan`:
139
-
140
- | Score | Shape | Use it for |
141
- |-------|-------|------------|
142
- | **Slop Index** | 0–100 | Frontend lint quality |
143
- | **Architecture Consistency** | 0–100 | Cross-file pattern duplication *(0.6.3)* |
144
- | **AI Security Risk** | `low` / `medium` / `high` / `critical` | AI-induced security failures *(0.6.4)* |
145
- | **Constitution drift** | pass / fail | Imports that violate declared stack *(0.6.2)* |
146
- | **Design-token drift** | inline violations | Spacing/radius off declared scales *(0.6.3)* |
147
-
148
- The slop detector is still here — but the bigger lever is *coherence*: one modal system, one state library, one fetch lib, a declared constitution that the AI agent checks before PR.
149
-
150
- ### What landed in 0.6.1 – 0.6.4
151
-
152
- **0.6.4 — AI Security Risk (new score) + 8 Tier-1/Tier-2 security rules**
153
-
154
- NOT a security scanner — Semgrep / GHAS / CodeQL / Gitleaks own that. This is a **categorical** score (`low | medium | high | critical`) for security failures that AI generates disproportionately. Independent of `slopIndex` — security failures do not get diluted into "good slop score" territory.
155
-
156
- - `security/hardcoded-secret` — provider prefixes (`sk-`, `sk-ant-`, `AKIA`, `ghp_`, `sk_live_`, `AIza`, `xox[abprs]-`) + sensitive-name literals.
157
- - `security/exposed-env-var` — `NEXT_PUBLIC_*` / `VITE_*` / etc. with secret names — inlined into every browser build.
158
- - `security/dangerous-cors` — wildcard `Access-Control-Allow-Origin: *` + `cors({ origin: '*' })` + reflective `cors({ origin: true })`.
159
- - `security/missing-auth-check` — Next.js `route.ts` / `pages/api` / Express handlers with no auth primitive.
160
- - `security/unsafe-html-render` — `dangerouslySetInnerHTML` fed a non-literal value.
161
- - `security/fail-open-auth` — `if (NODE_ENV === 'development') return true/next()`.
162
- - `security/sql-construction` — template-literal / concat SQL queries (use parameterized queries).
163
- - `security/public-admin-route` — routes under `/admin`, `/internal`, `/debug`, `/staff`, `/manage`, `/private`, etc. without an additional role check.
164
-
165
- New `slopbrick security [--format pretty|json] [--strict]` subcommand. `--strict` exits 1 on high/critical (CI gate).
166
-
167
- **0.6.3 — Architecture Consistency Score (the headline metric) + design-token enforcement**
168
-
169
- One 0–100 number that reflects how consistent a repository's patterns are. Subtracts from 100 for each pattern-duplication finding: `-12` per extra modal system, `-8` per extra button variant, `-10` per extra API client module, `-15` per extra state library (highest), `-10` per extra data-fetching library, `-1` per 5 off-scale spacing values, `-1` per 5 off-scale radius values. A project with 1 modal, 1 button, 1 api client, 1 state lib, 1 fetch lib lands at 100. A project with 3 modal systems + 4 button variants + 2 state libs lands at 37.
170
-
171
- Two new rules turn design tokens from docs into enforceable contracts:
172
- - `visual/spacing-scale-violation` — flags `p-[13px]`, `gap-[1.75rem]` etc. off the declared `spacingScale`.
173
- - `visual/radius-scale-violation` — flags `rounded-[7px]`, `rounded-tl-[2rem]` etc. off the declared `radiusScale`.
174
-
175
- Both emit auto-fix candidates so `slopbrick scan --fix` rewrites `p-[13px]` → `p-1`.
176
-
177
- **0.6.2 — Repository governance for AI coding agents**
178
-
179
- The single feature most projects asked for. New top-level `constitution` field in `slopbrick.config.mjs`:
180
-
181
- ```js
182
- export default {
183
- constitution: {
184
- stateManagement: ['zustand'],
185
- dataFetching: ['react-query'],
186
- uiLibrary: ['shadcn', 'radix'],
187
- forms: ['react-hook-form', 'zod'],
188
- styling: ['tailwind'],
189
- routing: ['next'],
190
- },
191
- };
16
+ ```bash
17
+ npm install -D slopbrick
18
+ npx slopbrick init # write .slopbrick/constitution.json
19
+ npx slopbrick scan # write .slopbrick/structure.md
20
+ npx slopbrick mcp # start the MCP server (Claude / Cursor)
192
21
  ```
193
22
 
194
- Auto-detected from `package.json` when unset; user declarations always win.
195
-
196
- - `slopbrick drift` — CLI command, exits 1 on any violation (CI-friendly).
197
- - `slop_suggest` MCP tool — project-wide inventory of existing patterns; AI agents call before writing new code.
198
- - `slop_check_constitution` MCP tool — per-file constitution diff.
199
- - `slop_architecture_score` MCP tool — Architecture Consistency Score via MCP.
200
-
201
- **0.6.1 — bug fixes + small refinements**
202
-
203
- - `slopbrick trend --format markdown` now actually emits markdown (the local flag was being shadowed by the global scan `--format`; renamed to `--render`).
204
- - Calibration test surfaces stderr/stdout on chunk failures instead of swallowing them.
205
- - v1.x working-tree labels stripped.
206
-
207
- ### CLI surface summary (post-0.8.0)
208
-
209
- | Command | Purpose |
210
- |---------|---------|
211
- | `slopbrick scan` | Main scan — runs all rules + computes all 8 scores |
212
- | `slopbrick architecture` | Architecture Consistency Score only |
213
- | `slopbrick security` | AI Security Risk only |
214
- | `slopbrick drift` | Constitution-violation scanner |
215
- | `slopbrick pr` | PR slop score (single weighted number per PR) |
216
- | `slopbrick test` | Test Quality score (4 `test/*` rules) |
217
- | `slopbrick business-logic` | Business Logic Coherence score (8 rules) |
218
- | `slopbrick patterns` | Pattern Fragmentation score (input to `slop_suggest`) |
219
- | `slopbrick maintenance-cost` | AI Maintenance Cost (categorical low/medium/high/critical + $/month) *(0.8.0)* |
220
- | `slopbrick docs` | Documentation Freshness (4 `docs/*` rules) *(0.8.0)* |
221
- | `slopbrick db` | Database Health (6 `db/*` rules, Postgres-only) *(0.8.0)* |
222
- | `slopbrick mcp` | MCP server (`slop_scan_file`, `slop_explain_rule`, `slop_list_rules`, `slop_suggest`, `slop_check_constitution`, `slop_architecture_score`) |
223
- | `slopbrick trend` | Slop Index trend over time |
224
- | `slopbrick flywheel` | Aggregated scan telemetry |
225
- | `slopbrick init` | Interactive setup wizard |
226
-
227
- ### What 0.6.x did *not* change
228
-
229
- - **No new competitor overlap.** We did not add a general security scanner, dependency vulnerability scanner, formatter, type checker, or coverage tool.
230
- - **No breaking CLI changes.** Existing scan commands, JSON / SARIF / HTML output formats, and public-API exports are unchanged.
231
-
232
- The full release history is in [CHANGELOG.md](./CHANGELOG.md).
233
-
234
- ---
235
-
236
- ## Why this matters (research-backed)
237
-
238
- The 0.7.0 release sits on top of an industry that's converging fast on AI-generated-code debt. The numbers below are from 2024–2026 studies and explain why the Constitution, not the Slop Index, is the moat.
23
+ For the prevention layer:
239
24
 
240
- - **AI slows experienced developers.** METR's July 2025 RCT (16 experienced open-source devs, 246 tasks on repos averaging 22k stars / 1M LoC) found AI tools produced a **19% slowdown** — developers had expected a 24% speedup. ([METR, 2025](https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/))
241
- - **AI-generated code carries 1.7× more issues per PR** (10.83 vs 6.45) and a higher share of critical/major issues. ([CodeRabbit, 2025](https://coderabbit.ai/blog/state-of-ai-vs-human-code-generation-report))
242
- - **Refactoring is collapsing.** GitClear's 211M-line analysis of Google/Microsoft/Meta repos shows "refactored" lines fell from 25% → <10% and "copy-pasted" lines rose from 8.3% → 12.3% between 2021–2024. ([GitClear, 2025](https://www.gitclear.com/ai_assistant_code_quality_2025_research))
243
- - **PR size is up 51%, bugs/PR up 28%, incidents/PR up 3×, code churn up 10×** across 22k developers in 2026. ([Faros AI, 2026](https://www.faros.ai/research/ai-acceleration-whiplash))
244
- - **Trust in AI accuracy dropped from 40% → 29%** in one year; 66% of devs spend *more* time debugging AI output. ([Stack Overflow 2025 Developer Survey](https://survey.stackoverflow.co/2025/ai))
245
- - **Code-surface ↔ doc-surface staleness is an open hole.** No shipped tool (Docusaurus, Mintlify, GitBook, mkdocstrings, TypeDoc) cross-references `package.json` ↔ README or exported names ↔ markdown inline code. The 2026 state-of-the-art is F1 = 96.73% on a single analog task (description-code inconsistency, [arXiv 2606.04769](https://arxiv.org/html/2606.04769v1)). That's what `slopbrick docs` ships against in 0.8.0.
246
- - **Schema-quality static analysis is an open hole for Drizzle.** The official `eslint-plugin-drizzle` has exactly 2 rules. Prisma has 8+ Prisma-Lens rules but they target per-file linting, not schema-wide drift. Squawk owns migration safety; nobody owns schema quality. That's the wedge for `slopbrick db` in 0.8.0.
247
- - **The canonical AI-coding-agent failure is the AWS Kiro outage (Dec 2025).** An agentic coding tool autonomously deleted a production environment; 13-hour outage in a China region. ([Docker blog, 2026](https://www.docker.com/blog/coding-agent-horror-stories-the-13-hour-aws-outage/)) The post-mortem: "predictable given unchecked AI permissions." The preventive: a Constitution the agent checks before it acts, with a `$306,000/yr/MLoC` baseline for what the debt costs when it isn't checked. ([Sonar, 2025](https://www.sonarsource.com/blog/new-research-from-sonar-on-cost-of-technical-debt/))
248
-
249
- The full research notes for each 0.8.0 phase are in [`docs/research/`](./docs/research/).
250
-
251
- **Mathematical foundations** — the peer-reviewed methods behind every threshold:
252
- [`docs/research/math-foundations-for-slopbrick.md`](./docs/research/math-foundations-for-slopbrick.md) maps 8 published results (Halstead 1977, Hindle 2012, Rissanen 1978, Kullback-Leibler 1951, Blondel 2008, Fiedler 1973, McCabe 1976, Adams-MacKay 2007) to the slopbrick rules and composite scores that cite them. v0.9.3+ ships the highest-leverage ones (Halstead, Code Naturalness, MDL composite) to replace heuristic thresholds with closed-form citations.
253
-
254
- **v0.10 implementation plan** — the credibility-milestone roadmap with dependency graph, effort estimates per phase, and readiness checklist: [`docs/research/v0.10-implementation-plan.md`](./docs/research/v0.10-implementation-plan.md). Phases 1–5 (~4 working days) ship v0.10; Phases 6–11 land the far-horizon graph-theoretic, Repository Memory, `--diff`, `find_similar_function`, BRICK, and SARIF work.
255
-
256
- ---
25
+ ```bash
26
+ slopbrick watch # re-run scan on every file change
27
+ slopbrick lock # install the Git pre-commit hook
28
+ slopbrick ci # CI gate: exit 1 on constitution violation
29
+ ```
257
30
 
258
- ## Roadmap
259
-
260
- | Version | Themes | Status |
261
- |---------|--------|--------|
262
- | 0.5.x | Engine re-architecture, Slop Index, framework support | Shipped |
263
- | 0.6.x | Constitution, Architecture Consistency, AI Security Risk, design-token enforcement | Shipped |
264
- | 0.7.0 | Constitution rename + `forbidden` deny-list, `pr` subcommand, Test / Business-Logic / Patterns subcommands | Shipped 2026-06-25 |
265
- | 0.8.0 | `docs` (Doc Drift), `db` (Database Health, Postgres-static), `maintenance-cost` ($/month categorical) | Shipped 2026-07-15 |
266
- | **0.9.0** | **Repository Coherence Scanner reframe, default-off INVERTED + NOISY rules, expanded `slop_suggest`, new `slop_governance` MCP tool** | **Shipped 2026-08-15** |
267
- | **0.10** | **Credibility milestone: per-rule P/R/FPR + peer-reviewed thresholds (Halstead, McCabe, Hindle, Rissanen, Kullback-Leibler); MDL composite replaces heuristic weights** | **In flight — see [`docs/research/v0.10-implementation-plan.md`](./docs/research/v0.10-implementation-plan.md)** |
268
- | 1.0 | Stability commitment — 6+ months post-v0.10 empirical feedback; freezes the surface, no new scores | Far horizon |
269
-
270
- Per-version research notes:
271
- - [Phase 6 — Doc Drift](./docs/research/phase-6-doc-drift-internet-2026.md)
272
- - [Phase 8 — DB Health](./docs/research/phase-8-db-health-internet-2026.md)
273
- - [Memo #4 — AI Maintenance Cost](./docs/research/phase-memo4-ai-cost-internet-2026.md)
274
- - [Math foundations — peer-reviewed methods for v0.9.3+ rules](./docs/research/math-foundations-for-slopbrick.md)
275
- - [v0.10 implementation plan — credibility milestone roadmap](./docs/research/v0.10-implementation-plan.md)
31
+ **This isn't CLAUDE.md.** CLAUDE.md is a static file the agent reads once
32
+ per session. `.slopbrick/structure.md` is a generated artifact that updates
33
+ on every scan your repository, encoded for the next agent.
276
34
 
277
35
  ---
278
36
 
279
- ## Installation
280
-
281
- Run once without installing:
282
-
283
- ```bash
284
- npx slopbrick
285
- ```
37
+ ## What you get
286
38
 
287
- Add to a project as a dev dependency:
39
+ - **Repository Structure** the four `.slopbrick/` artifacts (structure,
40
+ inventory, constitution, health) make your codebase queryable by
41
+ any AI agent in O(read file) instead of O(parse AST).
42
+ - **LockBrick prevention** — `slopbrick watch` flags violations as you
43
+ write, `slopbrick lock` blocks AI-introduced slop at pre-commit,
44
+ `slopbrick ci` enforces the same in CI.
45
+ - **Constitution** — declare your canonical stack (state lib, form
46
+ lib, modal system, API client) once. The agent and the linter
47
+ enforce it together.
288
48
 
289
- ```bash
290
- pnpm add -D slopbrick
291
- ```
49
+ **Status:** v0.15.0 (current). See the [CHANGELOG](./CHANGELOG.md) for
50
+ the full release notes.
292
51
 
293
52
  ---
294
53
 
295
54
  ## Quick start
296
55
 
297
- Initialize a config in the project root:
298
-
299
56
  ```bash
300
- npx slopbrick init
301
- ```
57
+ # 1. Install
58
+ npm install -D slopbrick
302
59
 
303
- Scan the current workspace:
60
+ # 2. Initialize (8 quick questions about your stack)
61
+ npx slopbrick init
304
62
 
305
- ```bash
63
+ # 3. Scan (writes .slopbrick/ artifacts)
306
64
  npx slopbrick scan
307
- ```
308
-
309
- Or scan specific paths:
310
65
 
311
- ```bash
312
- npx slopbrick scan src app
66
+ # 4. Optional: start the MCP server so Claude Code / Cursor can
67
+ # consume the artifacts
68
+ npx slopbrick mcp
313
69
  ```
314
70
 
315
- On first run, `slopbrick` auto-detects your framework, styling solution, UI libraries (Tailwind, Tamagui, shadcn/ui, MUI, etc.), and workspace packages. Framework presets automatically disable or downgrade rules that are idiomatic for React Native, Expo, or Tamagui.
316
-
317
- ### Don't want to write a config from scratch?
318
-
319
- Four ready-to-use starter configs live in [`examples/`](./examples):
71
+ That's it. The agent integration is O(read file) for the next session.
320
72
 
321
- - [`examples/basic/`](./examples/basic) — sensible defaults for most projects
322
- - [`examples/strict/`](./examples/strict) — CI gating with `noIncrease` baseline
323
- - [`examples/monorepo/`](./examples/monorepo) — pnpm/turbo workspaces
324
- - [`examples/ci/`](./examples/ci) — JSON + SARIF output for code-scanning upload
325
-
326
- ```bash
327
- cp examples/strict/slopbrick.config.mjs ./slopbrick.config.mjs
328
- npx slopbrick validate-config # check it before running a scan
329
- ```
330
-
331
- See [`examples/README.md`](./examples/README.md) for the full walkthrough.
332
-
333
- ---
334
-
335
- ## Configuration
336
-
337
- Config lives at `slopbrick.config.mjs` in the project root. It is an ES module that exports a default object.
338
-
339
- ```js
340
- export default {
341
- include: ['src/**/*', 'app/**/*', 'pages/**/*', 'components/**/*'],
342
- exclude: [
343
- '**/node_modules/**',
344
- '**/*.test.{ts,tsx,js,jsx}',
345
- '**/*.stories.{ts,tsx}',
346
- '**/.next/**',
347
- '**/dist/**',
348
- '**/build/**',
349
- '**/coverage/**',
350
- ],
351
-
352
- // Per-category weight multiplier
353
- categoryWeights: {
354
- visual: 1.2,
355
- logic: 1.0,
356
- perf: 0.8,
357
- typo: 0.5,
358
- wcag: 1.0,
359
- layout: 1.0,
360
- component: 1.0,
361
- arch: 1.0,
362
- security: 1.0,
363
- },
364
-
365
- // CI threshold (Phase 2 §10: composite Slop Index only)
366
- thresholds: {
367
- meanSlop: 30,
368
- },
369
-
370
- // Rule severity overrides.
371
- // 'auto' keeps the rule's natural severity; 'off' disables it.
372
- rules: {
373
- 'visual/inline-style': 'auto',
374
- 'visual/hardcoded-color': 'low',
375
- 'logic/style-sheet-avoidance': 'medium',
376
- },
377
-
378
- // Boost or reduce scores for specific frameworks
379
- frameworkMultipliers: {
380
- astro: 0.8,
381
- },
382
-
383
- // Phase 2 §10: brick.config.json import paths. Defaults to common
384
- // shadcn-style paths. Imports from `@/components/*` not matching
385
- // these prefixes are flagged by `context/import-path-mismatch`.
386
- allowedImports: [
387
- '@/components/ui/',
388
- '@/components/',
389
- '@/lib/',
390
- '@/hooks/',
391
- ],
392
- };
393
- ```
394
-
395
- ### Key options
396
-
397
- | Option | What it does |
398
- |--------|--------------|
399
- | `include` | File patterns to scan (default: all source files) |
400
- | `exclude` | File patterns to skip |
401
- | `categoryWeights` | Make certain issue types count more or less |
402
- | `thresholds` | CI gates — see "Thresholds" below |
403
- | `rules` | Turn specific rules off or change their severity |
404
- | `frameworkMultipliers` | Boost/reduce scores for specific frameworks |
405
- | `arbitraryValueAllowlist` | Tailwind values that are OK to use |
406
- | `allowedImports` | brick.config.json import paths (Phase 2 §10) |
407
- | `wcag` | Accessibility-specific settings |
408
-
409
- ---
410
-
411
- ## Composite Slop Index (Phase 2 §10)
412
-
413
- slopbrick produces a single composite score that prioritizes structural integrity over minor visual escapes:
414
-
415
- ```
416
- S = (0.40 × S_boundary) + (0.35 × S_context) + (0.25 × S_visual)
417
- ```
418
-
419
- Each subscore is `min(100, severityPoints / componentCount)`, where `severityPoints` is the sum of severity weights for issues in that bucket.
420
-
421
- **Bucket weights:**
422
-
423
- | Bucket | Weight | What it measures |
424
- |--------|-------:|------------------|
425
- | **Boundary** | 40% | Structural integrity: file-size limits, multiple components per file, direct API calls in UI |
426
- | **Context** | 35% | Prop correctness, imports, state management |
427
- | **Visual** | 25% | CSS, layout, typography, accessibility |
428
-
429
- **Rule → Subscore mapping:**
430
-
431
- - **Boundary (40%)**: `logic/boundary-violation`, `component/giant-component`, `component/multiple-components-per-file`
432
- - **Context (35%)**: `component/shadcn-prop-mismatch`, `arch/astro-island-leak`, `context/import-path-mismatch`, most `logic/*`
433
- - **Visual (25%)**: all `visual/*`, `layout/*`, `typo/*`, `wcag/*`, `perf/*`
73
+ For a CI gate, see [`EXAMPLES.md`](./EXAMPLES.md#strict-ci-gate).
74
+ For monorepo setup, see [`EXAMPLES.md`](./EXAMPLES.md#monorepo-multi-package).
75
+ For every other config question, see [`EXAMPLES.md`](./EXAMPLES.md).
434
76
 
435
77
  ---
436
78
 
437
- ## CLI reference
438
-
439
- ```text
440
- Usage: slopbrick [options] [command]
441
-
442
- Options:
443
- -V, --version output the version number
444
- --framework <name> framework multiplier to apply
445
- --include <glob> include pattern (repeatable)
446
- --exclude <glob> exclude pattern (repeatable)
447
- --ai-only only report AI-specific issues
448
- --human-only only report human-facing issues
449
- --ignore-wcag22 ignore WCAG 2.2 related issues
450
- --format <pretty|json|sarif|html> output format (default: "pretty")
451
- --threads <n> number of worker threads
452
- --since <ref> only scan files changed since git ref
453
- --workspace <path> workspace/project path
454
- --tighten tighten baseline allowances
455
- --fix apply auto-fixes
456
- --dry-run preview fixes without writing any files
457
- --diff print unified diff of proposed auto-fixes
458
- --doctor run diagnostics
459
- --watch watch files and re-run
460
- --suggest print remediation advice
461
- --heatmap print migration ROI heatmap
462
- --quiet suppress non-error output
463
- --strict exit 2 if any high-severity issue remains
464
- --no-increase exit 2 if slop index increased since last run
465
- --auto-disable-noisy-rules downgrade rules whose measured precision < 0.5
466
- or recall < 0.1 by one severity step
467
- --baseline save a baseline after this scan
468
- --trend [n] print a sparkline of the last n runs
469
- --json [path] write JSON report to path or stdout
470
- --html [path] write HTML report to path or stdout
471
- --staged scan only staged files
472
- --changed scan working-tree changes
473
- --incremental skip unchanged files via content-hash cache
474
- --cache-path <path> path to the incremental cache (default: .slop-audit-cache.json)
475
- --tokens <path> merge tokens.json layout values into the
476
- arbitrary-value allowlist
477
- --cache cache parsed AST results locally
478
- --rule <ruleId> run a single rule by id, skip all others
479
- -h, --help display help for command
480
-
481
- Commands:
482
- init [options] create a slopbrick config file
483
- install install the git pre-commit hook
484
- uninstall uninstall the git pre-commit hook
485
- badge print a shields.io slop-index badge
486
- suggest print remediation advice
487
- flywheel [options] summarize aggregated scan telemetry
488
- scan [paths...] scan files for slop
489
- explain <ruleId> print rationale, pattern, and remediation for a single rule
490
- tokens <path> ingest a W3C DTCG tokens.json and summarize it by category
491
- report <path> re-render a saved JSON report (from --json path.json)
492
- doctor check your setup, config, and environment for common problems
493
- rules [--category <name>] [--ai-only] [--json]
494
- list all built-in rules with descriptions
495
- mcp run an MCP server (for AI agents)
496
- help [command] display help for command
497
- ```
498
-
499
- ### pr — score a pull request
500
-
501
- `slopbrick pr` runs the engine over the files changed between two
502
- git refs and returns a single weighted slop score. The score is
503
- `sum(SEVERITY_WEIGHTS[issue.severity]) + constitution_violations`
504
- per file, summed across the diff. With the default threshold of
505
- `20` (configurable via `prScoreThreshold` or `--threshold`), a PR
506
- can introduce roughly 4 medium-severity issues before it fails.
507
-
508
- ```bash
509
- slopbrick pr [--base <ref>] [--head <ref>]
510
- [--format text|json|markdown]
511
- [--threshold <n>] [--max-files <n>]
512
- ```
513
-
514
- Defaults: `--base main` (falls back to `master` then the first
515
- commit), `--head HEAD`, `--format text`, `--threshold 20`,
516
- `--max-files 500`. The diff is computed with three-dot syntax
517
- (`git diff --name-only base...head`), which matches GitHub's PR
518
- view (merge-base comparison).
519
-
520
- ```text
521
- $ slopbrick pr
522
- PR score: 4 (threshold: 20) — PASS
523
- Base: main Head: HEAD
524
- Files changed: 1
79
+ ## The headlines (v0.15.0+ — 4-score model)
525
80
 
526
- src/store.ts issues=1 constitution=1 score=4
527
- [medium ] security/public-admin-route line 1
528
- [forbidden] Constitution violation: imports 'redux' (canonical: 'redux').
81
+ > **v0.15.0 breaking change:** The single `Slop Index` is replaced by
82
+ > **4 independent scores** (all 0-100, **higher = better**). The legacy
83
+ > `slopIndex` field is kept as optional on `ProjectReport` for backward
84
+ > compat with existing test fixtures and historical telemetry; will be
85
+ > removed in v0.16.0.
529
86
 
530
- ────────────────────────────────────────────
531
- PR score: 4 / 20 threshold — PASS
532
- ```
87
+ | Score | What it measures | CI gate? |
88
+ |-------|------------------|----------|
89
+ | **`AI Quality`** | How good the AI-generated code is (USEFUL + OK rules) | **Yes** (≥ 70 passes) |
90
+ | **`Engineering Hygiene`** | Internal consistency — one stack, one pattern, no drift | No (informational) |
91
+ | **`Security`** | Security findings (security/* rules) | No (informational) |
92
+ | **`Repository Health`** (composite) | Weighted sum of the 3 + secondary signals | No (informational) |
533
93
 
534
- Use it as a CI gate:
94
+ `AI Quality` is composed of boundary (40%) + context (35%) + visual (25%).
535
95
 
536
- ```yaml
537
- - run: npx slopbrick pr --threshold 10
538
- # exits 1 when PR score > 10
539
- ```
96
+ The same numbers are in `.slopbrick/health.json`.
540
97
 
541
- ### Exit codes
98
+ For the full math, the 2×2 quadrant, and which one to focus on, see
99
+ [`docs/scoring-explained.md`](./docs/scoring-explained.md).
542
100
 
543
- | Code | Meaning |
544
- |------|---------|
545
- | `0` | Composite Slop Index under `meanSlop` threshold |
546
- | `1` | Composite Slop Index exceeds threshold |
547
- | `2` | High-severity issues with `--strict`, score regression with `--no-increase`, or hook install failure |
548
- | `3` | Unexpected scan error (parser crash, worker failure after retries) |
101
+ For per-rule precision/recall/FPR (auditable), see
102
+ [`src/rules/signal-strength.json`](./src/rules/signal-strength.json).
549
103
 
550
104
  ---
551
105
 
552
- ## Example terminal output
106
+ ## Example output
553
107
 
554
108
  ```text
555
109
  $ npx slopbrick scan
556
- Scanned 312 files, 501 components, 1423 issues (high: 48, medium: 321, low: 1054)
110
+ Repo is concerning (25/100). The biggest problem is AI patterns — worst file is src/cli/scan.ts. Run `slopbrick scan --why-failing` for the top 5 rules, or `slopbrick scan --suggest` for fixes.
557
111
 
558
- Slop Index: 14.2 / 100 [PASS]
559
- (Phase 2 §10 composite: 0.40 × Boundary + 0.35 × Context + 0.25 × Visual)
560
- ├─ Boundary Slop: 12.5 (Weighted: 5.0)
561
- ├─ Context Slop: 4.0 (Weighted: 1.4)
562
- └─ Visual Slop: 31.0 (Weighted: 7.8)
112
+ AI Quality: 25 / 100 [CONCERNING] ↑5 (worse)
113
+ higher = better · measures AI-slop signatures. The same number in .slopbrick/health.json.
114
+ ├─ boundary: 10 (40%) — structural integrity
115
+ ├─ context: 50 (35%) — props / state / imports
116
+ └─ visual: 5 (25%) — CSS / a11y / layout
563
117
 
564
- Top offending components
565
- 72.3 src/app/(tabs)/keepsakes.tsx
566
- 65.1 src/app/(tabs)/search.tsx
567
- 58.0 src/app/child/[id]/edit.tsx
568
- ...
118
+ Engineering Hygiene: 60 / 100 [NEEDS WORK] — higher = better · measures internal consistency. This is a secondary view; the AI Quality above is the gate.
569
119
 
570
- Thresholds
120
+ Other signals (not the gate):
121
+ Code Hygiene 75/100
122
+ Accessibility 100/100
123
+ Performance 100/100
124
+ Business Logic 0/100
125
+ Security Risk LOW
571
126
 
572
- Composite Slop Index 14.2 30 pass
127
+ 99 INVERTED/NOISY issues correctly suppressed from 24 default-off rules.
573
128
 
574
- All thresholds passed.
129
+ Category breakdown (what kind of issue, and how much):
130
+ AI patterns ████████████████████ 167 — signatures of LLM-generated code
131
+ visual style ████████░░░░░░░░░░░░ 70 — colors, spacing, font sizes, layout
132
+ logic patterns ████████░░░░░░░░░░░░ 68 — state, hooks, prop usage
133
+ 13 other categories are clean
575
134
 
576
- Issues (1423)
577
- [HIGH ] logic/boundary-violation · src/app/(tabs)/keepsakes.tsx:91:22
578
- Data layer mixed with UI component
579
- Move fetch/state into a server action or hook.
135
+ Next step:
136
+ `slopbrick scan --rule src/cli/scan.ts` to drill into the worst file (4 issues)
137
+ `slopbrick scan --suggest` for auto-fix advice
138
+ `slopbrick scan --baseline` to accept today's scores as the new floor
139
+ → `slopbrick scan --why-failing` for the top 5 issues dragging the score down
580
140
  ```
581
141
 
582
- ---
583
-
584
- ## How scoring works
585
-
586
- ### Severity weights
587
-
588
- | Severity | Weight |
589
- |----------|-------:|
590
- | high | 5 |
591
- | medium | 3 |
592
- | low | 1 |
593
-
594
- (The `critical` tier was removed during the scoring-model refactor to prevent scoring inflation.)
595
-
596
- ### Per-file scoring
597
-
598
- For each file, the engine:
599
- 1. Parses the source (SWC for TS/JS, regex for HTML, dedicated parsers for Vue/Svelte/Astro).
600
- 2. Walks the AST to extract facts: imports, JSX elements, class names, inline styles, hooks, state bindings, etc.
601
- 3. Runs each of the 42 registered rules against the facts.
602
- 4. Each rule returns 0+ issues with severity, line, column, and optional fix suggestions.
603
-
604
- ### Project scoring (Phase 2 §10)
605
-
606
- 1. **Bucket** every issue into one of three subscores (boundary, context, visual) using the rule-to-bucket map.
607
- 2. **Sum** severity weights per bucket: `bucketPoints[b] = Σ SEVERITY_WEIGHTS[issue.severity]`.
608
- 3. **Normalize**: `subscore[b] = min(100, bucketPoints[b] / componentCount × 100)`.
609
- 4. **Composite**: `slopIndex = 0.40 × boundary + 0.35 × context + 0.25 × visual`.
610
- 5. **Health**: `assemblyHealth = max(0, 100 - slopIndex)`.
611
-
612
- ### Threshold
613
-
614
- A single threshold (`meanSlop`) gates the exit code: `slopIndex > meanSlop` → exit 1.
142
+ `--brief` (CI/scripts): same headline + threshold + delta in 4 lines.
143
+ `--why-failing`: top 5 rules ranked by weighted impact.
144
+ `--suggest`: per-rule auto-fix advice.
615
145
 
616
146
  ---
617
147
 
618
- ## Architecture
619
-
620
- ### High-level pipeline
621
-
622
- ```
623
- ┌────────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
624
- │ CLI bin/ │───▶│ discover │───▶│ parser │───▶│ visitor │───▶│ rules │
625
- │ slopbrick │ │ discover │ │ engine/ │ │ engine/ │ │ rules/ │
626
- │ .js │ │ .ts │ │ parser.ts│ │ visitor.ts│ │ *.ts │
627
- └────────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
628
-
629
-
630
- ┌────────────┐ ┌──────────────┐ ┌────────────────┐ ┌─────────────────┐
631
- │ Output │◀───│ aggregate │◀───│ report │◀───│ ProjectReport │
632
- │ report/ │ │ metrics │ │ ProjectReport│ │ (per-issue) │
633
- │ *.ts │ │ metrics.ts │ │ │ │ │
634
- └────────────┘ └──────────────┘ └────────────────┘ └─────────────────┘
635
- ```
636
-
637
- ### End-to-end flow (`slopbrick scan`)
638
-
639
- 1. **CLI entry** (`bin/slopbrick.js`)
640
-
641
- Loads `dist/index.js` (the bundled CLI), parses command-line flags with Commander, and resolves `cwd` from `--workspace` or `process.cwd()`.
642
-
643
- 2. **Config loading** (`src/config.ts`)
644
-
645
- Walks up from cwd looking for `slopbrick.config.{js,mjs,cjs,ts}`, merges the user config with `DEFAULT_CONFIG` (which sets `thresholds`, `rules`, `allowedImports`), and validates the merged result against the schema.
646
-
647
- 3. **File discovery** (`src/discover.ts`)
648
-
649
- Uses `globby` to expand `include` patterns and `minimatch` to apply `exclude`. For files without an extension, it reads the first 512 bytes and sniffs the content type (TSX/TS/JSX/JS/Vue/Svelte/Astro/HTML). It de-duplicates by basename when both extension-less and proper-extension versions exist, then filters by `SOURCE_EXTENSIONS` (`.ts`, `.tsx`, `.js`, `.jsx`, `.vue`, `.svelte`, `.astro`, `.html`).
650
-
651
- 4. **Per-file scanning** (`src/engine/worker.ts`, `src/engine/parser.ts`, `src/engine/visitor.ts`)
652
-
653
- Runs in worker threads (configurable via `--threads`).
654
-
655
- The **parser** dispatches based on file extension: SWC for TS/JS, dedicated handlers for Vue/Svelte/Astro, regex for HTML. Extension-less files try TSX → TS → JSX → JS in order.
148
+ ## Documentation
656
149
 
657
- The **visitor** walks the AST and extracts a `ScanFacts` summary, including:
658
- - `imports[]` — `{source, importedNames, line, column}`
659
- - `interactiveElements[]` JSX `<button>`, `<a>`, `<input>`, etc. with attributes
660
- - `staticClassNames[]` className string literals
661
- - `styleProps[]` inline `style={{...}}` props
662
- - `componentSizes[]` per-component line count + JSX branch count
663
- - `propBindings[]`, `stateBindings[]`, `hooks[]`, `logicalExpressions[]`, etc.
150
+ | If you want to... | Read this |
151
+ |-------------------|-----------|
152
+ | Add a new rule (most common contribution) | [`CONTRIBUTING.md`](./CONTRIBUTING.md) |
153
+ | Configure for strict CI, monorepo, Python, etc. | [`EXAMPLES.md`](./EXAMPLES.md) |
154
+ | Understand the Slop Index vs Coherence | [`docs/scoring-explained.md`](./docs/scoring-explained.md) |
155
+ | Connect Claude Code / Cursor / Copilot | [`docs/MCP.md`](./docs/MCP.md) |
156
+ | See the 4 `.slopbrick/` artifacts (structure, inventory, ...) | [`docs/repository-structure.md`](./docs/repository-structure.md) |
157
+ | See the 80 rules (per-rule descriptions + citations) | [`docs/rule-catalog.md`](./docs/rule-catalog.md) |
158
+ | See how the engine works (parser → facts → rules) | [`docs/architecture.md`](./docs/architecture.md) |
159
+ | See which frameworks are supported | [`docs/framework-parity-matrix.md`](./docs/framework-parity-matrix.md) |
160
+ | See what's changed in each release | [`CHANGELOG.md`](./CHANGELOG.md) |
161
+ | See the strategic plan (0.14 → 0.15 → 1.0) | [`ROADMAP.md`](./ROADMAP.md) |
162
+ | See research behind the calibration | [`docs/research/`](./docs/research/) |
163
+ | Report a security vulnerability | [`SECURITY.md`](./SECURITY.md) |
164
+ | Run a CI gate | `slopbrick ci` (see [`EXAMPLES.md`](./EXAMPLES.md#strict-ci-gate)) |
664
165
 
665
- **Rule execution** iterates the registered rules (built-ins + user overrides) and calls each rule's `analyze(facts, context)` method, collecting `Issue[]`.
666
-
667
- 5. **Aggregation** (`src/engine/metrics.ts`)
668
-
669
- Sums severity points per subscore bucket (boundary / context / visual), normalizes each bucket by component count capped at 100, and computes `slopIndex = 0.40 × boundary + 0.35 × context + 0.25 × visual`. Returns the structured `ProjectReport` with all subscores, severity counts, and per-file scores.
670
-
671
- 6. **Threshold check** (`src/cli/threshold.ts`)
672
-
673
- Calls `thresholdExceeded(report, config)`, which compares `report.slopIndex` against `config.thresholds.meanSlop`. Returns true → exit code 1. Also checks per-category thresholds (`categoryThresholds`) if configured.
674
-
675
- 7. **Output rendering** (`src/report/`)
676
-
677
- One module per format:
678
- - `pretty.ts` — human-readable terminal output with the composite breakdown tree
679
- - `json.ts` — serialized `ProjectReport` (full data)
680
- - `sarif.ts` — SARIF 2.1.0 for IDE/editor integration
681
- - `html.ts` — self-contained HTML report with score cards
682
- - `markdown.ts` — Markdown report for PR comments
683
- - `heatmap.ts` — migration ROI heatmap (top files by score)
684
- - `unified-diff.ts` — unified diff of the report
685
- - `advice.ts` — remediation suggestions
686
- - `flywheel.ts` — telemetry summary
687
-
688
- ### File layout
689
-
690
- ```
691
- src/
692
- ├── index.ts # Public facade (re-exports from ./cli/)
693
- ├── config.ts # Public config facade (re-exports from ./config/)
694
- ├── config/ # config/{defaults,presets,detect,load,init}
695
- ├── cli/ # CLI surface (Commander wiring + scan + init engines)
696
- │ ├── program.ts # runCli — Commander setup, per-command .action() callbacks
697
- │ ├── scan.ts # runScan, scanProject, watchProject, renderOutput
698
- │ ├── init.ts # runInitWizard, runDoctor, init prompts
699
- │ ├── options.ts # CLI option parsers (parseThreads, collectGlob, …)
700
- │ ├── render.ts # colorForSlop, formatBadge, formatSparkline, …
701
- │ └── threshold.ts # thresholdExceeded, stagedGating, filterIssues, …
702
- ├── engine/
703
- │ ├── parser.ts # SWC/Vue/Svelte/Astro/HTML dispatch + extension-less fallback
704
- │ ├── visitor.ts # AST walker → ScanFacts extraction (1313 lines — largest file)
705
- │ ├── worker.ts # Per-file scan worker thread
706
- │ ├── metrics.ts # Composite Slop Index aggregation
707
- │ ├── logger.ts # Test-aware logging
708
- │ ├── pool.ts # WorkerPool with work-stealing + retry
709
- │ ├── executor.ts # Inline scan path for small file counts
710
- │ ├── cache.ts # .slop-audit-cache.json + baseline.json
711
- │ ├── memory.ts # run-history.json (--trend, --no-increase)
712
- │ ├── telemetry.ts # Flywheel payloads
713
- │ └── trend.ts # --trend sparkline builder
714
- ├── rules/ # Rule modules (42 built-in rules across 9 categories)
715
- │ ├── arch/ # 1 rule — astro-island-leak
716
- │ ├── component/ # 3 rules — giant-component, multiple-components-per-file,
717
- │ │ shadcn-prop-mismatch
718
- │ ├── context/ # 1 rule — import-path-mismatch
719
- │ ├── layout/ # 4 rules — gap-monopoly, math-element-uniformity,
720
- │ │ math-grid-uniformity, spacing-grid
721
- │ ├── logic/ # 11 rules — boundary-violation, ghost-defensive,
722
- │ │ key-prop-missing, math-any-density,
723
- │ │ math-console-log-storm, math-gini-class-usage,
724
- │ │ math-variable-name-entropy, optimistic-no-rollback,
725
- │ │ qwik-hook-leak, reactive-hook-soup, zombie-state
726
- │ ├── perf/ # 2 rules — cls-image, css-bloat
727
- │ ├── typo/ # 5 rules — calc-fontsize, calc-raw-px, clamp-offscale,
728
- │ │ math-button-label-uniformity, math-cta-vocabulary
729
- │ ├── visual/ # 11 rules — arbitrary-escape, clamp-soup, generic-centering,
730
- │ │ inline-style-dominance, math-color-cluster,
731
- │ │ math-default-font, math-font-entropy,
732
- │ │ math-gradient-hue-rotation, math-rounded-entropy,
733
- │ │ math-spacing-entropy
734
- │ ├── wcag/ # 4 rules — dragging-movements, focus-appearance,
735
- │ │ focus-obscured, target-size
736
- │ ├── builtins.ts # Auto-generated registry (pnpm generate:rules)
737
- │ ├── rule.ts # createRule + RuleDefinition types
738
- │ ├── registry.ts # RuleRegistry (loadBuiltins, loadProjects)
739
- │ ├── registry-loader.ts # shadcn/ui registry snapshot cache
740
- │ ├── project.ts # Project-level rules (runProjectRules)
741
- │ ├── signal-strength.ts # --show-signal-strength lookup
742
- │ └── signal-strength.json # Per-rule precision/recall measurements
743
- ├── report/ # Output formatters (pretty, json, sarif, html, …)
744
- │ ├── pretty.ts, json.ts, sarif.ts, html.ts, markdown.ts
745
- │ ├── advice.ts # --suggest output
746
- │ ├── unified-diff.ts # --diff output
747
- │ ├── heatmap.ts # --heatmap output
748
- │ ├── flywheel.ts # flywheel summary
749
- │ └── html/ # html/{utils,sections,static}.ts
750
- ├── fix/ # Auto-fix codemods
751
- │ ├── index.ts # applyFixes orchestrator
752
- │ ├── visual-codemod.ts # Round-20 visual codemods entry point
753
- │ └── visual-codemods/ # tailwind.ts, jsx.ts, source.ts
754
- ├── snippet.ts # AI agent rule snippet generators (facade)
755
- ├── snippet/ # snippet/{data,render,generators,targets}
756
- ├── flywheel.ts # Flywheel state machine
757
- ├── mcp/ # MCP server (src/mcp/server.ts + tools)
758
- ├── research/ # research/generate, analyze, candidates, calibrate
759
- ├── config-validation.ts # Static config schema validator
760
- ├── discover.ts # File discovery + extension sniffing
761
- ├── git.ts # --staged / --changed / --since git integration
762
- ├── installer.ts # install/uninstall git pre-commit hook
763
- ├── explain.ts # `slopbrick explain <ruleId>` output
764
- ├── tokens.ts # W3C DTCG tokens.json parser
765
- ├── types.ts # All public types (ProjectReport, ScanFacts, Issue, …)
766
- └── bin/ # bin/slopbrick.js entry point
767
- ```
166
+ The 19 subcommands are auto-generated from commander and run
167
+ `slopbrick --help` to see them.
768
168
 
769
169
  ---
770
170
 
771
- ## MCP server (for AI agents)
772
-
773
- slopbrick ships a [Model Context Protocol](https://modelcontextprotocol.io/) server so AI coding agents can call it directly:
171
+ ## Installation
774
172
 
775
173
  ```bash
776
- slopbrick mcp # JSON-RPC 2.0 over stdio
174
+ npm install -D slopbrick
777
175
  ```
778
176
 
779
- Exposes three tools:
177
+ Requires Node 18+. The package ships ESM + CJS dual builds, TypeScript
178
+ types, and is published to npm as `slopbrick`.
780
179
 
781
- | Tool | Args | Returns |
782
- |------|------|---------|
783
- | `slop_scan_file` | `{path, framework?}` | issues + Slop Index for one file |
784
- | `slop_explain_rule` | `{ruleId}` | rule metadata + rationale + file location |
785
- | `slop_list_rules` | `{category?}` | all rules with category / severity / aiSpecific |
786
-
787
- Add to your MCP client config:
180
+ For the MCP server, add to your AI agent's config:
788
181
 
789
182
  ```json
790
183
  {
791
184
  "mcpServers": {
792
- "slopbrick": {
793
- "command": "npx",
794
- "args": ["slopbrick", "mcp"],
795
- "cwd": "/path/to/your/project"
796
- }
185
+ "slopbrick": { "command": "npx", "args": ["slopbrick", "mcp"] }
797
186
  }
798
187
  }
799
188
  ```
800
189
 
801
- ### AI agent rule snippets
802
-
803
- Generate directive snippets that teach your AI agent the slop rules BEFORE it writes code:
804
-
805
- ```bash
806
- slopbrick init --matrix # print the matrix table
807
- slopbrick init --yes --agents-md # Codex / opencode / Pi / Cline / Gemini
808
- slopbrick init --yes --claude-md # Claude Code
809
- slopbrick init --yes --all # all targets at once
810
- ```
811
-
812
- | Flag | File | Agent |
813
- |------|------|-------|
814
- | `--cursor` | `.cursor/rules/slopbrick.mdc` | Cursor (new format) |
815
- | `--cursorrules` | `.cursorrules` | Cursor (legacy format, deprecated) |
816
- | `--agents-md` | `AGENTS.md` | OpenAI Codex / opencode / Pi / Cline / Continue / Gemini |
817
- | `--claude-md` | `CLAUDE.md` | Claude Code (takes precedence over AGENTS.md) |
818
- | `--aider` | `CONVENTIONS.md` | Aider |
819
- | `--windsurf` | `.windsurfrules` | Windsurf (Cascade) |
820
- | `--cline` | `.clinerules/AGENTS.md` | Cline (folder-based) |
821
- | `--gemini` | `.gemini/GEMINI.md` | Gemini CLI |
822
- | `--copilot` | `.github/copilot-instructions.md` | GitHub Copilot |
823
-
824
- Content is generated live from the rule registry — always matches what slopbrick actually checks.
825
-
826
- ---
827
-
828
- ## Adding new rules
829
-
830
- Rule modules live in `src/rules/<category>/<rule>.ts`. Each module must export a const ending in `Rule` and a matching default export:
831
-
832
- ```ts
833
- import { createRule } from '../rule';
834
- import type { Issue, Rule, RuleContext, ScanFacts } from '../../types';
835
-
836
- export const myRule = createRule<RuleContext>({
837
- id: 'category/my-rule',
838
- category: 'visual',
839
- severity: 'medium',
840
- aiSpecific: true,
841
- description: 'Short one-line description used in `slopbrick rules` output.',
842
- create(context) {
843
- return context;
844
- },
845
- analyze(_context, facts: ScanFacts): Issue[] {
846
- const issues: Issue[] = [];
847
- // ... analyze facts ...
848
- return issues;
849
- },
850
- });
851
-
852
- export default myRule satisfies Rule<RuleContext>;
853
- ```
854
-
855
- Run `pnpm generate:rules` to regenerate `src/rules/builtins.ts`. This runs automatically before `pnpm build` and `pnpm test`.
190
+ See [`docs/MCP.md`](./docs/MCP.md) for Cursor, Continue, and other
191
+ clients.
856
192
 
857
193
  ---
858
194
 
859
- ## Calibration against held-out human code
195
+ ## Contributing
860
196
 
861
- The tool ships with an automated calibration test (`tests/integration/calibration.test.ts`) that scans both corpora and asserts every AI-signal rule has a recall/FP ratio ≥ its threshold. It runs as part of `pnpm test` and exits non-zero on regression.
862
-
863
- The corpora live at `/Users/cheng/ai-slop-baseline/extracted/`:
864
- - `positive/` — 6,142 AI-generated samples (vibe-coded React apps).
865
- - `negative/` 54,980 human-written samples (shadcn/ui, calcom, dub, mantine, excalidraw, lobehub, etc.).
866
-
867
- A rule with a recall/FP ratio above 1.0× is a useful AI tell. A ratio below 1.0× is an anti-signal — tighten it, scope-restrict it, or drop it.
868
-
869
- ---
870
-
871
- ## Glossary
872
-
873
- - **Slop Index** — 0–100 composite score per Phase 2 §10. Lower is better. Weighted average of boundary (40%), context (35%), and visual (25%) subscores.
874
- - **Assembly Health** — Inverse of Slop Index. Higher is better.
875
- - **Composite Slop Index** — Phase 2 §10's weighted three-bucket formula.
876
- - **AI-specific rule** — Rule that catches patterns AI defaults to but humans rarely do (e.g. `bg-violet-500`, "Get started today", badge-above-h1 layout).
877
- - **General rule** — Catches real bugs or code-quality issues regardless of author.
878
- - **brick.config.json** — Project config (in `slopbrick.config.mjs`) listing allowed import paths for `context/import-path-mismatch`.
879
- - **RSC / Server component** — React Server Component. Runs on the server, can't use `useState`/`useEffect`. The fix is `'use client'`.
880
- - **Memoization** — React skips re-renders if inputs haven't changed. Inline handlers break memoization because they're new functions on every render.
881
- - **Astro island** — Interactive component inside an otherwise static Astro page. Without `client:*` directive, clicks won't fire.
882
- - **DTCG tokens** — W3C Design Token Community Group JSON format. `slopbrick tokens <path>` reads these.
883
- - **MCP** — Model Context Protocol. JSON-RPC 2.0 over stdio for AI agent integration.
884
-
885
- ---
886
-
887
- ## Development
888
-
889
- ```bash
890
- pnpm install
891
- pnpm typecheck
892
- pnpm test
893
- pnpm build
894
- ```
197
+ See [`CONTRIBUTING.md`](./CONTRIBUTING.md) tl;dr: copy
198
+ `src/rules/visual/naturalness-anomaly.ts`, edit the `analyze()` body,
199
+ add a test in `tests/rules/`, then add a `defaultOff: true` entry to
200
+ `src/rules/signal-strength.json`. v0.14.5k's calibration will
201
+ validate the rule on the next corpus run.
895
202
 
896
- Adding a rule? Update `tests/integration/calibration.test.ts` to add a calibration entry — the corpus test will verify your rule discriminates AI from human code.
203
+ We follow the [Contributor Covenant](./CODE_OF_CONDUCT.md).
897
204
 
898
205
  ---
899
206
 
900
207
  ## License
901
208
 
902
- [MIT](./LICENSE)
209
+ [MIT](./LICENSE) © 2026 Brick.dev