Identifies recurring structural patterns in a codebase — idioms, copy-paste clones, homegrown abstractions — and characterizes each as a reusable template. Use when learning a codebase's conventions, when hunting for copy-paste that should be a function, or when documenting how this team does things.
80
100%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Every codebase has patterns — some intentional (house idioms), some accidental (copy-paste). Finding them tells you how code gets written here, and which duplication should be consolidated.
| Type | What it is | What to do with it |
|---|---|---|
| Idiom | The team's standard way of doing X | Document it. New code should follow it. |
| Clone | Copy-pasted code with minor tweaks | Extract to a function. → code-refactoring-assistant |
| Anti-pattern | A recurring mistake | Flag it. → code-smell-detector |
The same structural pattern can be any of the three — it depends on whether the repetition is good, accidental, or bad.
Exact-text clones are easy (rg + sort + uniq -c). Near-clones — same structure, different variable names — need normalization:
$1, $2, ...), normalize literals (42 → NUM, "foo" → STR).Original A: user = db.get(user_id); if user is None: raise NotFound("user")
Original B: order = db.get(order_id); if order is None: raise NotFound("order")
Normalized: $1 = db.get($2); if $1 is None: raise NotFound(STR)
$1 = db.get($2); if $1 is None: raise NotFound(STR)
→ Same hash. Clone pair found.Extractable as: def get_or_404(model, id, name): ...
Idioms are short (2–5 lines) and appear everywhere. Mine them by n-gram frequency on normalized AST nodes:
| Normalized n-gram | Count | Interpretation |
|---|---|---|
if $1 is None: return None | 89 | Null-propagation idiom — this codebase uses it heavily |
with self._lock: $BODY | 34 | Locking idiom — _lock is the house convention |
logger.info(f"{$1.__class__.__name__}: ...") | 27 | Logging idiom — always includes class name |
try: $X except Exception: pass | 11 | Anti-pattern — swallowing all exceptions |
The count tells you: high-count idioms are conventions to follow; high-count anti-patterns are systemic problems.
Observed in 23 places:
def get_foo(self, foo_id):
resp = self._client.get(f"/foos/{foo_id}")
resp.raise_for_status()
data = resp.json()
return Foo.from_dict(data)
def get_bar(self, bar_id):
resp = self._client.get(f"/bars/{bar_id}")
resp.raise_for_status()
data = resp.json()
return Bar.from_dict(data)
# ... ×21 morePattern template:
def get_$RESOURCE(self, ${RESOURCE}_id):
resp = self._client.get(f"/${RESOURCE}s/{${RESOURCE}_id}")
resp.raise_for_status()
return $MODEL.from_dict(resp.json())Parameters: $RESOURCE (string, e.g. foo), $MODEL (class, e.g. Foo).
Verdict: This is a clone, not an idiom. 23 copies of the same 4 lines with 2 parameters → extract:
def _get_resource(self, path: str, model: type[T]) -> T:
resp = self._client.get(path)
resp.raise_for_status()
return model.from_dict(resp.json())
def get_foo(self, foo_id): return self._get_resource(f"/foos/{foo_id}", Foo)23 × 4 lines → 23 × 1 line + 4 lines shared. And now error handling changes in one place.
| Signal | Points to idiom | Points to clone |
|---|---|---|
| Pattern length | Short (2–3 lines) | Long (5+ lines) |
| Parameter count | 0–1 | 2+ |
| Repetition within one file | Rare | Common |
| Language/framework requires this shape | Yes — it's idiom | No — it's duplication |
| Would extraction make callsites clearer? | No — idiom reads fine | Yes — callsite becomes a name |
with self._lock: (1 line, 0 params, language-required shape) → idiom.
The get_$RESOURCE block above (4 lines, 2 params, nothing requires this shape) → clone.
if x is None: return None appearing 89 times isn't duplication — it's an idiom, and extracting it to propagate_none(x) makes code less readable.if not user vs if user is None — different text, same pattern. Normalize aggressively.## Idioms (follow these)
| Pattern | Count | Example location |
| ------- | ----- | ---------------- |
## Clones (extract these)
### <pattern name>
Occurrences: <N>
Template:
<normalized pattern with $PARAMS>
Parameters: <list — what varies>
Proposed extraction:
<function signature + body>
Affected files: <list>
## Anti-patterns (fix these)
| Pattern | Count | Why bad | Locations |
| ------- | ----- | ------- | --------- |47d56bb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.