Audit the codebase for maintainability, the ISO/IEC 25010 characteristic covering modularity, reusability, analyzability, modifiability, and testability. Computes architectural metrics (coupling, fan-out, circular dependencies, layering violations, God modules) that the find-* family does not cover, and aggregates find-* results into a single maintainability scorecard. Use when the user says /audit-maintainability, "coupling analysis", "circular dependencies", "layering violations", "modulari...
Pro shows the line behind each finding and how to fix it
Scanned 10/6/2026
npx -y skills add tomzx/agents --skill audit-maintainability --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Audit Maintainability?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/tomzx-audit-maintainability)More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.
---
name: audit-maintainability
description: Audit the codebase for maintainability, the ISO/IEC 25010 characteristic covering modularity, reusability, analyzability, modifiability, and testability. Computes architectural metrics (coupling, fan-out, circular dependencies, layering violations, God modules) that the find-* family does not cover, and aggregates find-* results into a single maintainability scorecard. Use when the user says /audit-maintainability, "coupling analysis", "circular dependencies", "layering violations", "modularity audit", or runs a 25010 sweep via /audit-sdlc. Read-only; produces a scorecard and findings report.
argument-hint: "[--severity critical|high|medium|low] [--path <dir>]"
allowed-tools: Bash, Read, Glob, Grep
---
TODAY=!`date +%Y-%m-%d`
# Maintainability Audit (ISO/IEC 25010)
Audits the codebase for **maintainability**: how easily it can be modified to fix bugs, improve performance, or adapt to a changed environment. It computes the **architectural** maintainability metrics that per-function scanners miss, then combines the `find-*` family's output into one maintainability scorecard.
This is the **Maintainability** characteristic of the [ISO/IEC 25010](https://en.wikipedia.org/wiki/ISO/IEC_25010) quality model.
## What This Skill Adds Beyond the find-* Family
The `find-*` skills are per-function or per-file scanners (complexity, coverage, dead code, duplication, types). They cannot see **structure**: which module depends on which, whether layers are respected, whether cycles exist, whether one module is a God object. This skill computes those structural metrics and combines everything into one view.
| Source | What it provides here |
|---|---|
| `find-complexity-hotspots` | Modifiability: high cyclomatic complexity |
| `find-coverage-gaps` | Testability: untested code |
| `find-dead-code` | Reusability/analyzability: code that should be removed |
| `find-code-duplication` | Reusability: copy-paste to consolidate |
| `find-type-gaps` | Analyzability/modifiability: missing types |
| **This skill (unique)** | Modularity: coupling (fan-out), cohesion, circular dependencies, layering violations, God modules |
## Prerequisites
- Working directory is the root of the repository
- Read `.sdlc/context/architecture.md` if present (declares intended layering rules this audit checks against)
- `find-*` skills available (invoked as read-only scanners)
## What This Checks
| Sub-characteristic | Metric | How computed |
|---|---|---|
| Modularity | coupling / fan-out | count of distinct modules each module imports |
| Modularity | circular dependencies | import graph cycle detection |
| Modularity | layering violations | actual imports vs declared layers in `architecture.md` |
| Modularity | God modules | modules with LOC or import-count far above the median |
| Cohesion | mixed-concern modules | modules whose public functions span unrelated responsibilities (heuristic: divergent import sets) |
| Reusability | duplication | delegates to `find-code-duplication` |
| Analyzability | missing docs/types | delegates to `find-documentation-gaps`, `find-type-gaps` |
| Modifiability | complexity | delegates to `find-complexity-hotspots` |
| Testability | coverage gaps | delegates to `find-coverage-gaps` |
## Steps
### 1. Build the import graph
For the primary language, collect module-level imports to build a directed graph (module → imported module).
```
rg -n "^import |^from .* import |^const .* = require\(|^import .* from " -g '*.{py,ts,js,go}' .
```
Keep imports that resolve to internal modules (drop stdlib and third-party).
### 2. Coupling (fan-out)
For each module, count distinct internal modules it imports. Modules above the 90th percentile (or a fixed threshold like 20) are high-coupling findings. God modules = high fan-out AND high LOC.
```
wc -l $(find . -name "*.py" -not -path "*/test*" -not -path "*/.venv/*") | sort -rn | head -20
```
### 3. Circular dependencies
Detect cycles in the internal import graph. A cycle means a change in any member can affect all members. Report the smallest cycles first (easiest to break).
For Python, a quick check:
```
rg -n "^from \." -g '*.py' . | sort
```
Then trace relative-import chains for cycles. For JS/TS, map `import ... from "./..."` chains. Flag any cycle found.
### 4. Layering violations
If `.sdlc/context/architecture.md` declares layers (e.g., `api → service → repository`, or "UI must not import DB"), check actual imports against the rules. Every import that crosses a forbidden direction is a finding.
```
rg -n "import" -g '*.py' . | rg "api.*model|model.*api|ui.*db|db.*ui"
```
If no layering rules are declared, skip this step and recommend documenting them in `architecture.md`.
### 5. Delegate to find-* scanners
Invoke these read-only and collect their top findings as the per-characteristic detail:
- `/find-complexity-hotspots` (modifiability)
- `/find-coverage-gaps` (testability)
- `/find-dead-code` (reusability/analyzability)
- `/find-code-duplication` (reusability)
- `/find-type-gaps` (analyzability) — Python/TS/JS only
- `/find-documentation-gaps` (analyzability)
Skip any whose preconditions are not met.
### 6. Compute the maintainability scorecard
Combine these into a per-module and project-level score. Keep the formula simple and transparent:
```
maintainability_score = 100
- (coupling findings × weight_c)
- (cycles × weight_cycle)
- (layering violations × weight_layer)
- (complexity hotspots × weight_complex)
- (coverage gap weight)
- (duplication weight)
clamp to [0, 100]
```
Weights are illustrative; record the weights used in the report so the score is reproducible.
### 7. Confirm the decisive findings
Pick the critical or high findings that decide the report. Run the one or two you can: write a scratch script or test under `/tmp` that calls the code, run it, and paste the output, reaching `L3 - Executed` (see [`../sdlc/references/evidence.md`](../sdlc/references/evidence.md)). Never write scratch files into the repository; this audit is read-only and leaves no artifacts behind. Label every other finding with its level and pointer: `L1 - Cited` for a `file:line`, or `L2 - Ruled out` for a walked failure path. When a decisive finding cannot be executed, mark it `unproven` and state what runtime evidence it needed and why that was infeasible.
### 8. Report
Print the scorecard and findings. Do not modify files.
## Severity
| Severity | Criteria |
|---|---|
| Critical | Circular dependency on a core module; layering violation bypassing a security/correctness boundary |
| High | God module (>5x median LOC or fan-out); a layer consistently violated across a subsystem |
| Medium | High-coupling module; significant duplication not yet consolidated |
| Low | Missing types/docs; isolated complexity hotspot |
## Output Format
```
# Maintainability Audit — {TODAY}
## Scorecard
- Project maintainability score: NN/100 (weights: ...)
- Per-characteristic:
- Modularity: N coupling findings, N cycles, N layering violations
- Reusability: N duplication blocks (from find-code-duplication)
- Analyzability: N undocumented APIs, N missing types
- Modifiability: N complexity hotspots
- Testability: N coverage gaps
## Modularity (unique to this audit)
### High-coupling / God modules
| Module | Fan-out | LOC | Severity | Evidence |
|---|---|---|---|---|
### Circular dependencies
| Cycle | Members | Severity | Evidence |
|---|---|---|---|
### Layering violations
| From | To | Declared rule | Severity | Evidence |
|---|---|---|---|---|
## Aggregated from find-*
### Modifiability (find-complexity-hotspots)
| File:line | CC | Severity | Evidence |
|---|---|---|---|
### Testability (find-coverage-gaps)
| File | Coverage | Severity | Evidence |
|---|---|---|---|
### Reusability (find-code-duplication / find-dead-code)
| Location | Finding | Severity | Evidence |
|---|---|---|---|
### Analyzability (find-type-gaps / find-documentation-gaps)
| Location | Finding | Severity | Evidence |
|---|---|---|---|
```
## Example Usage
**Scenario 1: 25010 sweep**
```
/audit-sdlc maintainability
```
**Scenario 2: Structural only (skip find-* aggregation)**
```
/audit-maintainability --path src
```
Focuses on coupling, cycles, and layering.
**Scenario 3: Before a big refactor**
```
/audit-maintainability
```
Identifies the God modules and cycles that should be the refactor targets.
## Relationship to Other Skills
| Skill | Relationship |
|---|---|
| `audit-security`, `audit-functional-suitability`, `audit-performance-efficiency`, `audit-compatibility`, `audit-usability`, `audit-reliability`, `audit-portability` | The other seven ISO/IEC 25010 characteristics. Compose via `/audit-sdlc`. |
| `audit-sdlc` | Coordinator. The `maintainability` scope runs this skill. |
| `find-complexity-hotspots`, `find-coverage-gaps`, `find-dead-code`, `find-code-duplication`, `find-type-gaps`, `find-documentation-gaps` | Per-function scanners aggregated here. |
| `improve-codebase` | Acts on the safe subset of what this (and find-*) reports. |
## Useful Commands Reference
| Command | Description |
|---|---|
| `rg -n "^import \|^from .* import " -g '*.py' .` | Build the Python import graph |
| `rg -n "^import .* from " -g '*.{ts,js}' .` | Build the JS/TS import graph |
| `wc -l $(find . -name "*.py") \| sort -rn \| head` | LOC by file (God module detection) |
| `rg -n "^from \." -g '*.py' . \| sort` | Relative imports (cycle seed) |
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!