agents/claude.md
# Review Code Smells
Use these instructions when the task is mainly about identifying code smells, hidden complexity, or maintainability risks.
## Working Style
- Findings first, ordered by importance.
- Focus on smells that materially increase change cost or bug risk.
- Explain why the smell matters before suggesting cleanup.
- Prefer the smallest realistic remediation.
- Avoid nitpicking when larger structural issues exist.
## What To Optimize For
- Actionable findings
- Real maintenance impact
- Clear prioritization
- Remediation that is reviewable and proportional
## Load These References As Needed
- `skills/review-code-smells/SKILL.md` for the core workflow and guardrails
- `skills/review-code-smells/references/benchmark-harness.md` for a fair comparison workflow across agents
- `skills/review-code-smells/references/benchmark-starter-pack.md` for the fast comparison workflow across agents
- `skills/review-code-smells/references/benchmark-starter-prompts.md` for the first-pass smell-review benchmark set
- `skills/review-code-smells/references/smell-catalog.md` for common smell definitions
- `skills/review-code-smells/references/severity-guide.md` for prioritization guidance
- `skills/review-code-smells/references/review-checklist.md` for review questions
- `skills/review-code-smells/references/remediation-playbook.md` for practical fix patterns
- `skills/review-code-smells/references/eval-prompts.md` for evaluation prompts
- `skills/review-code-smells/references/evaluation-rubric.md` for output quality checks
- `skills/review-code-smells/references/go-guidance.md` for Go-oriented guidance
- `skills/review-code-smells/references/kotlin-guidance.md` for Kotlin-oriented guidance
## Stop Signals
- Do not overload the user with minor nits.
- Do not confuse style preferences with code smells.
- Do not suggest a rewrite when a local remediation is enough.
agents/openai.yaml
interface:
display_name: "Review Code Smells"
short_description: "Find maintainability risks that actually matter"
default_prompt: "Use $review-code-smells to review this code for the most important maintainability smells and suggest practical fixes."
references/benchmark-harness.md
# Benchmark Harness
Use this file when you want to compare how different agents behave with `review-code-smells`, especially Codex versus Claude Code.
## Goal
Measure whether the agent:
- surfaces the highest-value smells first
- explains why a smell matters
- prioritizes findings clearly
- avoids generic nitpicks
- recommends proportional remediation
## Inputs
- Prompt set: `references/eval-prompts.md`
- Starter prompt set: `references/benchmark-starter-prompts.md`
- Review rubric:
`finding_quality`, `risk_explanation`, `prioritization`, `remediation_practicality`
## Fair-Run Rules
- Use the same prompt text for each agent.
- Use the same codebase context, if any.
- Keep model settings as close as possible.
- Do not give one agent hidden hints the other does not receive.
## Script Workflow
Starter run:
```bash
python3 skills/review-code-smells/scripts/init_benchmark.py \
--prompt-file skills/review-code-smells/references/benchmark-starter-prompts.md \
--agents codex claude \
--output /tmp/smells-benchmark-starter.csv \
--run-label smells-starter
```
Full run:
```bash
python3 skills/review-code-smells/scripts/init_benchmark.py \
--agents codex claude \
--output /tmp/smells-benchmark-results.csv
```
After scoring the CSV manually, summarize it with:
```bash
python3 skills/review-code-smells/scripts/summarize_benchmark.py \
/tmp/smells-benchmark-results.csv
```
references/benchmark-starter-pack.md
# Benchmark Starter Pack
Use this file when you want the quickest meaningful comparison between Codex and Claude for code-smell review quality.
## Why These 6 Prompts
This starter set is intentionally balanced:
- Prompt 1 tests whether the agent surfaces the highest-value smells first.
- Prompt 2 tests whether the agent recognizes recurring change pain.
- Prompt 3 tests whether it can detect abstraction drift instead of praising indirection.
- Prompt 4 tests whether it identifies divergent change and mixed responsibilities.
- Prompt 5 tests whether it catches hidden side effects despite small function size.
- Prompt 6 tests whether it can distinguish between multiple likely smell classes and prioritize correctly.
## Recommended Use
Run this starter pack first when:
- you are validating a new installation of `review-code-smells`
- you are comparing Codex and Claude for review tasks for the first time
- you want a quick signal before expanding the smell-review benchmark
## Suggested Workflow
You can reuse the generic benchmark scripts from `apply-software-patterns`:
```bash
python3 skills/apply-software-patterns/scripts/init_benchmark.py \
--prompt-file skills/review-code-smells/references/benchmark-starter-prompts.md \
--agents codex claude \
--output /tmp/code-smells-benchmark-starter.csv \
--run-label smells-starter
```
After scoring the CSV manually, summarize it with:
```bash
python3 skills/apply-software-patterns/scripts/summarize_benchmark.py \
/tmp/code-smells-benchmark-starter.csv
```
references/benchmark-starter-prompts.md
# Benchmark Starter Prompts
Use this file for a fast first-pass benchmark before running a larger smell-review evaluation set.
This starter set intentionally samples:
- prioritization
- maintenance-risk explanation
- abstraction drift detection
- hidden side effects
- remediation practicality
## Starter Set
1. Review this service for the most important maintainability smells and order them by severity.
2. This handler works, but every new feature touches three branches and two helper files. What smell is most expensive here?
3. A refactor adds many wrappers and helper layers. Is this improved design or abstraction drift?
4. A class changes for logging rules, validation rules, and persistence changes. Which smell matters first?
5. A function looks short, but its side effects are hidden and order-dependent. How should that be reviewed?
6. Review this PR and tell me whether the biggest problem is readability, design drift, or duplicated business logic.
references/eval-prompts.md
# Eval Prompts
Use this file to test whether the smell-review skill finds high-value issues instead of generic nits.
1. Review this service for the most important maintainability smells and order them by severity.
2. This handler works, but every new feature touches three branches and two helper files. What smell is most expensive here?
3. A refactor adds many wrappers and helper layers. Is this improved design or abstraction drift?
4. A class changes for logging rules, validation rules, and persistence changes. Which smell matters first?
5. A function looks short, but its side effects are hidden and order-dependent. How should that be reviewed?
6. Review this PR and tell me whether the biggest problem is readability, design drift, or duplicated business logic.
references/evaluation-rubric.md
# Evaluation Rubric
Use this file to assess whether the smell review is strong enough before returning it.
Score each category from 0 to 2.
## 1. Finding Quality
- 0: Findings are generic or nitpicky.
- 1: At least one relevant smell is identified.
- 2: The review finds the highest-value smells first.
## 2. Risk Explanation
- 0: Does not explain why the smell matters.
- 1: Gives some rationale.
- 2: Connects the smell to concrete maintenance, readability, or bug risk.
## 3. Prioritization
- 0: Findings feel unordered.
- 1: Some prioritization is present.
- 2: Findings are clearly ordered by likely cost or impact.
## 4. Remediation Practicality
- 0: Recommends vague cleanup or broad rewrites.
- 1: Suggests some fixes.
- 2: Recommends realistic, reviewable next steps.
## Interpreting The Score
- 7-8: Strong output
- 5-6: Acceptable
- 0-4: Weak smell review
references/go-guidance.md
# Go Guidance
Use this file when reviewing Go code for smells.
- Watch for packages that mix transport, persistence, and business rules.
- Watch for error handling that buries the happy path.
- Watch for interfaces that exist only to satisfy tests.
- Prefer findings tied to package boundaries, traceability, and ownership.
references/kotlin-guidance.md
# Kotlin Guidance
Use this file when reviewing Kotlin code for smells.
- Watch for scope-function overuse that hides context.
- Watch for nested `if` and `when` flows that obscure the happy path.
- Watch for Android or framework concerns leaking into domain logic.
- Watch for extension functions scattering core business behavior across files.
references/remediation-playbook.md
# Remediation Playbook
Use this file when translating smells into practical next steps.
- For long functions: rename values, flatten the flow, then extract one responsibility at a time.
- For shotgun surgery: centralize one repeated decision or responsibility boundary.
- For feature envy: move the logic closer to the data it truly depends on.
- For primitive obsession: introduce one well-named type or helper where domain meaning is lost.
- For hidden side effects: make mutation and I/O explicit in names or boundaries.
- For abstraction drift: inline or remove one layer that adds no explanatory value.
Stop when comprehension materially improves. Do not keep refactoring just because more cleanup is possible.
references/review-checklist.md
# Review Checklist
Use this file when reviewing for code smells.
- What change would be hardest to make here and why?
- Are responsibilities mixed in a way that causes future churn?
- Is the main control flow easy to trace?
- Are there repeated concepts encoded in branching or flags?
- Are dependencies and side effects visible?
- Is abstraction clarifying behavior or hiding it?
- Which smell matters most if the team leaves this code untouched for three months?
references/severity-guide.md
# Severity Guide
Use this file to prioritize findings.
Prioritize higher when a smell:
- makes common changes risky
- increases bug surface area
- obscures ownership or intent
- repeats across multiple locations
- makes testing or debugging materially harder
Lower priority when the issue is mostly cosmetic or isolated and low-risk.
references/smell-catalog.md
# Smell Catalog
Use this file when reviewing code quality and maintainability.
- Long Function: too many concerns mixed into one flow.
- Large Class or Module: too many responsibilities owned together.
- Shotgun Surgery: one change requires touching many places.
- Divergent Change: one unit changes for many unrelated reasons.
- Feature Envy: logic depends more on another object's data than its own.
- Primitive Obsession: domain meaning hidden behind raw strings, ints, maps, or flags.
- Repeated Branching: the same concept encoded in conditionals across many places.
- Temporal Coupling: methods or steps must occur in the right order, but the contract is implicit.
- Hidden Side Effects: functions mutate or perform I/O unexpectedly.
- Comment Compensation: comments explain what clearer code should express directly.
- Abstraction Drift: wrappers, helpers, or interfaces make behavior harder to trace.
scripts/init_benchmark.py
#!/usr/bin/env python3
"""Create a benchmark score sheet from a code-smells prompt-pack markdown file."""
from __future__ import annotations
import argparse
import csv
import re
from pathlib import Path
PROMPT_LINE_RE = re.compile(r"^(\d+)\.\s+(.*)$")
def parse_eval_prompts(path: Path) -> list[dict[str, str]]:
prompts: list[dict[str, str]] = []
category = ""
for raw_line in path.read_text(encoding="utf-8").splitlines():
line = raw_line.strip()
if line.startswith("## "):
category = line[3:].strip()
continue
match = PROMPT_LINE_RE.match(line)
if match:
prompts.append(
{
"prompt_id": match.group(1),
"category": category or "Uncategorized",
"prompt": match.group(2).strip(),
}
)
if not prompts:
raise ValueError(f"No prompts found in {path}")
return prompts
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--eval-prompts",
default="skills/review-code-smells/references/eval-prompts.md",
help="Deprecated alias for --prompt-file",
)
parser.add_argument("--prompt-file", default="", help="Path to the benchmark prompt markdown file")
parser.add_argument("--agents", nargs="+", required=True, help="Agent labels to include")
parser.add_argument("--output", required=True, help="Output CSV path")
parser.add_argument("--run-label", default="baseline", help="Benchmark run label")
args = parser.parse_args()
prompt_file = args.prompt_file or args.eval_prompts
prompts = parse_eval_prompts(Path(prompt_file))
output_path = Path(args.output)
output_path.parent.mkdir(parents=True, exist_ok=True)
fieldnames = [
"run_label",
"agent",
"prompt_id",
"category",
"prompt",
"finding_quality",
"risk_explanation",
"prioritization",
"remediation_practicality",
"total",
"verdict",
"notes",
]
with output_path.open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=fieldnames)
writer.writeheader()
for agent in args.agents:
for prompt in prompts:
writer.writerow(
{
"run_label": args.run_label,
"agent": agent,
"prompt_id": prompt["prompt_id"],
"category": prompt["category"],
"prompt": prompt["prompt"],
"finding_quality": "",
"risk_explanation": "",
"prioritization": "",
"remediation_practicality": "",
"total": "",
"verdict": "",
"notes": "",
}
)
print(
f"Wrote {len(prompts) * len(args.agents)} rows to {output_path} "
f"from {prompt_file}"
)
return 0
if __name__ == "__main__":
raise SystemExit(main())
scripts/summarize_benchmark.py
#!/usr/bin/env python3
"""Summarize a benchmark CSV created from the code-smells eval prompts."""
from __future__ import annotations
import argparse
import csv
from collections import defaultdict
from pathlib import Path
SCORE_COLUMNS = [
"finding_quality",
"risk_explanation",
"prioritization",
"remediation_practicality",
]
def parse_score(value: str) -> int:
value = value.strip()
if value == "":
return 0
score = int(value)
if score < 0 or score > 2:
raise ValueError(f"Score must be between 0 and 2, got {score}")
return score
def is_scored(row: dict[str, str]) -> bool:
return any(row[column].strip() != "" for column in SCORE_COLUMNS)
def average(values: list[float]) -> float:
return sum(values) / len(values) if values else 0.0
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("csv_path", help="Benchmark CSV path")
args = parser.parse_args()
csv_path = Path(args.csv_path)
rows = list(csv.DictReader(csv_path.open(encoding="utf-8")))
if not rows:
raise ValueError(f"No rows found in {csv_path}")
by_agent: dict[str, list[int]] = defaultdict(list)
by_agent_category: dict[tuple[str, str], list[int]] = defaultdict(list)
low_rows: list[tuple[int, str, str, str]] = []
unscored_rows = 0
for row in rows:
if not is_scored(row):
unscored_rows += 1
continue
total = sum(parse_score(row[column]) for column in SCORE_COLUMNS)
agent = row["agent"]
category = row["category"]
prompt_id = row["prompt_id"]
prompt = row["prompt"]
by_agent[agent].append(total)
by_agent_category[(agent, category)].append(total)
if total <= 4:
low_rows.append((total, agent, prompt_id, prompt))
print(f"Benchmark summary for {csv_path}")
print(f"Scored rows: {sum(len(scores) for scores in by_agent.values())}")
print(f"Unscored rows: {unscored_rows}")
if not by_agent:
print("")
print("No scored rows found yet. Fill the rubric columns in the CSV, then rerun the summary.")
return 0
print("")
print("Per-agent averages")
for agent in sorted(by_agent):
print(f"- {agent}: avg={average(by_agent[agent]):.2f} prompts={len(by_agent[agent])}")
print("")
print("Per-agent category averages")
for agent, category in sorted(by_agent_category):
scores = by_agent_category[(agent, category)]
print(f"- {agent} | {category}: avg={average(scores):.2f} prompts={len(scores)}")
print("")
print("Lowest-scoring rows")
for total, agent, prompt_id, prompt in sorted(low_rows)[:10]:
print(f"- {agent} prompt {prompt_id}: total={total} | {prompt}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
SKILL.md
---
name: review-code-smells
description: Review code for maintainability smells, readability risks, hidden complexity, and design drift, then explain the most important findings with practical remediation guidance. Use when Codex needs to identify code smells, review technical debt, prioritize cleanup, explain why code feels hard to change, or suggest targeted refactors without unnecessary rewrites.
---
# Review Code Smells
## Overview
Use this skill to review code with a maintainability-first lens. The goal is to identify the smells that matter, explain why they matter, and recommend the smallest effective remediation.
Prefer concrete findings over generic advice. A good smell review helps a teammate understand what is wrong, why it is risky, and what to change first.
## When To Use This Skill
Use this skill when the task involves any of the following:
- Reviewing code quality or technical debt
- Explaining why code feels hard to change
- Prioritizing cleanup opportunities
- Identifying maintainability, readability, or design smells
- Reviewing a PR for hidden complexity or code health regressions
Do not use this skill as a substitute for architecture design or detailed pattern selection. It is a review and prioritization skill first.
## Workflow
### 1. Find The Most Expensive Smells
Look for issues that create real maintenance cost, such as:
- Long functions with mixed responsibilities
- Repeated branching around the same concept
- Primitive obsession and vague data shaping
- Feature envy or logic living far from the data it depends on
- Shotgun surgery risk when one change touches many files
- Divergent change where one unit changes for many unrelated reasons
- Hidden side effects or temporal coupling
- Comments compensating for unclear code
- Over-abstraction that makes tracing behavior harder
Prioritize smells by likely maintenance pain, not by textbook neatness.
### 2. Explain The Risk Clearly
For each important smell, explain:
- what it is
- where it appears
- why it increases change cost, bug risk, or confusion
- what smaller change would reduce the risk
### 3. Prefer Reviewable Remediation
Recommend fixes in this order:
1. naming and structure cleanup
2. local extraction or simplification
3. responsibility separation
4. boundary refactor only if local fixes are not enough
Avoid broad rewrites unless the user explicitly wants one.
### 4. Keep Findings Actionable
Strong findings are:
- specific
- tied to actual code behavior
- ordered by severity or change cost
- paired with a realistic next step
Weak findings are:
- generic style complaints
- rules without context
- cleanup advice that costs more than the smell
## Output Contract
For review tasks, present:
1. Findings first, ordered by severity
2. Why each finding matters
3. Suggested remediation direction
4. Open questions or assumptions
5. Residual risks or testing gaps
If no significant smells are present, say so explicitly and mention any smaller risks that remain.
## Quality Bar
The response should usually satisfy all of the following:
- focuses on the highest-value smells first
- explains real maintenance or readability risk
- avoids generic rule recitation
- recommends the smallest helpful remediation
- keeps findings concrete enough to act on
## Reference Guide
Read only the files that match the current task:
- `agents/claude.md`: Claude Code adapter memory for using this package through `CLAUDE.md`
- `references/benchmark-harness.md`: workflow for benchmarking Codex versus Claude against this skill package
- `references/benchmark-starter-pack.md`: recommended first benchmark pack for quick smell-review comparisons
- `references/benchmark-starter-prompts.md`: small benchmark prompt pack for fast first-pass evaluation
- `references/smell-catalog.md`: common code smells and why they matter
- `references/severity-guide.md`: how to prioritize findings by likely cost and risk
- `references/review-checklist.md`: concise smell-review checklist
- `references/remediation-playbook.md`: practical fix patterns and when to stop
- `references/eval-prompts.md`: evaluation prompts to test smell-review quality
- `references/evaluation-rubric.md`: scoring rubric for whether the smell review is actually useful
- `references/go-guidance.md`: Go-oriented smell review notes
- `references/kotlin-guidance.md`: Kotlin-oriented smell review notes
Scripts are available for benchmark setup and summary:
- `scripts/init_benchmark.py`: generates a blank benchmark score sheet from the smell-review prompt packs
- `scripts/summarize_benchmark.py`: summarizes scored benchmark CSV files by agent and category
Do not read every reference file by default. Load only what the task needs.
## Guardrails
- Do not flood the user with low-value nits when bigger smells exist
- Do not call something a smell without explaining the maintenance cost
- Do not recommend rewrites when local cleanup would do
- Do not confuse style preferences with meaningful findings
- Do not ignore readability and traceability when code is technically correct
The goal is to help teams see and fix the smells that actually slow them down.