Tech debt audit
Harness agnostic skill pack for AI coding agents that audits codebases for technical debt across ten categories
npx -y skills add jjw013/tech-debt-skill --skill tech-debt-auditAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Audits a codebase for technical debt across 10 categories (dependencies, documentation, bugs-and-logic, performance, security, test-coverage, dead-code, accessibility, todo-fixme, licensing) and produces a structured findings.md report. Use when a user wants a holistic debt assessment before deciding whether to file tickets or start fixing.
SKILL.md
13.8 KB, as published. Nobody here has run it
Tech Debt Audit
Overview
This skill audits a codebase for technical debt across ten categories and produces a single findings.md file conforming to the schema at templates/findings.schema.md. The file is the handoff artifact — downstream skills (tech-debt-tickets, tech-debt-fix) consume it deterministically.
The audit is read-only. It does not modify source files, install packages, or push anything anywhere. It may invoke audit-style tooling if permitted by the user (npm audit, pip-audit, dotnet list package --vulnerable, license-checker, etc.), but even those invocations are describe-then-ask, never silent.
The ten categories, each with its own checklist in references/:
dependencies— outdated, EOL, CVE-affected, unused packagesdocumentation— missing README, module docs, ADRs, stale commentsbugs-and-logic— null-handling, off-by-one, swallowed errors, race conditionsperformance— N+1, sync I/O on hot paths, memory leaks, unbounded loopssecurity— committed secrets, injection, auth gaps, misconfigurationtest-coverage— critical paths untested, missing edge cases, brittle testsdead-code— unused exports, unreachable branches, orphaned modulesaccessibility— WCAG violations (UI projects only)todo-fixme— stale / uncontextualized / high-risk inline markerslicensing— missing LICENSE, incompatible deps, attribution gaps
When to Use
Trigger on any of:
- User asks for a "tech debt audit", "debt review", or "debt assessment".
- User says something vague like "look at this codebase and tell me what's broken" and hasn't scoped to a specific bug.
- User has picked this skill explicitly from the
using-tech-debt-skillsrouter.
Do NOT use this skill when:
- The user has a specific bug they want fixed (use a debugging skill instead).
- The user wants a code review of a PR (use a code-review skill).
- The user wants fixes applied directly (this skill only audits; hand off to
tech-debt-fixafter).
Persona Adopted
This skill adopts the debt-evaluator persona defined at agents/debt-evaluator/SKILL.md. Read that file before proceeding.
If the harness supports sub-agents: delegate the audit work to a sub-agent prompted with the debt-evaluator persona. The parent agent composes the final findings.md and returns to the user.
If the harness does not support sub-agents: assume the debt-evaluator persona directly for the duration of the audit. Speak in its voice. Apply its Process Discipline rules.
Either way, the persona's rules are binding:
- Evidence over speculation — every finding cites a file/line/observation.
- Never fabricate.
- Redact secrets when encountered; never write them to
findings.md. - One pass per category before triage.
Process
1. Confirm scope with the user
Ask the user:
- Repo path — default is the current working directory. Confirm it's the intended audit target.
- Output path — default is
<repo>/findings.md. Confirm or take override. - Category scope — default is all 10 categories. User may exclude categories (e.g., "skip a11y, no UI"). Record exclusions for
categories_skipped. - Permission to invoke tooling — ask explicitly: "May I run audit-style commands (e.g.,
npm audit,dotnet list package --vulnerable,license-checker) if they're available? I will not install anything or modify source files." Wait for yes/no.
Record the answers; you'll need them for the top-level frontmatter.
2. Detect project type and ecosystems
Determine what this repo is so the right checklists apply:
- Language/ecosystem detection. Search for manifests:
package.json,*.csproj,pyproject.toml,requirements.txt,Cargo.toml,go.mod,Gemfile,composer.json,pom.xml,build.gradle,pubspec.yaml. Record every one found. - UI detection. Look for one of:
index.html, JSX/TSX files,.vue,.sveltefiles, React Native / Expo / Flutter manifests, WPF/WinUI/Electron evidence. If none found,accessibilitywill be skipped with reasonno UI detected in project. - Service type detection. Presence of HTTP frameworks (Express, Fastify, ASP.NET, FastAPI, Gin, Rails, etc.), queue consumers (BullMQ, Celery, Sidekiq), or CLIs (commander, click, cobra) informs which subsections of the performance/security/bugs checklists apply most.
- Project visibility. README and repo metadata indicate OSS vs. internal — affects documentation and licensing emphasis.
Record the determination in a working note; it becomes part of the audit_scope field and per-category categories_skipped reasons.
3. Load checklists on demand
For each category in scope, read the corresponding checklist from references/:
| Category | Checklist file |
|---|---|
| dependencies | references/dependencies-checklist.md |
| documentation | references/documentation-checklist.md |
| bugs-and-logic | references/bugs-and-logic-checklist.md |
| performance | references/performance-checklist.md |
| security | references/security-checklist.md |
| test-coverage | references/test-coverage-checklist.md |
| dead-code | references/dead-code-checklist.md |
| accessibility | references/accessibility-checklist.md |
| todo-fixme | references/todo-fixme-checklist.md |
| licensing | references/licensing-checklist.md |
Do not substitute your own mental model for the checklist content. If you think the checklist misses something important, file a normal finding and also note the gap in the audit notes — don't improvise a parallel category.
4. Run the categories
Recommended order (security first; it gates on secrets that must not leak elsewhere):
- security — especially the secrets sweep. If you find a committed
.envor equivalent, file that finding IMMEDIATELY with redacted evidence, before moving on. - dependencies
- licensing
- documentation
- bugs-and-logic
- performance
- test-coverage
- dead-code
- accessibility (if in scope)
- todo-fixme
For each category:
- Read the checklist in full. Apply only the subsections whose applicability section matches the detected project type.
- Inspect the relevant files. Read manifests in full; sample source files; search broadly using grep/ripgrep-class capabilities.
- If tooling is available AND permission was granted in step 1, describe what you're about to run, then run it, then capture output. If tooling is available but permission was denied, document what would have been run in the suggested fix of the relevant finding.
- For every concern that hits, draft a finding. Use the finding shape in the checklist's "What a Finding Looks Like" section and conform to the schema's finding fields.
Never mix categories mid-pass. Finish security before starting dependencies. The debt-evaluator persona's "one pass per category" rule prevents blind spots where emotional investment in one category eats the time for others.
5. Assign IDs and triage
Assign finding IDs sequentially from TD-001 across the entire audit (not per category). Do this after all findings are drafted, not as you go — you won't need to renumber if findings get combined or dropped.
Assign severity and effort per the checklist guidance + debt-evaluator values:
- Severity tracks concrete harm if unfixed.
- Effort tracks the fix — t-shirt size.
auto_fixable— check every criterion in schema §3. If any fails, setfalse. When in doubt,false.
6. Compose the top-level frontmatter
Fill in per schema §1:
schema_version: "1.0"project(basename of repo path)project_root(absolute)audit_date(today, ISO 8601)audit_scope(free-form; include project type, manifests scanned, any limits from step 1)audit_skill_version: "[email protected]"categories_covered— categories that produced findings OR that were checked with zero findings (both count).categories_skipped— categories you did not run, each with a reason string.summary— compute totals from the findings you composed. The math must check out (see schema §1 rules).notes— optional; use for audit-wide caveats (e.g., "tooling not invoked; CVE findings may undercount").
7. Write findings.md
Write the file to the output path from step 1.
Immediately self-validate against schema §4 rules 1–8. If any fail, fix the output before proceeding. Common failures:
total_findingsdoesn't match theTD-heading count.summary.by_severitysum doesn't equaltotal_findings.- A finding cites a
filethat can't be resolved relative toproject_root. - A YAML block is malformed (unquoted range like
line: 12-20instead ofline: "12-20"). - Secrets accidentally written inline.
8. Summarize for the user and offer the downstream fork
Print a short summary:
Audit complete. Wrote findings.md to <path>.
Project type: <type>
Total findings: <N>
By severity: critical=<n>, high=<n>, medium=<n>, low=<n>
By category: <cat>=<n>, <cat>=<n>, ...
Categories skipped: <cat> (<reason>), ...
Next step — pick one:
1. Write tickets for each finding → I'll invoke the tech-debt-tickets skill.
2. Start fixing → I'll invoke the tech-debt-fix skill.
3. Stop here. You review the file and come back later.
If any finding has severity critical, lead the summary with it:
⚠ 1 critical finding: TD-019 — .env file committed to repository. See findings.md for details and remediation (rotation required).
Wait for the user to choose. Do NOT auto-invoke either downstream skill.
Rationalizations
| Excuse | Rebuttal |
|---|---|
| "The user said 'audit fast', so I'll pick the top 3 categories." | "Fast" means fewer findings per category, not fewer categories. Skipping categories silently hides debt. Ask what to cut if the user insists on cutting. |
| "I found 200 TODOs. Filing 200 findings would drown the report." | Exactly. File one aggregate finding (scope: repository) with a count and the high-risk markers enumerated — see todo-fixme-checklist.md §6. |
| "Accessibility doesn't apply; I'll skip it silently." | Record it in categories_skipped with a reason. Silent skipping = the reader doesn't know the audit was incomplete. |
"I found the .env with API keys — let me just paste it into the finding so the user can see." | Never. Redact. Record file+line. The finding describes the leak, not the secret. |
| "This check is slow on a monorepo; I'll skip the workspace packages." | Surface it in categories_skipped notes, or widen audit_scope to say which packages were sampled vs. scanned exhaustively. |
| "I found a bug in the code while doing the dependencies pass, I'll file it under dependencies." | No — file it under bugs-and-logic where it belongs. Cross-category leakage pollutes the counts. |
| "The checklist's security section 7 (client-side) doesn't apply to this backend repo." | Correct — skip specific subsections whose applicability doesn't match. That's by design. |
| "Something looks off but I can't localize it." | Note it in audit notes as an unlocalized observation. Do not file a finding without a specific file/line. |
"The totals in summary don't quite add up, but the report is mostly right." | Fix them. Schema validation is non-negotiable; the handoff contract is how downstream skills work. |
Red Flags
Stop and reset if:
- You're composing a finding without a file path or concrete evidence line.
- You're in the middle of category 2 already thinking about how to write the category 5 section — you're losing focus on the current pass.
- You've silently skipped a category. Every skip needs a reason in
categories_skipped. - You're minimizing a security finding because "it's probably not exploitable." File it. Let severity reflect your assessment; don't suppress.
- You're starting to argue with the checklist. Either follow it or escalate the disagreement in audit
notes— don't rewrite the rules mid-audit. - Your
total_findingsdoesn't match the heading count, and you're tempted to "just fix the count". - You notice a secret and your first instinct is to mention it inline somewhere.
Verification
The skill is done when ALL of these are true:
-
findings.mdexists at the output path. - File opens with a valid YAML frontmatter block containing all required fields from schema §1.
-
schema_versionis exactly"1.0". -
audit_skill_versionis"[email protected]"or newer. -
categories_covered+categories_skippedcover ALL 10 categories with no overlap. - Every skipped category has a non-empty reason.
-
total_findingsequals the count of^## TD-headings. -
summary.by_severitytotals matchtotal_findings. -
summary.by_categorytotals matchtotal_findings. - Every finding has a valid YAML block with all required fields from schema §2.
- Every finding has the three required markdown sections (Description, Rationale, Suggested fix) in that order.
- No secrets appear anywhere in the file.
- Every
filein a finding resolves to a real file in the repo (unlessscope: repository). - Finding IDs are unique and sequential from
TD-001. - The user has been shown the summary with leading-critical-finding callout if applicable, and offered the three next-step options.
If any item fails, fix it before reporting the skill complete.
Version History
- 0.1 — Dependencies category only. Validated the schema contract.
- 1.0 (current) — All 10 categories. Category ordering prioritizes security first (secret sweep before anything else gets written). Full project-type detection for applicability gating.