Skip to content

Commit 7750bb2

Browse files
committed
add skill
1 parent 22a4668 commit 7750bb2

2 files changed

Lines changed: 608 additions & 0 deletions

File tree

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
---
2+
name: reduce-complexity
3+
description: >
4+
Analyze code for complexity hotspots and suggest simplifications. Identifies functions
5+
exceeding evidence-based LOC and nesting thresholds, classifies complexity as essential
6+
(domain-inherent, leave alone) or accidental (reducible), and produces actionable
7+
reduction suggestions with safety annotations. Use PROACTIVELY when: reviewing files
8+
or modules for maintainability, before refactoring to find highest-ROI targets, triaging
9+
tech debt, when the user says "simplify", "reduce complexity", "find complex functions",
10+
"what should I refactor", "maintainability review", "this file is too complex", "hard
11+
to understand", or asks about code quality or readability of specific files. Also use
12+
when examining large functions (>100 lines) during code review. Works on any language
13+
with emphasis on Rust-specific patterns. Does NOT perform automated refactoring -- it
14+
detects, explains, and suggests.
15+
---
16+
17+
# Code Complexity Reduction
18+
19+
Detect complexity hotspots, classify them as essential or accidental, and suggest
20+
specific reduction techniques with safety annotations. The core value is not metric
21+
computation (Clippy already does that) but explaining WHY code is complex and WHETHER
22+
reduction is safe in context.
23+
24+
## When to use
25+
26+
- Reviewing a file or module for maintainability
27+
- Before refactoring, to identify the highest-ROI targets
28+
- Triaging tech debt across a codebase or directory
29+
- When a function feels hard to understand and you want to know why
30+
- During code review of large or deeply nested functions
31+
32+
## When NOT to use
33+
34+
- For code review (use code-review skills instead)
35+
- For performance optimization (use performance-analyzer)
36+
- For automated refactoring (use refactoring-assistant)
37+
- For style/formatting issues (use cargo fmt / linters)
38+
39+
---
40+
41+
## Input
42+
43+
| Form | Example | Behavior |
44+
|------|---------|----------|
45+
| File path | `/reduce-complexity src/cache.rs` | Analyze all functions in the file |
46+
| Directory | `/reduce-complexity src/` | Scan source files, report top-N hotspots |
47+
| No argument | `/reduce-complexity` | Scan all non-test source files, report top-10 |
48+
49+
Exclude test files (`*_tests.rs`, `tests/`) from default scans unless explicitly passed.
50+
Test code has different complexity norms.
51+
52+
---
53+
54+
## Analysis Pipeline
55+
56+
Execute these four phases in order. Read the target code before starting.
57+
58+
### Phase 1: Detection
59+
60+
Enumerate every function in the target scope. For each, measure:
61+
62+
1. **LOC** -- lines from opening `{` to closing `}`, excluding blanks and comment-only lines
63+
2. **Max nesting depth** -- with the Rust match discount (see below)
64+
3. **Parameter count** -- including `&self`/`&mut self`
65+
4. **Unsafe presence** -- whether the function body contains `unsafe` blocks
66+
5. **Clippy annotations** -- any `#[allow(clippy::...)]` on the function or enclosing impl
67+
68+
Flag a function if ANY independent threshold triggers:
69+
70+
| Metric | Advisory | Moderate | High | Critical |
71+
|--------|----------|----------|------|----------|
72+
| LOC | 51-100 | 101-200 | 201-400 | >400 |
73+
| Nesting | 4 | 5-6 | 7+ | -- |
74+
| Params | 6-7 | 8+ | -- | -- |
75+
76+
Advisory items appear only in the codebase overview unless another metric also triggers.
77+
78+
**Rank** flagged functions by: number of thresholds exceeded (descending), then LOC
79+
(descending). Cap output at 15 functions per file, 25 per directory.
80+
81+
#### Why these metrics, not cyclomatic/cognitive complexity
82+
83+
LOC is the most stable defect predictor across all major studies (Menzies, Hatton,
84+
Lessmann). Cyclomatic complexity correlates with LOC at r > 0.9 -- it catches
85+
nothing LOC misses. Cognitive complexity adds only 5.26% accuracy and the Clippy
86+
team placed their implementation in the `restriction` group as unreliable for Rust.
87+
Independent threshold checks are transparent and evidence-based.
88+
89+
#### Rust match discount
90+
91+
An exhaustive `match` on an enum with <= 6 variants counts as nesting +0 (no increment).
92+
Rust's exhaustive matching is a type-safety mechanism, not decision complexity. A
93+
`match` on `Result<T, E>` or a 4-variant enum is idiomatic.
94+
95+
A `match` on a runtime value (integer, string) or an enum with >6 variants counts
96+
as normal nesting +1.
97+
98+
### Phase 2: Classification
99+
100+
For each flagged function, read it and its surrounding context (enclosing impl,
101+
module doc, called functions). Classify as:
102+
103+
- **ESSENTIAL** -- complexity is inherent to the problem domain; leave alone
104+
- **ACCIDENTAL** -- complexity is reducible; suggestions follow
105+
- **MIXED** -- some essential, some accidental; suggestions target only the accidental part
106+
107+
Use these tests to make the judgment:
108+
109+
1. **Domain necessity**: Would a clean-room reimplementation solving the same problem
110+
have similar structure? If yes, the complexity is essential.
111+
112+
2. **Error handling**: Does each branch handle a semantically distinct error case with
113+
distinct recovery (logging, circuit breaker signaling, metrics, cleanup)? If yes,
114+
the branching is essential -- not reducible by collapsing.
115+
116+
3. **Sequential coupling**: Do steps have data or control dependencies preventing
117+
reordering? If yes, the sequential length is essential.
118+
119+
4. **Accidental indicators**: Duplicated logic blocks (same pattern 3+ times), deep
120+
nesting flattenable with early returns, boilerplate extractable to a helper,
121+
parameters always passed together (struct opportunity), conditions testing
122+
implementation state rather than domain state.
123+
124+
Include a 1-2 sentence rationale with each classification.
125+
126+
### Phase 3: Suggestions
127+
128+
For ACCIDENTAL and MIXED functions, recommend specific techniques. Read
129+
`references/techniques.md` for the full catalog of 12 techniques with preconditions,
130+
contraindications, and presentation templates.
131+
132+
Techniques are classified by confidence:
133+
134+
| Category | Techniques | Confidence |
135+
|----------|-----------|------------|
136+
| Fully automatable (5) | Guard clauses, redundant else removal, remove unnecessary Result, pass by reference, type aliases | `auto-apply` or `suggest` |
137+
| Judgment-required (4) | Extract function, ? operator, merge match arms, let-else | `suggest` or `flag-for-review` |
138+
| Not automatable (3) | Collapse if-chains, polymorphism, decompose state machine | `flag-for-review` only |
139+
140+
**Never suggest more than 3 techniques per function.** More than 3 signals the
141+
function needs broader redesign, not incremental fixes. Say so explicitly.
142+
143+
### Phase 4: Safety Checks
144+
145+
Apply these checks after generating suggestions. They can override or annotate output.
146+
147+
1. **Unsafe exclusion zone**: If the function contains `unsafe`, or calls a function
148+
in the same module that contains `unsafe` -- label "MANUAL REVIEW REQUIRED" and
149+
suppress all suggestions except guard clauses. Unsafe invariants (like `set_len` +
150+
`truncate`, `#[repr(align)]`, FFI contracts) often span multiple statements and are
151+
invisible to any analysis.
152+
153+
2. **Clippy annotation respect**: If the function has `#[allow(clippy::...)]`, note
154+
the developer made a deliberate decision. Do not suppress suggestions but lower
155+
confidence by one level.
156+
157+
3. **Over-abstraction brake** (for extract-function suggestions):
158+
- **Shallow module check**: If `param_count + return_type_fields >= body_lines / 3`,
159+
warn that the extraction interface is nearly as complex as the body.
160+
- **Single call-site + high coupling**: If the extracted code would be called from
161+
exactly 1 site AND requires >3 parameters, warn about locality destruction.
162+
- **Zero intention gap**: If the body is only stdlib/library calls with no domain
163+
logic, warn that a function name adds no information.
164+
165+
4. **Async boundary warning**: If a suggestion involves extracting code containing
166+
`.await` points, warn about `Send` bound implications and recommend `cargo check`.
167+
168+
5. **Validation requirement**: Any accepted suggestion must pass `cargo check` +
169+
`cargo clippy`. Characterization tests alone are insufficient -- they miss
170+
`Send`/`Sync` violations and lifetime constraint breakages.
171+
172+
---
173+
174+
## Output Format
175+
176+
Structure the report with these four sections:
177+
178+
### Section 1: Hotspot Summary
179+
180+
A ranked table:
181+
182+
```
183+
## Complexity Hotspots
184+
185+
| # | Function | Location | LOC | Nesting | Params | Flags | Class |
186+
|---|----------|----------|-----|---------|--------|-------|-------|
187+
```
188+
189+
Flags use abbreviated severity: `LOC:High`, `Nest:Mod`, `Params:Mod`.
190+
Class is ESSENTIAL, ACCIDENTAL, or MIXED.
191+
192+
### Section 2: Per-Function Analysis
193+
194+
One block per flagged function, in rank order:
195+
196+
```
197+
### #N: `function_name` (file:line) -- CLASSIFICATION
198+
199+
**Metrics:** N LOC | max nesting M | K params
200+
**Flags:** which thresholds triggered
201+
202+
**Why it is complex:** 2-3 sentences explaining the dominant complexity driver.
203+
204+
**Essential vs Accidental:** What is inherent to the domain vs what is structural.
205+
206+
**Suggestions:** (only for ACCIDENTAL/MIXED)
207+
1. TECHNIQUE (confidence): explanation, before/after sketch, impact estimate
208+
- Over-abstraction check result if applicable
209+
- Safety warnings if applicable
210+
```
211+
212+
### Section 3: Codebase Health Overview
213+
214+
Aggregate statistics:
215+
216+
```
217+
## Codebase Health
218+
219+
| Metric | Value | Assessment |
220+
|--------|-------|------------|
221+
| Functions exceeding LOC threshold | N / total (%) | vs Pareto norm (10-20%) |
222+
| Functions exceeding nesting threshold | N / total (%) | |
223+
| Essential complexity ratio | N of M flagged (%) | Higher = more domain-inherent |
224+
| Dominant complexity pattern | e.g. "sequential orchestration" | |
225+
226+
**Highest-ROI targets:** Functions with the most accidental complexity and
227+
simplest extraction boundaries.
228+
```
229+
230+
### Section 4: Essential Complexity Warnings
231+
232+
Functions that are complex but should NOT be simplified:
233+
234+
```
235+
## Essential Complexity -- Leave Alone
236+
237+
| Function | Location | Why Essential |
238+
|----------|----------|---------------|
239+
```
240+
241+
Close with: "Complex code takes 124% longer to resolve issues in (CodeScene, 39
242+
codebases). This is a cognitive load effect -- the cost is developer time, not
243+
production failures. Rust's compiler eliminates many defect classes."
244+
245+
---
246+
247+
## Supplementary Signals
248+
249+
When git history is available, use it to adjust ranking priority (not detection):
250+
251+
| Signal | Command | Effect |
252+
|--------|---------|--------|
253+
| Change frequency | `git log --oneline -- <file> \| wc -l` | High-churn functions ranked higher |
254+
| Author count | `git log --format=%aN -- <file> \| sort -u \| wc -l` | Many-author functions ranked higher |
255+
| Recency | `git log --since=90d -- <file>` | Recently changed functions ranked higher |
256+
257+
Process metrics outperform all static code metrics for defect prediction (Moser 2008).

0 commit comments

Comments
 (0)