Skip to content
Back to skills

Quality Debt

ASecurity

Inventorying technical debt and ordering repayment by measured interest: touch frequency, blast radius, comprehension cost. Use to decide what to fix first and justify not fixing the rest.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 20, 2026
ai-agentsgobashrefactoringgit

Security analysis

A100/100

Pro scans all 7 files and shows the line behind each finding

Scanned October 20, 2026

npx -y skills add simota/quality-skills --skill quality-debt --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Quality Debt?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Quality Debt
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/simota-quality-debt/badge)](https://www.skillsdirectory.com/skills/simota-quality-debt)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: quality-debt
description: "Inventorying technical debt and ordering repayment by measured interest: touch frequency, blast radius, comprehension cost. Use to decide what to fix first and justify not fixing the rest."
allowed-tools: Read, Grep, Glob, Bash, Write
---
<!-- quality:contract -->

## Owns

A ledger of what the codebase will cost to keep changing, ordered by measured
interest, plus the reasoning for everything deliberately left alone. It
sequences and justifies; **it never implements the repayment**.

Phases: `INTAKE → MEASURE → SCORE → SEQUENCE → EMIT`.

## Before starting

- **Get the numbers before the ranking.** Touch frequency comes from git, blast
  radius from imports; incidents from the tracker go in `Cost today`, not the
  score. An input that cannot be measured is stated as unmeasured and the
  ranking is presented as partial
- **Separate deliberate debt from accidental rot.** Taken-for-a-reason with a
  repayment condition, and nobody-meant-this, rank and repay differently
- **Read the existing ledger and carry `first seen` dates forward.** The age of
  an entry is data
<!-- deliver:sizing -->
- **Size it before anything else**, first match wins. `T0` — one skill owns it, one file or
  one number, the question fits in one sentence: answer in a line that still carries the sweep,
  **no brief, no handoff payload**. `T1` — a `T0` condition fails: settle the brief first. `T2` —
  two or more skills own parts of it, or the verdict depends on another's output: route it. `T0`
  drops the paperwork, **never the evidence floor**. Mis-sized mid-run means re-sizing and saying so
- **Scale the checks, not the standard.** Run the narrowest check that could
  falsify the claim, and **say which checks were deliberately skipped** — a
  silent skip reads as coverage that was never there
- **A dialogue comes first** when the deliverable's shape is not uniquely
  determined, when a threshold is implied but unstated ("enough coverage", "good
  enough to ship" are numbers somebody has to choose), or when the work would set
  a gate that blocks other people. `excludes` may not be empty and `floor` is
  agreed before the work, not after (`_quality/SIZING.md`)
- **A term with two meanings, or a concept with two names, is a question, never
  a silent choice** — one question with its default, the answer into the
  brief's `terms` and `.agents/glossary.md`, and the glossary's names only from
  then on (`_quality/SIZING.md` § Terms)
<!-- /deliver:sizing -->

## Decide first

| Situation | How to proceed |
|---|---|
| Deciding whether something is debt at all | [what-counts](playbooks/what-counts.md) — ugliness nobody touches costs nothing |
| Naming the kind | [debt-taxonomy](reference/debt-taxonomy.md) |
| Scoring what it costs to leave | [interest](reference/interest.md) |
| Sequencing the work | [repayment](reference/repayment.md) |
| About to propose an order | [traps](playbooks/traps.md) |
| The hot code has no tests | It ranks **above** tested hot code — every change to it is a gamble. But its repayment **starts** with characterisation tests, never with restructuring. Rank order and work order are different questions |
| An entry is not being repaid | It carries the condition that would change that. "Won't fix" without a condition is a decision nobody can revisit |
| The proposal exceeds roughly a week | That is a planning decision, not a quality verdict. Ask |
| A claim here would be expensive to get wrong | [refute](refute.py) — put it to the engines that did not make it, asked to break it rather than to agree. Unrefuted is n engines finding nothing, never proof |
<!-- deliver:values -->
- Ties break by `_quality/VALUES.md`, read top to bottom: honesty over speed ·
  mechanism over intent · **independence over throughput** · subtraction over
  addition · what is measured over what is believed · the human decides what,
  the agent decides how. Against all of them: **a harness that is correct and
  avoided has failed** — this pack is the heaviest of its kind, and when the
  discipline costs more than the check, say so rather than performing it
<!-- /deliver:values -->

## Always / Never

- Always: state cost in observable units — minutes to understand, places a
  change must be made, incidents attributable, changes blocked
- Always: put characterisation tests first in any repayment that restructures.
  Refactoring untested code is how quality initiatives cause incidents
- Always: state what the ledger does not cover
- Always: get permission first before proposing more than about a week of work,
  before any repayment that changes a public interface or a data schema, or
  before declaring something permanently "won't fix"
- Never: implement the repayment. Emit a sequenced plan and fix directives
- Never: rank by how bad the code looks. The metric is what the next change
  costs, and beautiful code in a file nobody opens costs nothing to leave alone
- Never: propose a large refactor of untested code as the first step. The first
  step is the tests
- Never: produce the numbers yourself and then rank on them in the same breath
  without saying which came from where
- Never: write outside `.agents/quality/` — the ledger, the fix directives and
  this skill's journal are the whole of what it owns. Holding `Write` is not
  permission to touch the code the ledger is about

## Verify with

`touch_score` and `blast_score` are `E1` at minimum — each names the command it
came from (`git log`, an import graph). `comprehension_score` is the one estimate
(`E0`), allowed only because `_quality/SEVERITY.md` §4 defines it so: it is flagged
`ESTIMATED`, never partial. Any other input that is felt rather than measured is
stated as unmeasured, and the ranking says it is partial.

- **A ranking whose inputs are unmeasured is an opinion with a sort order.**
  Say which entries rest on complete data and which do not
<!-- deliver:report -->
- **Every claim carries its actual rung and is warranted for that claim** (`_quality/CONTRACT.md`
  §1-3): `E0` reasoning alone never ships · `E1` static · `E2` execution · `E3` automated test ·
  `E4` independent oracle · `E5` integration · `E6` production. A command that ran proves nothing
  about a different claim; `E4` needs a traced independent expectation, not a different agent
- **A claim that cannot reach its floor is not downgraded and shipped anyway** — it is a
  `HYPOTHESIS` with the observation or safe check that would settle it. A bounded `E1` proof may
  establish a defect; missing evidence never does. Narrowing a claim does not close the
  original question's unresolved parts
- **Report `status`**: `DONE` (every claim warranted, every residual classified) / `PARTIAL` / `BLOCKED`
- **Every residual is `BLOCKED` / `OUT-OF-SCOPE` / `DEFERRED` / `HYPOTHESIS`**
  and appears in the handoff's `residuals`; where this skill's own write scope reaches the place a
  reader would next look, a `#TODO(agent):` marker carrying that class goes there too
- **Never omit the sweep** — markers against `residuals`, claims made against claims warranted:
  `swept, 0 markers; 9 claims / 9 warranted`. While either pair disagrees the status is not `DONE`
<!-- /deliver:report -->
<!-- deliver:outcome -->
- **For findings emitted or adjudicated, record the outcome**: `real` · `refuted` · `accepted` ·
  `moot` · `open`. Refutation needs checked evidence; disagreement stays `open`. Report
  `real / (real + refuted)` with all five counts and its scope, source and method; with a zero
  denominator it is undefined. A rate of one is not suspicious by itself — read it against `open`,
  and never manufacture findings to have something to adjudicate. A run with no findings owes no
  precision report (`_quality/OUTCOMES.md`)
<!-- /deliver:outcome -->

## Done when

Every entry names its kind, its measured interest inputs and their sources, its
cost in observable units, and — where it is not being repaid — the condition
that would change that; and the ledger says what it does not cover.
<!-- deliver:surface -->
- **Say what the moment needs.** Start: one line naming what will be checked and what is
  excluded. Mid-run: a line whenever the reader must act now — a finding that changes the verdict,
  a blocked path, work that would grow the scope. Asking counts as speaking: one question, the
  decision it unblocks, the default taken if nobody answers
- **End with the verdict in one line** — status, and the finding that matters; then the sweep
  line, then one line per residual a human must decide, then what is next
- **The payload is the record, the report is the view.** Every finding, rung and outcome lives
  there; ten findings with two that matter are reported as the two and the count of the rest
- **The report is the four parts above and nothing else** — verdict, sweep, residuals, next; the
  findings file is named, never reproduced. It carries only what the payload does not, and its
  length follows the residuals a human must decide (`_quality/REPORT.md`)
- **Not bigger than it is.** The requested scope is the deliverable; thought goes deeper into the
  one thing asked, never wider. **A real problem is the exception** — something that would break,
  is unsafe, or rests on a false premise is explained in full (`_quality/REPORT.md`)
<!-- /deliver:surface -->

Files in this skill

  • SKILL.md9.2 KB
  • playbooks/traps.md1.2 KB
  • playbooks/what-counts.md2.1 KB
  • reference/debt-taxonomy.md4.7 KB
  • reference/interest.md7.3 KB
  • reference/repayment.md5.2 KB
  • refute.py29 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.