# Tech Debt Management

> Inventory and prioritize technical debt — TODO/FIXME/HACK, any usage, deprecated APIs, untested logic — with impact × effort matrix. Use at quarter start, before a refactoring sprint, when a new teammate joins, or when feature velocity slows. Not for actually paying down debt (use code-refactoring) or recording a migration approach (use decision-records) — this only inventories and prioritizes.

- Skill: `jaykim88/tech-debt-management` (Agent Skill)
- Install (CLI): `npx skillmds@latest add jaykim88/tech-debt-management`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jaykim88/tech-debt-management/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- License: MIT
- Author: JayKim88 (https://skillmd.com/u/jaykim88)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/jaykim88/tech-debt-management

---


# Tech Debt Management

## Purpose
Make hidden tech debt visible so it can be prioritized and repaid. Untracked debt compounds silently; tracked debt is just a backlog item.

**Universal** — the inventory + impact×effort + sprint-budget pattern applies to any codebase; tool names (grep patterns, deprecated APIs) vary by stack.

## Procedure

1. **Inventory comment-flagged debt**
   - Find all in-code debt markers (TODO / FIXME / HACK / XXX)
   - Classify each: still relevant? actionable? stale?
   - Classify the *kind* (Fowler's quadrant): deliberate vs inadvertent × prudent vs reckless — a prudent-deliberate shortcut ("ship now, refactor post-launch") is a tracked loan; reckless/inadvertent debt signals a process or knowledge gap to address differently
   - Delete stale ones; categorize the rest into the debt registry
   - Going forward, require attributable markers — `// TODO(owner, TICKET-123): ...` (a lint rule can forbid bare TODOs) so debt links to the tracker

2. **Inventory type-system escape hatches**
   - Locate all type bypasses (TS `any`/`as any`, Python `# type: ignore`, etc.)
   - For each: justified (with comment) or accidental?
   - Prioritize removal of unjustified escapes in hot paths

3. **Inventory deprecated dependencies and APIs**
   - Major-version migrations pending (framework, libraries)
   - Replacements for unmaintained deps
   - Legacy patterns (deprecated lifecycle hooks, removed APIs)
   - Check package-manager `outdated` report

4. **Identify untested business logic**
   - Coverage report → list files/branches with 0% coverage
   - Cross-reference with business-criticality (auth, payment, data integrity = high risk)
   - Untested + critical = top of repayment list

5. **Score each debt item: Impact × Effort**

   | | Low effort | High effort |
   |---|---|---|
   | **High impact** | 🟢 Do now | 🟡 Plan a project |
   | **Low impact** | 🔵 Backlog | 🔴 Delete from list |

   - Impact = user-facing risk, dev velocity drag, or **compounding** cost (favor debt that slows *every* future change over one-time costs)
   - Effort = engineer-hours
   - **Weight Impact by change frequency** (git churn): debt in a file touched weekly costs far more than debt in code untouched for a year — a hotspot is high churn × high complexity (`git log` churn, CodeScene)
   - Debt that has *already caused* an incident or bug is proven high-impact — mine the bug tracker

6. **Document in `TECH-DEBT.md`** (or `docs/exec-plans/tech-debt-tracker.md` if using craft-kit conventions)
   - One section per item: description, location, impact, effort, status (open / scheduled / done)
   - Sort by Impact × Effort (top of doc = highest leverage)
   - ⚠ A standalone debt doc rots — nobody opens it. Use it for *triage*, but **promote scheduled high-impact items into the real backlog / issue tracker** (linked) so debt competes with features in planning, not in a doc no one reads

7. **Allocate 15-20% sprint capacity to debt**
   - Otherwise it never gets paid
   - Beyond the budget, repay **opportunistically**: when you touch a file for a feature, clean the debt you encounter there (boy-scout rule). Don't proactively repay debt in stable, rarely-touched code that works — repay what's *in your path* or actively slowing you
   - Track Technical Debt Ratio (TDR) as a leadership-facing metric — common formula: `TDR = (fix-cost) / (build-cost from scratch)`
   - [OPINION] The exact TDR formula varies across sources (SQALE, CAST Software, internal company definitions). Treat as an industry-common heuristic, not a standard. Use whatever formulation is meaningful in your org and document it.
   - **Translate friction to annualized hours** for leadership: "10 min/day workaround = ~40 hrs/year per dev" — this framing converts soft "annoyance" into hard cost

8. **Schedule quarterly review**
   - Re-score items (effort estimates often change as code evolves)
   - Move stale items to "won't fix" with reason
   - Promote new items spotted during normal work

## Completion Criteria
- [ ] `TECH-DEBT.md` lists every known debt item with impact × effort score (Impact weighted by change frequency)
- [ ] Top 5 high-impact items have a scheduled repayment plan AND are promoted to the real backlog/tracker
- [ ] Stale TODO/FIXME deleted or reclassified; remaining TODOs are attributable (owner + ticket)
- [ ] Quarterly review on the calendar

## Stop & Ask (AI must pause for user approval)

- **Before deleting any TODO/FIXME comment** — even if it looks stale; the author may have context AI doesn't
- **Before re-categorizing an item from "open" to "won't fix"** — explicit team decision required
- **Before bulk-removing `any` types** — some may be intentional pending downstream library types

## Output
- **Registry**: `TECH-DEBT.md` (or `docs/exec-plans/tech-debt-tracker.md` if using craft-kit conventions) with table:
  - Item / Location / Impact (1-5) / Effort (S/M/L) / Status / Owner
- **Impact × Effort matrix**: visual 2x2 in the same file
- **Quarterly review entry**: dated subsection listing re-scored items + new items + closed items
- **Annualized friction memo** (for leadership): one-pager summarizing top 5 items as hours/year lost

## Implementation

### React + Next.js (default)
- Comment grep: `grep -rEn 'TODO|FIXME|HACK|XXX' src/`
- TS `any` grep: `grep -rEn ': any($|[^a-zA-Z])|as any' src/`
- Common deprecated patterns: Pages Router → App Router, `moment` → `date-fns`/`dayjs`, class components → hooks, `componentDidMount` → `useEffect`
- Dep status: `npm outdated` or `pnpm outdated`
- Coverage: `vitest run --coverage`

### Other stacks
- **Vue / Nuxt**: same grep; deprecated: Options API → Composition API for new code; Vue 2 → Vue 3 migrations
- **SvelteKit**: same grep; deprecated: Svelte 4 reactivity → Svelte 5 runes
- **Angular**: same grep; deprecated: `NgModule` → standalone components; `@Input()` → `input()` signal
- **Generic**: the universal procedure stands alone — only the language-specific grep patterns and dep-management commands change

## Related skills
- `code-refactoring` — most debt is paid down through refactoring passes
- `decision-records` — large debt items deserve an ADR for the migration approach

## Reference
- **Key insight encoded**: Reserve 15-20% sprint capacity for debt as a budget item, not a "when we have time" hope. Use Technical Debt Ratio (TDR = fix-cost / build-cost) as the leadership-facing metric — it shows that debt compounds. Triage with impact × effort matrix **weighted by change frequency** (debt in hot files costs most) and start with low-effort/high-impact wins to build trust. Two senior judgments: repay debt that's *in your path* (boy-scout rule) rather than proactively cleaning stable code that works, and promote scheduled items into the real backlog — a standalone debt doc nobody opens just rots.
- **Caveat**: This is the weakest-referenced skill in the toolkit — open-source standards in this space are thinner than in technical domains. Cite both sources and treat as an evolving practice.

