The 3:1 Ratio¶

Scheduling Consolidation in AI Development¶
Jose Alekhinne / February 17, 2026
How often should you stop building and start cleaning?
Every developer knows technical debt exists. Every developer postpones dealing with it.
AI-assisted development makes the problem worse -- not because the AI writes bad code, but because it writes code so fast that drift accumulates before you notice.
In Refactoring with Intent, I mentioned a ratio that worked for me: 3:1. Three YOLO sessions create enough surface area to reveal patterns. The fourth session turns those patterns into structure.
That was an observation. This post is the evidence.
The Observation¶
During the first two weeks of building ctx, I noticed a rhythm in
my own productivity. Feature sessions felt great: new commands,
new capabilities, visible progress. But after three of them, things
would start to feel sticky: variable names that almost made sense,
files that had grown past their purpose, patterns that repeated without
being formalized.
The fourth session -- when I stopped adding and started cleaning -- was always the most painful to start and the most satisfying to finish.
It was also the one that made the next three feature sessions faster.
The Evidence: Git History¶
The ctx git history between January 20 and February 7 tells a clear
story when you categorize commits:
| Week | Feature commits | Consolidation commits | Ratio |
|---|---|---|---|
| Jan 20-26 | 18 | 5 | 3.6:1 |
| Jan 27-Feb 1 | 14 | 6 | 2.3:1 |
| Feb 1-7 | 15 | 35+ | 0.4:1 |
The first week was pure YOLO. Almost four feature commits for every consolidation commit. The codebase grew fast.
The second week started to self-correct. The ratio dropped as refactoring sessions became necessary -- not scheduled, but forced by friction.
The third week inverted entirely. v0.3.0 was almost entirely consolidation: the skill migration, the sweep, the documentation standardization. Thirty-five quality commits against fifteen features.
The debt from weeks one and two was paid in week three.
The Compounding Problem
Consolidation debt compounds. Week one's drift doesn't just persist into week two -- it accelerates, because new features are built on top of drifted patterns.
By week three, the cost of consolidation was higher than it would have been if spread evenly.
What Drift Actually Looks Like¶
"Drift" sounds abstract. Here is what it looked like concretely in the
ctx codebase after three weeks of feature-heavy development:
Predicate Naming¶
Convention says boolean functions should be named HasX, IsX,
CanX. After three feature sprints:
// What accumulated:
func CheckIfEnabled() bool // should be IsEnabled
func ValidateFormat() bool // should be HasValidFormat
func TestConnection() bool // should be CanConnect
func VerifyExists() bool // should be Exists or HasFile
func EnsureReady() bool // should be IsReady
Five violations. Not bugs -- but friction that compounds every time someone (human or AI) reads the code and has to infer the naming convention from inconsistent examples.
Magic Strings¶
// Week 1: acceptable prototype
if entry.Type == "task" {
filename = "TASKS.md"
}
// Week 3: same pattern in 7+ files
// Now it's a maintenance liability
When the same literal appears in seven files, changing it means finding all seven. Missing one means a silent runtime bug. Constants exist to prevent exactly this -- but during feature velocity, nobody stops to extract them.
Refactoring with Intent documented the constants consolidation that cleaned this up. The 3:1 ratio is the practice that prevents it from accumulating again.
Hardcoded Permissions¶
os.WriteFile(path, data, 0644) // 80+ instances
os.MkdirAll(path, 0755) // scattered across packages
Eighty-plus instances of hardcoded file permissions. Not wrong -- but if we ever need to change the default (and we did, for hook scripts that need execute permissions), it means a codebase-wide search.
Drift Is Not Bugs
None of these are bugs. The code works. Tests pass.
But drift creates false confidence: the codebase looks consistent until you try to change something and discover that five different conventions exist for the same concept.
Why You Cannot Consolidate on Day One¶
The temptation is to front-load quality: write all the conventions, enforce all the checks, prevent all the drift before it happens.
This fails for two reasons.
First, you do not know what will drift. Predicate naming violations only become a convention check after you notice three different naming patterns competing. Magic strings only become a consolidation target after you change a literal and discover it exists in seven places.
The conventions emerge from the work. They cannot precede it.
This is what You Can't Import Expertise meant in practice: the consolidation checks grow from the project's own drift history. You cannot write them on day one because you do not yet know what will drift.
Second, premature consolidation slows discovery. During the prototyping phase, the goal is to explore the design space. Enforcing strict conventions on code that might be deleted tomorrow is waste. YOLO mode has its place -- the problem is not YOLO itself, but YOLO without scheduled cleanup.
The Consolidation Paradox
You need drift history to know what to consolidate.
You need consolidation to prevent drift from compounding.
The 3:1 ratio resolves this paradox: let drift accumulate for three sessions (enough to see patterns), then consolidate in the fourth (before the patterns become entrenched).
The Consolidation Skill¶
The ctx project now has a /consolidate skill that encodes nine
project-specific checks:
| Check | What It Catches |
|---|---|
| Predicate naming | Boolean functions not using Has/Is/Can |
| Magic strings | Repeated literals not in config constants |
| File permissions | Hardcoded 0644/0755 not using constants |
| Godoc style | Missing or non-standard documentation |
| File length | Files exceeding 400 lines |
| Large functions | Functions exceeding 80 lines |
| Template drift | Live skills diverging from templates |
| Import organization | Non-standard import grouping |
| TODO/FIXME staleness | Old markers that are no longer relevant |
This is not a generic linter. These are project-specific conventions
that emerged from ctx's own development history. A generic code
quality tool would catch some of them. Only a project-specific check
catches all of them -- because some of them (predicate naming, template
drift) are conventions that exist nowhere except in this project's
CONVENTIONS.md.
The Decision Matrix¶
Not all drift needs immediate consolidation. Here is the matrix I use:
| Signal | Action |
|---|---|
| Same literal in 3+ files | Extract to constant |
| Same code block in 3+ places | Extract to helper |
| Naming convention violated 5+ times | Fix and document rule |
| File exceeds 400 lines | Split by concern |
| Convention exists but is regularly violated | Strengthen enforcement |
| Pattern exists only in one place | Leave it alone |
| Code works but is "ugly" | Leave it alone |
The last two rows matter. Consolidation is about reducing maintenance cost, not achieving aesthetic perfection. Code that works and exists in one place does not benefit from consolidation -- it benefits from being left alone until it earns its refactoring.
Consolidation as Context Hygiene¶
There is a parallel between code consolidation and context management
that became clear during the ctx development:
| Code Consolidation | Context Hygiene |
|---|---|
| Extract magic strings | Archive completed tasks |
| Standardize naming | Keep DECISIONS.md current |
| Remove dead code | Compact old sessions |
| Update stale comments | Review LEARNINGS.md for staleness |
| Check template drift | Verify CONVENTIONS.md matches code |
ctx compact does for context what consolidation does for code: it
moves completed work to cold storage, keeping the active context clean
and focused. The attention budget applies to both
the AI's context window and the developer's mental model of the codebase.
When context files accumulate stale entries, the AI's attention is wasted on completed tasks and outdated conventions. When code accumulates drift, the developer's attention is wasted on inconsistencies that obscure the actual logic.
Both are solved by the same discipline: periodic, scheduled cleanup.
This is also why parallel agents make the problem harder, not easier. Three agents running simultaneously produce three sessions' worth of drift in one clock hour. The consolidation cadence needs to match the output rate, not the calendar.
The Practice¶
Here is how the 3:1 ratio works in practice for ctx development:
Sessions 1-3: Feature work
- Add new capabilities
- Write tests for new code
- Do not stop for cleanup unless something is actively broken
- Note drift as you see it (a comment, a task, a mental note)
Session 4: Consolidation
- Run
/consolidateto surface accumulated drift - Fix the highest-impact items first
- Update CONVENTIONS.md if new patterns emerged
- Archive completed tasks
- Review LEARNINGS.md for anything that became a convention
The key insight is that session 4 is not optional. It is not "if we have time." It is scheduled with the same priority as feature work.
The cost of skipping it is not visible immediately. It becomes visible three sessions later, when the next consolidation session takes twice as long because the drift compounded.
What the Ratio Is Not¶
The 3:1 ratio is not a universal law. It is an empirical observation from one project with one developer working with AI assistance.
Different projects will have different ratios. A mature codebase with strong conventions might sustain 5:1 or higher. A greenfield prototype might need 2:1. A team of multiple developers with different styles might need 1:1.
The number is less important than the practice: consolidation is not a reaction to problems. It is a scheduled activity.
If you wait for drift to cause pain before consolidating, you have already paid the compounding cost.
If you remember one thing from this post...
Three sessions of building. One session of cleaning.
Not because the code is dirty -- but because drift compounds silently, and the only way to catch it is to look for it on a schedule.
The ratio is the schedule.
The Arc So Far¶
This post sits at a crossroads in the ctx story. Looking back:
- Building ctx Using ctx documented the YOLO sprint that created the initial codebase
- Refactoring with Intent introduced the 3:1 ratio as an observation from the first cleanup
- The Attention Budget explained why drift matters -- every token of inconsistency consumes the same finite resource as useful context
- You Can't Import Expertise showed that consolidation checks must grow from the project, not a template
- The Discipline Release proved the ratio works at release scale: 35 quality commits to 15 feature commits
And looking forward: the same principle applies to context files,
to documentation, and to the
merge debt that parallel agents produce. Drift is
drift, whether it lives in code, in .context/, or in the gap
between what your docs say and what your code does.
The ratio is the schedule. The schedule is the discipline.
This post was drafted from git log analysis of the ctx repository,
mapping every commit from January 20 to February 7 into feature vs
consolidation categories. The patterns described are drawn from the
project's CONVENTIONS.md, LEARNINGS.md, and the /consolidate skill's
check list.