quality-debt
Inventory AICP's technical debt across code (TODO/FIXME/XXX markers), wiki (deferred backlog tasks), and architecture (known workarounds + structural-vs-operational gaps), then prioritize what to pay
SKILL.md.claude/skills/quality-debt/SKILL.md
GitHubquality-debt
Inventories AICP's known but unaddressed gaps — code TODO markers, wiki
deferred tasks, structural-only adoptions awaiting operational depth, and
documented workarounds. Different from quality-coverage (gaps you DIDN'T
know about until measurement) — this is gaps you DOCUMENTED at decision time
but deferred fixing. The skill turns the scattered debt signals into one
prioritized inventory the operator can actually act on.
Trigger phrases (when to load this skill)
Load when the conversation matches any of:
- Direct verb: operator says "tech debt", "what's deferred", "debt inventory", "known shortcuts", "what do we owe", "structural vs operational gaps"
- Periodic cycle: monthly/quarterly debt review (debt grows silently between reviews)
- Pre-release gate: before a milestone ships, audit the debt that was deferred FROM the milestone (was the deferral correct? still warranted?)
- Post-incident retrospective: when a bug ships, check if the debt inventory had warned about that area
- Onboarding new contributor: hand them the debt inventory so they know where the workarounds and shortcuts live
- Capacity planning: when the operator asks "what should the next sprint focus on?", debt is a candidate
Do NOT load when:
- A specific bug needs fixing now (load
feature-implementorsystematic-debuggingfor the fix) - The concern is testing gaps surfaced by measurement (load
quality-coverage) - The concern is style/lint gaps (load
quality-lint) - You want a full multi-dimension audit (load
quality-audit— debt is one of its sub-audits)
Operations
This skill has 4 named operations. Execute in order.
Operation 1: Inventory debt across all sources
Trigger: skill loaded; operator wants the inventory.
Process:
Code markers — scan the codebase for explicit debt signals:
grep -rn "TODO\|FIXME\|XXX\|HACK\|XXX-LATER" aicp/ tools/ tests/ 2>/dev/null | grep -v ".pyc"Capture: file, line, marker type, comment text. Classify by marker meaning:
- TODO: planned future work (medium urgency)
- FIXME: known broken behavior (HIGH urgency — possible bug)
- XXX: warning about edge case (HIGH urgency)
- HACK: deliberate workaround (medium urgency, but never delete without understanding)
Backlog deferrals — read
wiki/backlog/tasks/for tasks taggeddeferred, withstatus: blocked, or with notes containing "DEFERRED" / "deferred until":grep -lE "status: (blocked|deferred)|DEFERRED" wiki/backlog/tasks/*.md 2>/dev/nullFor each, capture: task ID, deferred reason, target unblock date/milestone (if any).
Structural-vs-operational gaps — read
wiki/decisions/andwiki/log/for items marked "structural only" or "stub". Per Structural Compliance Is Not Operational Compliance, AICP currently has structural Tier 4/4 but operational only Tier 2+. Inventory which Tier-3+ requirements are stubs:grep -rln "structural stub\|STRUCTURAL only\|operational implementation pending\|TODO:.*operational" tools/ wiki/ 2>/dev/nullDocumented workarounds — search wiki + memory for "workaround", "temporary", "until <X>", "known limitation":
grep -rln -i "workaround\|temporary\|known limitation" wiki/ docs/ 2>/dev/nullWrite the inventory to
wiki/decisions/00_inbox/debt-audit-<date>.md(type=reference). Group by source (code markers / backlog deferrals / structural stubs / workarounds).
Quality bar (Operation 1 done when):
- All four sources scanned with explicit commands captured
- Each item recorded with: file/path, marker type or category, brief description, age (days since first introduced if discoverable via git blame)
- Inventory written to dated audit page
Operation 2: Classify and prioritize
Trigger: Operation 1 inventory captured.
Process:
- For each debt item, assign two attributes:
- Risk: what happens if this debt is never paid? Low (cosmetic, internal-only) / medium (degrades dev velocity, complicates onboarding) / high (risk of bug, blocks Stage 3+ progress, blocks fleet integration).
- Cost to pay: how much work to address? Low (<1 day) / medium (1-5 days) / high (>1 week).
- Score: low cost + high risk = HIGHEST priority (pay now). Low cost + low risk = LOW priority (cleanup at convenience). High cost + low risk = DEFER permanently (or accept). High cost + high risk = PLAN as epic (too big for ad-hoc).
- Identify "compound debt" — items that share a root cause. Example: 5 TODO markers all reference "router doesn't have stage-aware routing yet." Those are ONE debt (PreToolUse hooks — Step 9.5), not 5. Compound debt items get folded into the parent epic.
- Identify "antiquated debt" — items older than 6 months that haven't been addressed AND aren't blocking anything. Candidate for deletion (the marker, not the code) — if it's been ignored for 6 months and nothing broke, the marker was wrong.
Quality bar (Operation 2 done when):
- Every item has risk + cost attributes
- Items grouped by priority quadrant
- Compound debt identified and grouped
- Antiquated debt flagged for deletion review
Operation 3: Author follow-up tasks for the priority items
Trigger: Operation 2 prioritization complete; operator approved which items to address.
Process:
- Operator picks which HIGHEST priority items to address THIS pass. Don't try to address all — capacity is finite; debt grows faster than fixes if you over-commit.
- For each chosen item, create a backlog task at
wiki/backlog/tasks/T<n>-<slug>.mdwith:- Reference to the debt-audit page (
derived_from) - Specific file/line references from Operation 1
- Done When criteria (the debt marker is removed AND the underlying issue resolved, not just commented out)
- Estimated effort from Operation 2's cost classification
- Reference to the debt-audit page (
- For "PLAN as epic" items, create an epic at
wiki/backlog/epics/instead of a task. Epic decomposes into modules + tasks viapm-plan. - For antiquated debt approved for marker deletion, create a single cleanup task: "Delete N antiquated debt markers" with the file:line list.
- Update the debt audit page with the task IDs created (so future audits can verify the items were actioned).
Quality bar (Operation 3 done when):
- Each chosen HIGHEST priority item has a backlog task
- Each "PLAN as epic" item has an epic + at least 1 child module
- Antiquated debt cleanup task created (if any)
- Audit page updated with task IDs
Operation 4: Update the debt-audit page + contribute trends
Trigger: Operation 3 tasks landed.
Process:
- Re-open the debt-audit page. Record:
- Total items per source (code markers / deferrals / stubs / workarounds)
- Distribution per priority quadrant
- Items addressed (task IDs)
- Items deferred (with reasoning)
- Items deleted as antiquated (count)
- Comparison with prior debt audit (if any) — trend up/stable/down
- If a SYSTEMIC pattern emerged (e.g., "3 of 5 HIGHEST priority items are about stage-gate enforcement gaps"), contribute back as a lesson:
gateway contribute --type lesson --title "...". - Run
tools/lint.py wiki/decisions/00_inbox/debt-audit-<date>.md. - Schedule next audit. Defaults: monthly for active development, quarterly for stable codebases. Increase frequency if trend shows growing debt.
Quality bar (Operation 4 done when):
- Per-source counts in audit page
- Per-priority distribution
- Tasks/epics created and IDs captured
- Trend comparison vs prior audit (or "baseline established" if first)
- Lesson contributed if systemic
- Audit page lint passes
Gotchas (known failure modes — read before doing)
Gotcha 1: Counting items, not understanding them (debt theater)
The temptation: report "47 TODO markers, 12 backlog deferrals, 5 stubs" and feel productive. But raw counts without classification are useless — 47 cosmetic TODOs are NOT equivalent to 5 high-risk operational stubs. Per Quality Standards anti-pattern: this is "documentation theater for the operator."
Detection: did you classify (risk + cost) for EACH item? Or did you report aggregate counts and call it done?
The rule: classification is the work, not counting. An audit page with raw counts but no per-item attributes failed Operation 2.
Gotcha 2: Deleting markers without understanding (silent debt re-creation)
A # HACK: temporary fix comment is annoying. Tempting to delete the comment because "the code seems to work." But the HACK marker was put there for a reason — deleting it loses the warning. Future readers don't know it's a workaround; future bugs hit the unmarked workaround and aren't recognized as such.
Detection: did you delete a marker without confirming the underlying issue is fixed (not just that the code "works for now")?
The rule: never delete a marker unless the underlying issue is RESOLVED (and document the resolution in the same commit). If the code works but the workaround is still there, the marker stays.
Gotcha 3: Inventorying everything as HIGH (priority inflation)
The temptation: every debt item feels important when you're looking at it. Marking everything HIGH defeats the purpose of prioritization.
Detection: more than 30% of items are marked HIGH risk.
The rule: HIGH risk means "real risk of bug, blocks roadmap, or affects external consumers." Most items are medium or low. If you have 47 items and 30 are HIGH, your filter is broken — recalibrate.
Gotcha 4: Conflating debt with backlog (work-in-progress is not debt)
Tasks in wiki/backlog/tasks/ with status: in-progress are WORK IN PROGRESS, not debt. Counting them as debt inflates the inventory and confuses the priority.
Detection: did Operation 1 step 2 filter on status: blocked|deferred? Or did it count ALL backlog items?
The rule: only status: blocked or status: deferred (or notes containing DEFERRED) count as debt. Active tasks are progress, not debt.
Gotcha 5: Skipping the structural-vs-operational gap inventory
The temptation: code markers are concrete; structural-vs-operational gaps feel abstract. Skip them. NO — structural-only adoptions are AICP's biggest hidden debt right now (Tier 4/4 STRUCTURAL but Tier 2+ operational means: many tools have stubs, many adoption requirements are presence-only). Skipping this category misses the largest debt class.
Detection: did Operation 1 step 3 explicitly scan for "structural stub" / "STRUCTURAL only" / "operational implementation pending"?
The rule: structural-vs-operational gaps ARE debt, possibly the most consequential kind because they create FALSE CONFIDENCE (compliance checker says "Tier 4/4" while operational depth is shallower). Always inventory them.
Reference exemplars
Per Extension Standards, reference exemplars are the second brain's model-builder and wiki-agent skills. For the OUTPUT artifact:
- Debt audit page: same shape as
coverage-audit-<date>.mdandlint-audit-<date>.mdfrom sibling quality skills — reference page with classification table + recommendations. - Real systemic pattern example: see Skills audit 2026-04-17 — that audit identified 47% of skills as boilerplate; the systemic pattern was "scaffolding script generated all skills from one template without filling in skill-specific content." That's the kind of insight a debt audit should surface.
Domain context
This skill operates in backend-ai-platform-python — see wiki/config/domain-profiles/backend-ai-platform-python.yaml. Read-only on code (creates wiki content + backlog tasks).
Related skills
| Skill | When | Why distinct |
|---|---|---|
| quality-coverage | unknown gaps surfaced by coverage measurement | Discovered debt; this skill inventories KNOWN debt |
| quality-lint | style/hygiene gaps | Different debt class — style isn't usually called "debt" but tracked separately |
| quality-audit | umbrella across all quality dimensions | Includes this skill as a sub-audit |
| pm-plan | epic/module/task decomposition | Large debt items become epics; this skill identifies them, pm-plan decomposes them |
| refactor-* skills | acting on debt that requires structural change | Debt audit identifies; refactor skills act |
| feature-iterate | improving a shipped feature | Different cycle — iterate adds value, debt-pay removes risk |