September 12, 2026
EVERY PATCH LEAVES A SHAPE

In Class 38 you learned to spot context drift — the moment the AI quietly starts solving a different task than the one you agreed on. Drift changes the task. This lesson is about what happens when you keep accepting the changes anyway.
Each accepted patch leaves a mark on the project. Enough unexamined marks, and the system no longer has an understandable shape.
Debt is extra future work
Technical debt is extra future work created when a shortcut makes the system harder to understand or change.
That definition matters because it removes the moral judgment. Debt is not laziness. It is often a rational trade: you accept a rough edge now to learn something fast. A prototype that hard-codes three company cards to test a layout has debt. That is fine — as long as you know it is there.
The dangerous kind is debt that is invisible, unmeasured, and allowed to compound on a system people depend on. Nobody wrote it down. Nobody remembers why the code looks that way. The next person — or the next AI session — cannot see where a behavior belongs or why it works, so they add another patch beside the old one.
There is also a sharper edge worth naming: security debt.
Security debt is technical debt that an attacker can use. An old dependency with a known vulnerability. A copied authorization check that was correct in one file and wrong in the next. An undocumented admin route. An overpowered API key. A secret committed to the repository. Each of these can sit quietly for weeks and look harmless — until the wrong person finds it.
So keep two questions separate: "Is this messy?" and "Could this expose people, money, or control?" Mess is expensive. Security debt is dangerous.
The familiar AI project pattern
AI-built projects tend to decay through the same sequence:
requested feature
→ fast patch
→ problem caused by the patch
→ second patch in another file
→ copied logic
→ exception for one screen or customer
→ no one knows the actual source of truth
Notice what happened. Nobody decided to build spaghetti. Each step was locally reasonable. The button needed to work, so the AI added a check. The check broke exports, so the AI added a second check in the export script. The alert job needed the same rule, so the AI copied it a third time. Then one customer needed an exception, so the AI added a special case that only applies on one screen.
At the end, the project has four answers to one question, and no file can tell you which answer is correct.
Take the research dashboard from this part of the course. The first version computes "source freshness" inside the citation display component: if the publication date is within 30 days, show a green badge. Later, someone asks for freshness in exports, so the AI copies the 30-day logic into the export script — but writes 21 days by mistake. Later still, the alert job gets its own copy with yet another threshold. Now three surfaces disagree about what "fresh" means, and the durable question — *where is source metadata owned?* — was never answered. The team keeps asking "which line should I patch next?" when they should be asking "which function owns this rule?"
That drift from one owner to many copies is the shape debt leaves behind.
Five signals you can spot early
You do not need senior-engineer instincts to see debt forming. Look for these five signals:
| Signal | What it looks like | Why it matters |
|---|---|---|
| Duplicate logic | Two files calculate "source freshness" differently. | A future fix changes one and silently misses the other. |
| Giant file | One page handles UI, database calls, auth, formatting, and business rules. | A small change becomes risky because everything is tangled together. |
| Dead code | Old components, scripts, or feature flags remain after replacement. | The AI may reuse or modify the wrong path. |
| Conflicting patterns | Three ways to fetch the same data — direct fetch, a helper, and a copied snippet. | New work becomes guesswork about which pattern to follow. |
| Excess dependencies | A new package is installed for a tiny function already available in the project. | Updates, security review, and debugging all get harder. |
Walk through them with the dashboard. Duplicate logic is the freshness rule in three places. A giant file is a brief page that renders citations, calls the database, checks the login, formats dates, and decides alert thresholds. Dead code is the old citation component left behind after a redesign — still importable, still confusing the next AI session. Conflicting patterns are three different data-fetching styles across three features. Excess dependencies are a second date library installed because the AI did not know the project already had a date utility.
The events finder shows the same signals at smaller scale: two different distance calculations for "near me," one oversized page component, an abandoned filter control nobody deleted, two ways of saving favorites, and a new library for a job three lines of existing code could do.
None of these breaks the demo. All of them raise the price of the next change.
Why AI accelerates this
AI is very good at producing a locally plausible patch. Ask it to "make the export show freshness too" and it will — by writing code that works on that screen, today.
Unless you instruct it to inspect existing patterns first, it may not know the long-term architecture you intend. It does not feel the cost of a third copy. It does not ask "where should this rule live?" unless the task tells it to ask. Speed without an ownership question produces copies, exceptions, and new dependencies by default.
That is why Class 38's rails matter here. A bounded task — "reuse the existing freshness helper; do not add a dependency or a new pattern" — prevents a whole category of debt before it starts.
Practical exercise: a 20-minute shape audit
Set a timer. This exercise is observation only. You are not allowed to rewrite anything yet.
Create a file called PROJECT-SHAPE.md next to your project:
# Project shape: Research dashboard
- Duplicate: freshness rule lives in citation display and export script with different thresholds.
- Oversized file: brief page handles rendering, data fetching, auth check, and formatting.
- Unclear ownership: no single function owns "is this source fresh?" — three surfaces decide independently.
- Dependency to investigate: second date library added last week; check whether the existing utility already covers it.
- Candidate cleanup (one only): consolidate the freshness rule behind one function.
- Explicitly NOT doing: no rewrite, no redesign, no dependency removal today.
Four observations, one candidate cleanup, and a written promise not to start the refactor. That restraint is the skill. An audit that turns into an immediate rewrite usually adds a sixth signal to the five it found.
Finish line: a PROJECT-SHAPE.md with the four observations and one candidate cleanup — not a giant refactor plan.
Verify: can a second person read your file and point to each signal in the actual code? If an observation has no file and line to stand on, it is a feeling, not a finding.
Common failure mode: turning the audit into "fix everything tonight." Recovery: close the editor, keep the audit file, and bring one seam — not five — to the next lesson.
Check your understanding
1. In plain language, what is technical debt — and when is it a rational trade? 2. What makes security debt sharper than ordinary mess? 3. Retell the patch-to-no-truth chain in your own words, using the freshness example. 4. Name the five debt signals and one dashboard example of each. 5. Why does an AI coding assistant tend to accelerate debt unless it is told to inspect existing patterns?
ARTICLE DISCUSSION
JOIN THE
CONVERSATION.
Got a question, a take, or a better way to do this? Log in and leave a comment.
