plugins/coordinator/skills/debt-triage/SKILL.md
EM-PM conversation to review and prioritize the technical debt backlog. Triggers on demand or when open item count exceeds 20.
npx skillsauth add oduffy-delphi/coordinator-claude debt-triageInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Review the debt backlog, verify items are still relevant, re-prioritize based on current state, close resolved items, and present recommendations to the PM.
Announce at start: "I'm using the coordinator:debt-triage skill to review the debt backlog."
This is an EM-PM conversation, not a dispatched agent. The EM reads the backlog, applies judgment, and presents recommendations.
Before reading the backlog, check tasks/out-of-scope/*.md (if the directory exists — skip silently if absent). For each file present, note the concept and rejection reason. During triage, when any incoming item or discussion overlaps a known rejection, surface it:
"This is similar to
tasks/out-of-scope/<concept>.md— we rejected this because [reason]. Still feel the same?"
The maintainer can:
tasks/debt-backlog.mdAlso read tasks/bug-backlog.md (if it exists). Flag any BS-* entries that overlap with open DCH-/WAA- items by file path or description similarity. When overlap is found, populate the Cross-ref field on both entries (e.g., Cross-ref: BS-2026-03-18-1 on the debt item, Cross-ref: WAA-2026-03-19-1 on the bug item). Present overlaps to PM for deduplication decision.
Before dispatching any Haiku verification agents, do a quick staleness pre-check on the full item list.
For each item in tasks/debt-backlog.md, note its cited file path and the date it was logged. Items where git log --since="<finding-date>" -- <file-path> shows relevant commits are candidates for already-fixed status and should be confirmed first.
This pre-check prevents dispatching agents to verify debt that has already been resolved. In one measured run, 11 of 20 backlog items were already fixed before dispatch — the same failure mode applies to debt backlogs that drift behind active development.
Why pre-dispatch rather than during Step 2: Step 2 Haiku agents do the full per-line verification; this pre-check is the EM's own lightweight scan (date + git log) that prunes obviously-stale items before agent dispatch, reducing cost.
When evaluating whether a debt item or proposed enhancement is worth acting on, the debt-triage analyst may apply two concrete structural probes:
Deletion test. Imagine deleting the module, class, or abstraction in question. If complexity vanishes (callers simplify, the code reads more directly), the abstraction was a pass-through — it was not earning its keep. If complexity reappears across N callers (each must now handle what the module was hiding), the abstraction was load-bearing. Use this as a single-sentence verdict: "Deletion test: complexity would [vanish / reappear at N callers]."
One-adapter / two-adapter rule. One adapter is a hypothetical seam. Two adapters is a real seam that pays its abstraction cost. A single adapter wrapping one concrete implementation is usually premature — the deletion test confirms this. Two independent adapters in production justify the interface.
These probes apply when evaluating YAGNI calls, scope-change proposals, and deepening candidates. Pair any deletion-test finding with the convergence rule (≥2 independent agents before acting on a "shallow module" verdict) — single-agent subjective verdicts have elevated false-positive rates.
Dispatch Haiku agents to verify each open item against the current code. This is mechanical read-and-confirm work — no judgment needed. Group items by system for efficient dispatch (one Haiku per system).
Each Haiku agent receives a list of items for its system and:
git log --since="<finding-date>" -- <file-path>
still-open / already-fixed / partially-addressedThe coordinator then categorizes:
already-fixed: mark as no-longer-applicablestill-open: item remains openpartially-addressed: update the description based on Haiku's reportWhy Haiku: 12 of 16 items in the 2026-03-19 triage were already fixed. Haiku verification costs minutes; dispatching Sonnet executors on ghost debt costs significantly more.
Based on current state:
Before grouping items, query the completion log for historical nature: tech-debt entries to surface which areas have consumed significant effort recently versus which have been avoided:
query-completions.sh --where "nature=tech-debt" --since "90d" --sort "-loe.tshirt" --format markdown-list
Interpret the output with two lenses:
nature: tech-debt completions may reflect avoidance. Flag these for PM attention: "We have carried this debt for N days without touching it — is that intentional?"Present a one-paragraph hot-zone summary to the PM before the Step 4 grouping. Example framing:
"The completion log shows three XL tech-debt sessions in
src/indexer/over the last 90 days — that area is festering. Two open backlog items cite it; I'm escalating both.src/cache/has two open items but no recent debt sessions — possible avoidance."
Zero-row rendering: If the query returns no results (fresh repo or no tech-debt completions logged yet), render: (no tech-debt completions logged in last 90d — hot-zone analysis unavailable) and proceed without escalating.
Group remaining items by system for efficient batch execution:
## Triage Results
### Closed (no longer applicable): N items
| ID | Reason |
|----|--------|
### Recommended for immediate action: N items
| ID | System | Severity | Description | Effort |
|----|--------|----------|-------------|--------|
### Can defer: N items
| ID | System | Severity | Reason to defer |
|----|--------|----------|----------------|
### Needs PM decision (YAGNI/scope): N items
| ID | System | Description | Question |
|----|--------|-------------|----------|
Present the triage results and ask for:
After PM decisions:
Close resolved items (status: closed — [reason])
Update priorities per PM direction
Remove items PM declares YAGNI
Update header counts
For any item rejected with a load-bearing reason (scope conflict, doctrine conflict, cost-benefit rejection, architectural veto): write tasks/out-of-scope/<concept>.md using the template below. One file per concept, not per item — if a matching file already exists, append a new entry under "Prior requests" instead of creating a duplicate. Bugs do NOT go to .out-of-scope/ — only enhancement rejections. Create the directory on first use; never scaffold it empty.
# Out of scope: <concept>
**First raised:** YYYY-MM-DD
**Status:** Rejected (open to reconsideration)
## What was proposed
[One sentence describing the enhancement.]
## Why we rejected it
[Load-bearing reason. Cost, scope, doctrine conflict, etc.]
## Prior requests
- YYYY-MM-DD: [Brief description of how this came up]
## What would change our minds
[Conditions under which this should be reconsidered. Optional but useful.]
Commit:
git add tasks/debt-backlog.md tasks/out-of-scope/
git commit -m "debt-triage: reviewed N items, closed M, N remain open"
tools
Orient session — preflight, load context, choose work
documentation
Wrap up finished work — capture lessons, update docs
development
Triangulate plan-claim / code-reality / review oracles to classify each plan into DELIVERED+REVIEWED / DELIVERED-UNREVIEWED / PARTIAL / IN-FLIGHT / ABANDONED. Run after any crash or 'did we actually finish what we think we finished?' moment.
testing
Check for a published coordinator update and advise a preserve-by-default migration path — never a blind overwrite.