Maintain docs/TECH_DEBT.md, the living list of code-level cleanup that isn't a risk, a shortcut, or an open decision (that's the risk-register skill's job) and isn't a future feature (that's ROADMAP.md's job). Use when a lint/format/style violation slips past an existing gate, a small known cleanup is noticed while working on something else, or a filed item is fixed and needs removing. DO NOT use for anything with a real cost or risk if left unaddressed (use risk-register instead), for aislop baseline findings (already lifecycle-managed in .aislop/baseline.json), or for anything confidential. Triggers: 'add to tech debt', 'log this as cleanup', 'track this lint violation', 'mark tech-debt item #N fixed', 'what's on the tech debt list'.
86%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
A single committed table (docs/TECH_DEBT.md) of code-level cleanup that isn't a risk, a shortcut, or an open
decision (docs/RISK_REGISTER.md's job) and isn't a future feature (docs/ROADMAP.md's job) -- just things that
should get tidied up when there's spare time. Sibling to the risk-register skill, sharing its scaffolding pattern
(dedicated skill, YAML row template, JSON schema, validation script) but not its append-only invariant: a tech-debt
row is deleted once fixed, not archived, because there is no decision to keep evidence of.
risk-register's docs/RISK_REGISTER.md, there is no
append-only guard here and no technical backstop preventing deletion -- that is the deliberate design, not a gap.
A concurrent-edit merge that drops a still-open row alongside a legitimate deletion is a known, accepted
limitation of this model; it is not engineered around, because the whole point of choosing this model over
risk-register's is to avoid that machinery for low-stakes items.scripts/validate-tech-debt-schema.sh,
wired into pre-commit via lefthook, blocks a locally-committed malformed row. A commit made through the GitHub
web UI or API, git commit --no-verify, or from a machine without lefthook installed is not stopped by this.docs/RISK_REGISTER.md instead. Before deleting a row (marking
it fixed), confirm the fix didn't reveal a real cost or risk; if it did, promote it to docs/RISK_REGISTER.md
first (see Workflow) rather than letting the row vanish with the discovery unrecorded.docs/TECH_DEBT.md exists. If this is the first entry in a project and the file doesn't exist yet, create it with
a # Tech Debt title, an intro paragraph drawing the boundary against RISK_REGISTER.md/ROADMAP.md/aislop's
baseline, the enforcement-scope caveat from Rule 2, and an empty table using the columns in
assets/templates/tech-debt-row-template.yaml.assets/templates/tech-debt-row-template.yaml -- the shape of a single row, illustratedassets/schemas/tech-debt-row.schema.json -- the same shape, as enforceable constraintsscripts/validate-tech-debt-schema.sh, wired into pre-commit (lefthook), so a malformed row can never be
committed. No append-only companion (Rule 1).jq (schema constraints are read at runtime, never hardcoded -- see Scripts) and shellcheck (CI and pre-commit
both gate the validator script), both pinned in mise.toml.docs/TECH_DEBT.md documents.docs/RISK_REGISTER.md (risk-register
skill), not this doc. If a tech-debt item turns out to carry one, promote it (see Workflow).aislop baseline findings (.aislop/baseline.json) -- already a scored, regression-tracked inventory of
code-quality findings with its own mechanism. Don't duplicate a finding aislop already tracks.area is a small, tech-debt-specific set of values (currently Code quality and Testing), not a closed JSON
Schema enum and not the .context/ themes vocabulary. RECOMMENDED reading before filing or resolving a row: see
Area Taxonomy and Row Schema for the full value list, the revisit
trigger for splitting an overloaded area, and the complete column-by-column row schema.
docs/RISK_REGISTER.md instead.# in docs/TECH_DEBT.md; the new row's # is that value + 1 (rows are freely
reused after deletion, so don't assume the max # ever seen -- just the max currently present).Description -- don't assume the reader has whatever prompted this open in front of them.
Never cite a .context/ file as where the extra detail lives -- .context/ is gitignored local scratch, so a
reference to it may be dead for every reader but the one who filed it. Inline the essential facts directly, or
point at a committed doc (an ADR, an MR description, another docs/*.md page) instead.assets/templates/tech-debt-row-template.yaml's field shapes (Area from the current
taxonomy, Effort from its enum, Since as YYYY-MM-DD, Status starting Open).scripts/validate-tech-debt-schema.sh before committing (the pre-commit hook runs it too, but check early to
avoid a bounced commit).# or Item name.docs/RISK_REGISTER.md
first, with the new row's Description referencing this tech-debt item by name -- since this row is about to be
deleted and would otherwise leave no trace of where the risk was first noticed.risk-register, there is no Resolved state to flip to -- deletion is the
resolution.risk-registerThe boundary between the two docs is exactly the kind of judgment call people get wrong -- that's the reason this
skill's grounding finding (a 2026-07-31 governance-model analysis) exists. If a
risk-register row turns out, on inspection, to actually be cleanup rather than a real risk, that's a correction to
make via the risk-register skill (amend or, if genuinely mis-filed, raise it there), not a silent move into this
doc.
risk-register's append-only guard exists to preserve a
decision audit trail; tech debt carries no decision to preserve evidence of. Don't add append-only machinery here
"for consistency" -- that would defeat the reason this skill exists as a separate, lighter sibling.
See the tech-debt-vs-risk-register governance rationale that grounds this skill for the full reasoning.docs/TECH_DEBT.md with one honest row is more
useful than an empty one or no doc at all -- RECOMMENDED to ship with whatever real rows exist rather than waiting
for a "complete" sweep.docs/RISK_REGISTER.md UNLESS the answer is a clear no.docs/TECH_DEBT.md by
2026-10-31 (90 days from creation), delete docs/TECH_DEBT.md and this skill -- the doc isn't earning its
keep if nobody is using it. The 90-day window is tied to this skill's 2026-07-31 seeding date, the same audit
referenced below.NEVER add an append-only guard or a Resolved status value to this doc.
WHY: Both exist in risk-register to preserve a decision audit trail. Tech debt carries no decision -- adding
either here just re-creates the machinery this skill was deliberately built to avoid.
BAD: "For consistency with risk-register, let's also block row deletion here."
GOOD: Delete the row. That's the resolution mechanism, not a shortcut around one.
NEVER file a real risk or open decision here because it's less ceremony than risk-register.
WHY: docs/TECH_DEBT.md has no append-only guard and no audit trail -- a real risk filed here can be silently
lost the moment its row is deleted, with nothing to notice.
BAD: Filing "Directions API retries could silently exhaust the free quota" as tech debt to skip risk-register's due-diligence step.
GOOD: File it in docs/RISK_REGISTER.md, where deletion is blocked and the item can't quietly disappear.
NEVER delete a row without checking whether the fix revealed a real cost or risk (Rule 3).
WHY: Deletion is irreversible in practice here -- there's no technical backstop, so a real risk "resolved away"
by deletion instead of promoted leaves no trace and no failing check to catch the mistake.
BAD: Deleting the lint-violation row the moment the lint is fixed, without checking whether the underlying test
gap it was masking is itself a bigger problem.
GOOD: Confirm the fix is complete and clean, then delete -- or, if it wasn't, promote to risk-register first.
NEVER cite a .context/ file as where a row's extra detail lives.
WHY: .context/ is gitignored local scratch, not a committed, durable record -- a reference to it may point at
something no other reader, machine, or fresh clone can ever open, the moment the row is committed.
BAD: Description: ... (.context/findings/2026-07-31-foo.md, finding M2)
GOOD: Inline the essential fact in the row itself, or reference a committed doc (ADR, MR, another docs/*.md
page) if it doesn't fit.
NEVER invent placeholder rows to make the doc look more populated than it is. WHY: A fabricated row is worse than an honest gap -- it looks like real signal to the next reader and wastes their time chasing cleanup that doesn't exist. The 2026-07-31 launch audit found exactly one genuine candidate and shipped with that rather than padding the count. BAD: Adding a vague "clean up some old code somewhere" row just to reach a target count. GOOD: Ship with however many real, verified rows exist -- one is more useful than five fabricated ones.
One check -- no append-only companion (Rule 1), unlike risk-register's two:
scripts/validate-tech-debt-schema.sh # Content: does every row match tech-debt-row.schema.json?Problem | Solution
Pre-commit blocks: a field doesn't match | validate-tech-debt-schema.sh caught a malformed field --
| fix it to match tech-debt-row.schema.json's constraints.
Pre-commit blocks: schema required fields mismatch | The script's column order is out of sync with a schema edit --
| update validate-tech-debt-schema.sh's expected_fields.
Not sure what the next # should be | Read the last row of the table; next # = its # + 1 (# is
| reused after deletion, so this is the max currently present,
| not the max ever assigned).
Unsure whether something belongs here or in | Does it carry a real cost/risk if left unaddressed? -> register
docs/RISK_REGISTER.md | row. Is it just cleanup for spare time? -> tech-debt row.| Topic | Reference | When to Use |
|---|---|---|
| Area values, the revisit/split trigger, full row schema, a worked example row | Area Taxonomy and Row Schema | Filing a new row or unsure which Area value or column format applies |
| Row shape as illustrated YAML | assets/templates/tech-debt-row-template.yaml | Drafting a new row before appending it |
| Row shape as enforceable constraints | assets/schemas/tech-debt-row.schema.json | Checking what the validator script actually enforces |
| Deciding whether an item is cleanup or a real risk | risk-register skill | Rule 3's due-diligence check, in either direction |
pantheon-org/tekhne
c8416e9
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.