ByeBuy.ai
BUILD YOUR ESCAPE ROUTE · ✦ CURSOR · HOST IT · ◫ SUPABASE · CONNECT IT · ↯ RELAY · BUILD YOUR ESCAPE ROUTE · ✦ CURSOR · HOST IT · ◫ SUPABASE · CONNECT IT · ↯ RELAY ·
CURRICULUM
← BYEBUY NOTES

September 12, 2026

TECHNICAL DEBT IS A CHANGE-COST PROBLEM

Technical Debt Is a Change-Cost Problem

Class 52 taught you to fix the cause, prove the behavior, and leave a better system. But what do you do when the system itself has become hard to change — when every small feature touches ten files, every AI patch adds another special case, and nobody remembers why a config value exists? That is this class. Before you clean anything, you need to name what is actually wrong.

Debt is future cost, not ugly code

Technical debt is the future cost created when a code or design shortcut makes a necessary change harder, riskier, or slower. The word "debt" is deliberate: like money debt, you borrow speed now and pay interest on every later change until you repay the principal.

That definition rules out a common mistake. Debt is not "code I personally dislike," "code written by AI," or "code in a style I would not have chosen." If a block is unfashionable but cheap to change, tested, and understood, it is not debt — leave it alone. If a tidy-looking block forces every new feature through three copy-pasted edits and an untested permission check, it is debt no matter how clean it looks.

Think of it as a change-cost question: *when the next real requirement arrives, how many places must I touch, how much must I understand, and how likely am I to break something unrelated?* The higher those answers, the higher the debt.

A second distinction matters. There is planned debt — a documented temporary shortcut with a review trigger ("we duplicate this parser for launch; revisit when we add a second provider or by June") — and neglected debt — a quiet "we'll clean it later" that nobody wrote down and nobody scheduled. Planned debt is a tool. Neglected debt is how codebases rot.

Eight signals worth learning to see

Debt announces itself in repeatable patterns. Learn these eight, because AI-generated code produces all of them enthusiastically:

1. Repeated logic. The same 15 lines appear in three routes. Research Desk's provider date-parsing copied into the brief route, the refresh worker, and the export helper is the classic case. Fix the format once, miss two copies, ship a bug. 2. Giant files with mixed responsibilities. One page fetches data, transforms it, renders it, and enforces authorization. Nothing can be tested or reused without loading everything. 3. Unclear names. data2, handleStuff, tmp_final_v2. Every future reader — including you in a month, including an AI agent — must reverse-engineer intent before making a safe change. 4. Dead branches and code. Commented-out experiments, if (false) blocks, unreachable flags from a prototype. They cost reading time and invite an AI to "reuse" something that should not run. 5. Unused or duplicated dependencies. An image library nobody imports, two date libraries doing the same job. Each one is download size, update burden, and supply-chain surface (recall Class 48.4). 6. Copied permission checks. Ownership logic pasted into five routes instead of living in one helper or policy. One route gets the fix; four keep the hole. In Neighborhood Events, "organizer can edit only their own listing" copied per route is a security debt, not a style complaint. 7. Scattered configuration. Timeouts, provider URLs, and feature flags spread across four files and two environment samples. Nobody can answer "what runs in production?" without a scavenger hunt. 8. Untested boundaries and ten-place features. A watchlist route with no ownership test, or any small feature that requires touching ten unrelated places. The test gap tells you where a change will hurt; the blast radius tells you how much.

Any one signal is a hint. Two or three clustered around the same seam mark a repayment candidate.

Draw a debt map of the Research Desk

Do not inventory the whole codebase at once. Map debt around one product area — say, Research Desk's brief-and-watchlist flow — so the inventory stays tied to user and system risk.

Sketch the flow left to right, then annotate where the signals live:

Search UI → /api/brief route → providerAdapter? → cache/DB
   → brief page (fetch + transform + render + authorize — GIANT)
   → POST /api/watchlist (copied ownership check — UNTESTED)
        → watchlist read (scattered config: TTL in 2 files)

Side piles: unused image library, dead export flag,
  obsolete prototype config, duplicated date parsing ×3

For each annotation, record three things: the file evidence (exact path and lines), the risk (who is affected and how — wrong brief shown? wrong user reads a private list? refresh bill spikes?), and the blast radius (how many routes, users, or deploys a change here could disturb). That turns grumbling into a decision tool.

Debt itemEvidenceRiskBlast radius
Duplicated provider date parsingroutes/brief.ts:40–58, worker/refresh.ts:22–38, lib/export.ts:15–29Wrong dates on briefs; each fix risks divergence3 call sites, all brief displays
Giant brief pageapp/brief/[ticker]/page.tsx (~600 lines: fetch, transform, render, authz)Any UI tweak risks breaking auth or parsing1 page, but 4 responsibilities
Watchlist route, no ownership testapi/watchlist/route.ts:30–70User A reads User B's list; high severityAll watchlist reads/writes
Unused image librarypackage.json:18, zero importsUpdate churn, bundle weight, advisory surfaceBuild only
Scattered refresh configworker/refresh.ts:8, .env.example:12, lib/config.ts:31Silent wrong interval or key in productionWorker + deploys

Planned versus neglected — and the trigger

For each row, add a fourth column: planned or neglected, and what triggers a revisit?

A planned entry reads: "Duplication accepted to ship one-provider v1. Trigger: adding a second provider OR brief-date bug OR June review. Owner: you. Cost of waiting: one more copy." That is honest borrowing.

A neglected entry reads: "Unknown. Found during inventory. No owner, no trigger." That is the dangerous kind — not because the code is worse, but because no decision governs it.

The rule: never repay neglected debt on vibes. Convert it to planned debt first (owner + trigger + rank), then schedule the repayment like any other task-card work from Part X.

Exercise: a read-only inventory → TECH-DEBT.md

Ask AI to investigate, but forbid it from changing anything. Investigation and repair are separate jobs with separate cards (Class 52.2).

Give the model this prompt shape:

Then you do the ranking. Sort by impact × confidence: high user or security risk with solid evidence goes first; aesthetic complaints with vague evidence go last or off the list entirely.

Done means: a TECH-DEBT.md file with 5–10 ranked entries, each carrying evidence, risk, blast radius, planned/neglected status, trigger, and a leave/fix/defer verdict. Verify: pick one entry and confirm you can open every cited file and line in under two minutes. Common failure: a list of dislikes with no file citations — that is taste, not an inventory, and no agent can act on it.

Check your understanding

  • Why is "code I dislike" not a sufficient definition of debt?
  • Which eight signals mark debt that raises future change cost?
  • What turns neglected debt into planned debt?

In the next lesson you will take exactly one item from that map — one safe seam — and restructure it without changing what the user sees.

ARTICLE DISCUSSION

JOIN THE
CONVERSATION.

0 COMMENTS

BYEBUY ACCOUNT ACCESS

Sign in

Use your account to save routes and make the catalogue yours.

Enter your email and we’ll send a secure sign-in link and code.

NEW ROUTES ADDED WEEKLY · 9,235 CATALOGUE ENTRIES · BUILD · DEPLOY · QUERY · STACK · SAY BYE TO BUY · NEW ROUTES ADDED WEEKLY · 9,235 CATALOGUE ENTRIES · BUILD · DEPLOY · QUERY · STACK · SAY BYE TO BUY ·