audit-debt
Audits technical debt in a repository or directory: where complexity concentrates, which functions exceed structural thresholds, and where code is duplicated. Use when the operator asks for a tech-deb
SKILL.mdplugin/skills/audit-debt/SKILL.md
GitHubAudit Debt
This skill audits the code health of a repository or a directory with the act-lite MCP tools. It ranks the files where complexity concentrates, lists the structural problems in those files, and shows the largest duplicated code. It ends in a report and never edits a file.
Adapt
An operator instruction wins over every default below: the scope, the number of files to detail, whether tests are audited.
The tools are the act-lite MCP server's. The same results come from the
act-lite analyze command (act-lite analyze hotspots …), so a session
without the MCP server runs the commands instead.
Inputs
paths: the files or directories to audit, relative to the workspace root. Default:[], the whole workspace.top: the number of hotspot files to detail, 1 to 1000. Default: 10.include_tests:false, unless the operator asks to audit tests too. Pass it to every call only then.
Procedure
Where to start. Call
analyze_hotspotswithpathsandlimit=top. Its findings are the top files, highest score first.- If it returns no file (
findingsis[]), no analyzed file has a function: skip step 3, and say so in the report.
- If it returns no file (
Counts for the whole scope. Call
analyze_patternswithpathsandlimit= 0. Itstotalanddetails.counts_by_rulegive the findings per rule in the whole scope; it returns no finding.Structural problems in the top files. Call
analyze_patternswithpaths= thefileof each step-1 finding andlimit= 1000.- If the result has
truncated: true, the report shows the first 1000 findings and says how many oftotalare not shown.
- If the result has
Largest duplicates. Call
analyze_cloneswithpathsandlimit=- Its findings are the largest clone classes first.
4a. Dependency cycles. Call analyze_cycles with paths and limit =
20. Its findings are the largest cycles first.
4b. Most coupled files. Call analyze_coupling with paths and limit =
top. Its findings are the most connected files.
- Pass
include_teststo both calls only when the operator asks to audit tests too.
Empty scope. If a call returns the error that starts with
no files to analyze in the requested scope, quote the message in the report's Coverage and limits section, and still run the other steps.Report. Write the report below from the four results: their findings,
total,truncated,status,complete,coverage,excluded,incompleteanddetails. Write nothing else, and change no file.
Report
## Technical debt audit: <scope>
Summary: <analyzed_files> files analyzed; supported and unsupported languages; each call's status and completeness;
findings by rule (<counts_by_rule>); <total> clone classes.
### Where to start
| Rank | File | Score | Functions | Top function (complexity × lines) |
Ranking: <details.formula>.
### Structural problems in the top files
| Location | Function | Rule | Value | Threshold |
### Largest duplicates
- <kind> clone, <tokens> tokens, <members_total> members: …
### Dependency cycles
<total> cycles over <cyclic_files> files.
- <members_total> files, <edges_total> edges: <path as <file> → <to> → …>[ (path of <path_total> steps, <n> shown)]; members: <file>, …[ (members not all shown)]
### Most coupled files
| File | Fan-in | Fan-out | Instability | Unresolved |
Instability = fan_out / (fan_in + fan_out). Fan-in counts only files in <scope>.
### Coverage and limits
Unsupported languages and rules (<not_applicable>), exclusions, skipped files, parse failures, regions not analyzed (<file>:<range>: <reason>), truncation.
A clone class shows that code has the same syntax tree, apart from formatting, comments and, for renamed clones, identifier names and literal values. It does not show that the members behave the same, that they can share one function, or that extracting them is safe.
<scope>: thepaths, or "the workspace" for[].- Summary:
coverage.analyzed_filesof the hotspots result; thecoverage.languagesentries, supported and not; for each call,statusandcomplete;details.counts_by_ruleandtotalfrom step 2; the clones result'stotal. - Where to start: one row per step-1 finding, in result order. Rank is
1, 2, …; File, Score and Functions are
file,scoreandfunctions; Top function is the first oftop_functions: itsfunction(or(anonymous)fornull) at itsrange, with itscomplexity×lines. Then thedetails.formulaline. With no file, write "No analyzed file has a function." - Structural problems: one row per step-3 finding, in result order.
Location is
<file>:<range>; Function isfunction, or(anonymous); Rule, Value and Threshold arerule,valueandthreshold. With no finding, write "None in the top files." - Largest duplicates: one line per step-4 finding, in result order,
with its
members(each<file>:<range>); whenmembers_totalis more than the members listed, add "and <n> more". With no class, write "No clone class." - Coverage and limits: the
coverage.languagesentries withsupported: false;details.not_applicableof the patterns results; theexcluded.counts; theincomplete.skipped_filesandincomplete.parse_failures; thedetails.regions_not_analyzedentries of theanalyze_hotspots,analyze_patternsandanalyze_clonesresults, each entry (file,range,reason) once, and eachdetails.regions_not_analyzed_totalthat is more than the entries listed; any empty-scope message from step 5; each truncation (totalagainst what is shown); then the sentence above. A result withcomplete: falsecan miss findings in that evidence; say so. In component files (.vue,.svelte,.astro), only script regions are analyzed: the template and style regions are not, so no finding comes from them. - Dependency cycles:
totalanddetails.cyclic_filesof the step-4a result, then one line per finding, in result order:members_totalandedges_total; thepathsteps, from the cycle'sfileback to it, written as<file> → <to>steps (the first step'sfile, then each step'sto), with "(path of <path_total> steps, <n> shown)" whenpath_totalis more than the <n> steps shown; and themembers, listed separately, with "(members not all shown)" whenmembers_totalis more than the members listed. Themembersare sorted by path, not in traversal order: never write them as a path. With no cycle, write "No cycle." - Most coupled files: one row per step-4b finding, in result order: File,
Fan-in, Fan-out, Instability and Unresolved are
file,fan_in,fan_out,instabilityandunresolved. Then the formula line and the fan-in scope line, word for word, with<scope>as in the heading. With no file, write "No file with a relationship." - Dependency limits: add to the Coverage and limits section, from the
analyze_cyclesandanalyze_couplingresults: thecoverage.languagesentries withsupported: false; thedetails.relationshipscounts (total,resolved,external,unresolved); the relevantincomplete.counts.unresolvedand the first entries ofincomplete.unresolved(file,kind,target,reason), with a note that an unresolved relationship can hide a cycle or a dependency; eachlimits_hitentry; theexcluded.counts,incomplete.skipped_filesandincomplete.parse_failures; and each truncation (totalagainst what is shown). A result withcomplete: falsecan miss cycles or dependencies; say so.