When to use
When planning maintenance work, justifying refactor time to stakeholders, or auditing a codebase or service for accumulated risk. The aim is a ranked, honest list.
Not for: greenfield design, or renaming "any code I'd write differently" as debt. Debt is deferred cost that actively hurts — aesthetic disagreement isn't debt.
Method
- Inventory concretely. Gather from code smells, TODO/FIXME markers, incident postmortems, slow tests, flaky deploys, and team pain points. Name each item as what is wrong and where — a vague "the code is messy" gets dropped.
- Categorize each item: Design (bad abstractions), Code (duplication, complexity), Test (gaps, flakiness), Infra/Ops (manual toil, fragile deploys), Dependency (outdated/unsupported), or Documentation.
- Assess impact and cost. Impact = how often it hurts × how badly (velocity drag, incident risk, security exposure, onboarding friction). Cost = effort to fix. Estimate both, even roughly.
- Score and rank. High-impact/low-cost first. If an item is high-impact but high-cost, don't jam it into a sprint — flag it as a project needing planning. If impact is low, park it explicitly (recording it counts as done).
- Separate deliberate from accidental debt. Deliberate debt (a conscious shortcut) needs a written payoff trigger; accidental debt (neglect) needs a root-cause note so it stops recurring.
- Recommend a next-cycle slice — the small set with the best impact-to-effort ratio.
Example
Debt register (excerpt):
| Item | Cat | Location | Impact | Cost | Pri |
| Auth check duplicated in 6 routes | Code | api/routes/* | High | Low | P1 |
| Payment tests mock the ledger | Test | test/pay/* | High | Med | P1 |
| Node 16 EOL runtime | Dep | Dockerfile | High | Med | P2 |
| 400-line God controller | Design| orders.ctrl.ts | Med | High | P3 |
Quick win: extract shared auth middleware (High impact, Low cost).
Deferred: God controller — real but high-cost; schedule as a project.
Pitfalls
- A wish list, not a register — every dislike logged with no impact/cost, so nothing is actually prioritizable.
- Chasing low-impact, satisfying refactors while high-impact debt festers.
- No effort estimate, so stakeholders can't weigh the trade and nothing gets funded.
- Ignoring deliberate debt's payoff trigger — the shortcut quietly becomes permanent.
Output format
Debt register (table): item | category | location | impact | est. cost | priority
Top priorities: <ranked, one-line justification each>
Quick wins: <high impact, low effort>
Deferred / accept: <item + reason it's parked>
Recommended next-cycle slice: <the best impact-to-effort set>
1---2name: eng-tech-debt3description: Identify, categorize, and prioritize technical debt into a ranked, defensible backlog that ties each remediation to impact and effort — a register, not a wish list.4---56## When to use78When planning maintenance work, justifying refactor time to stakeholders, or auditing a codebase or service for accumulated risk. The aim is a ranked, honest list.910**Not for:** greenfield design, or renaming "any code I'd write differently" as debt. Debt is deferred cost that actively hurts — aesthetic disagreement isn't debt.1112## Method13141. **Inventory concretely.** Gather from code smells, TODO/FIXME markers, incident postmortems, slow tests, flaky deploys, and team pain points. Name each item as *what is wrong and where* — a vague "the code is messy" gets dropped.152. **Categorize each item:** Design (bad abstractions), Code (duplication, complexity), Test (gaps, flakiness), Infra/Ops (manual toil, fragile deploys), Dependency (outdated/unsupported), or Documentation.163. **Assess impact and cost.** Impact = how often it hurts × how badly (velocity drag, incident risk, security exposure, onboarding friction). Cost = effort to fix. Estimate both, even roughly.174. **Score and rank.** High-impact/low-cost first. If an item is high-impact but high-cost, don't jam it into a sprint — flag it as a project needing planning. If impact is low, park it explicitly (recording it counts as done).185. **Separate deliberate from accidental debt.** Deliberate debt (a conscious shortcut) needs a written payoff trigger; accidental debt (neglect) needs a root-cause note so it stops recurring.196. **Recommend a next-cycle slice** — the small set with the best impact-to-effort ratio.2021## Example2223```24Debt register (excerpt):25 | Item | Cat | Location | Impact | Cost | Pri |26 | Auth check duplicated in 6 routes | Code | api/routes/* | High | Low | P1 |27 | Payment tests mock the ledger | Test | test/pay/* | High | Med | P1 |28 | Node 16 EOL runtime | Dep | Dockerfile | High | Med | P2 |29 | 400-line God controller | Design| orders.ctrl.ts | Med | High | P3 |30Quick win: extract shared auth middleware (High impact, Low cost).31Deferred: God controller — real but high-cost; schedule as a project.32```3334## Pitfalls3536- **A wish list, not a register** — every dislike logged with no impact/cost, so nothing is actually prioritizable.37- **Chasing low-impact, satisfying refactors** while high-impact debt festers.38- **No effort estimate**, so stakeholders can't weigh the trade and nothing gets funded.39- **Ignoring deliberate debt's payoff trigger** — the shortcut quietly becomes permanent.4041## Output format4243```44Debt register (table): item | category | location | impact | est. cost | priority45Top priorities: <ranked, one-line justification each>46Quick wins: <high impact, low effort>47Deferred / accept: <item + reason it's parked>48Recommended next-cycle slice: <the best impact-to-effort set>49```