One Session, One Task — The Principle I Learned from Claude Code Context Management
Go deeper on this topic
Claude Code Workflow
Large-scale refactoring, CLAUDE.md design, and session management with Claude Code
Article 3 of 4 in this series.
Next reads
How to Guarantee Quality When AI Mass-Produces Your Code — The 4-Layer Gate System Behind 200 Components
The real quality machinery behind ~200 AI-built interactive components: four pre-commit hooks, data invariant tests, real-browser pixel smoke tests, and a quality-score + PR-proposal pipeline — documented down to the file names.
Bulk-Fixing 200 Components with Claude Code — The Full Pipeline of Classification, Fixing, and Verification
A practical record of bulk-fixing bugs across 203 interactive components with Claude Code in 6 commits and 100+ files. The entire process of classification, templating, and verification.
Growing CLAUDE.md — Three Months of Evolving an AI Collaboration Config File
A record of continuously updating CLAUDE.md over 3 months across 323 commits. Rules that worked, rules that didn't, and the limits of "advisory" configuration.
Use the topic hub as a map, then continue to the next article in the series. New here? Start at the home hub →
Introduction
I've developed 211 interactive components with Claude Code. Fluid simulations, pianos, pinball, maze generation — small demos running in the browser, built one after another, debugged, refactored, and improved for accessibility.
Through that process, I went through an enormous amount of trial and error with workflow. How to write prompts, how to structure CLAUDE.md, how to split tasks. I tried dozens of rules, kept what worked, and discarded what didn't.
The result was writing this in CLAUDE.md:
One session, one task. Context is the scarcest resource.
Here's the story of how I arrived at that line. Why this is the most effective principle, and what failures led to it.
What Is Context Exhaustion
First, the premise. LLMs have a context window constraint. Everything during a session — prompts, tool calls, file read/write results — piles up in this window.
What happens when the window fills up? Older information gets compressed. "Compressed" sounds nice, but the reality is closer to "forgotten." The contents of a file just read, a design decision just discussed, a bug pattern just fixed — these all become fuzzy.
I noticed this phenomenon during a bulk fix across all 211 components. The task was to find and fix setTimeout leaks across all files. The first 30 files were perfect. Patterns were accurately recognized, and cleanup functions were properly added.
But around 50 files in, accuracy visibly dropped. The same bug patterns were missed. Fixes already applied to earlier files were reported as "new discoveries." In the worst cases, code that had already been fixed was reverted.
This is context exhaustion. The window has finite capacity, and as the task grows larger, context "freshness" degrades. Like human focus, the more you use it, the more it depletes.
Four Failure Patterns
Before recognizing context exhaustion, I repeated several typical failures.
1. "While We're at It" Syndrome
The most common trap. During a session fixing AudioContext error handling, you notice a missing mountedRef and try to fix that too.
It seems efficient. The file is already open, so why not fix it while we're here?
Here's what actually happens. With the AudioContext fix pattern loaded in context, you suddenly start processing the mountedRef pattern. Two patterns coexist, and it becomes ambiguous which rules are being applied. The result: AudioContext fixes at 80% accuracy, mountedRef fixes at 60% accuracy. Both end up half-baked.
Done separately, both complete at 95%+ accuracy. That's what I did. Commit 04163d8e fixes "AudioContext error handling, mountedRef guards, and clipboard safety" across 18 files, but it was executed as three small sessions and committed together at the end.
2. Accuracy Decline in Long Sessions
I once continued a session for 3 hours. The first hour was smooth. Explaining patterns, reading files, verifying fixes. Accuracy above 95%.
In the second hour, things got shaky. Even saying "same pattern as before," slightly off fixes were suggested. More verification rounds were needed.
By the third hour, starting a new session would have been faster. Repeating the same explanations, re-verifying the same fixes. Accuracy felt below 50%.
The problem with long sessions is that productivity decline is gradual and hard to notice. It doesn't break suddenly; accuracy erodes slowly. By the time you notice, you need to redo all the work from the second half.
3. Context Contamination
Residual information from a previous task distorting judgments for the new task.
For example, right after doing performance optimization on Canvas components, switching to accessibility improvements for DOM components. The result: Canvas-style optimizations suggested for DOM components. Things like trying to apply requestAnimationFrame batch processing to DOM elements.
This project clearly separates Canvas and DOM usage. BubbleWrap and ParticleField use Canvas (performance-focused), while GravityBadges and FidgetZone use DOM + CSS Transform (accessibility-focused). This distinction is established architecture, but context contamination blurs the boundary.
4. "Fix Everything" Delegation
In the early days, I sent prompts like:
"Inspect all components under src/components/interactions/ and fix any bugs."
The result was disastrous. Scope was infinite for 211 files. No criteria for what constitutes a bug. No priority for fixes. The AI dutifully tried to read all files, but context exhausted partway through and it stopped functioning properly.
This failure taught me that scope clarity directly affects context efficiency. Saying "fix setTimeout leaks" means the AI only needs to keep the setTimeout and clearTimeout pattern in context. No extraneous information consuming the window.
Establishing the Principle
After these failures, I wrote several clear rules in CLAUDE.md.
"If the same problem fails twice, /clear." Failing twice means the needed information isn't in context, or it's contaminated. Starting fresh is faster than retrying.
"/clear between unrelated tasks too." When moving from task A to task B, even if task A succeeded, /clear. Task A's information is unnecessary for task B but continues to consume context.
Task granularity is "a size that fits in one commit." This was the most practical criterion. A task too large to explain in one commit is a signal that it should be split.
The actual commit log supports this principle:
04163d8e: AudioContext error handling — 18 files, 1 sessionf51f0c83: Module-level mutable state elimination — 15 files, 1 session1fc14711: Numerical safety guards — 8 files, 1 session7723cfaf: Pointer Events unification — 16 components, 1 session
Each commit focuses on a single bug category. This was the most important decision for conserving context and maintaining accuracy.
Integration with the takt Workflow
To systematize the one-session-one-task principle, I created a workflow called takt. It varies session splitting based on task size.
quick-fix: Bug fixes or small refactors. If the scope is clear and involves 3 files or fewer, complete it in one session. Planning, implementation, and verification all happen within a single session. Most tasks fall here.
plan-implement-review: Adding new features. Split into 3 sessions: planning, implementation, and review. The first session decides what to do, the second implements it, the third verifies quality. Each session is independent, carrying forward only the conclusions of the previous one.
spec-then-build: Large features or architecture changes. Split into 4 sessions: spec writing, planning, implementation, and review. Writing the spec first lets the implementation session focus purely on code.
The key discovery was that splitting sessions itself improves quality. The planning session focuses only on planning, producing better plans. The implementation session focuses only on implementation, producing more accurate code.
This is the same for human workflows. Someone who writes design docs while coding tends to do both poorly. Separating phases improves the quality of each phase. The same was true for AI.
Practical Techniques
Several techniques are used alongside the one-session-one-task principle to maximize its effectiveness.
Validation First
At the start of a session, explicitly state "what constitutes done." If there are tests, provide them. If not, show the expected output concretely.
This alone improves quality 2-3x. Why? Because when the AI knows the goal, it uses context differently. Instead of "examining every file thoroughly," it prioritizes "retaining information relevant to the goal." Efficient use of the context window.
For example, "fix all files where useEffect cleanup doesn't call clearTimeout" is less effective than "find and fix this pattern: Before: useEffect(() => { const id = setTimeout(...); }, []) → After: useEffect(() => { const id = setTimeout(...); return () => clearTimeout(id); }, [])." The latter is overwhelmingly more accurate.
Naming Patterns Explicitly
The instruction "use the same pattern as this file" is extremely effective. Rather than explaining abstract rules, showing one concrete implementation example lets the AI reproduce the pattern accurately.
What I actually did: manually perfect one of the 211 components, then pass it as the "model" to the session. "Follow the fix pattern in Match3.tsx and apply the same fixes to the remaining files." The AI holds that pattern in context and propagates it laterally.
The more concrete the model, the less context it consumes. Abstract rules leave room for interpretation, and that interpretation consumes context. Concrete examples can be applied directly with minimal consumption.
Worktree Isolation
Independent tasks are split into separate worktrees using the cc <name> command for parallel execution. This uses Git's worktree feature to physically separate directories, completely eliminating inter-session interference.
For example, Canvas component fixes and DOM component fixes are completely independent. Doing them sequentially in the same session triggers the "context contamination" described above. Running them in parallel in separate worktrees lets each session focus on its own task.
Auto-merging to the staging branch on completion means virtually no integration overhead.
Separating Review Perspectives
Code review and specification review happen in separate sessions.
Code review (microscopic) examines implementation details: variable names, error handling, performance, type safety. Specification review (macroscopic) examines requirements alignment, architectural consistency, and user experience impact.
Doing both in the same session causes bias. Diving into code details means forgetting the big-picture spec; thinking about spec means missing code details. Separating them makes each review thorough.
Quantitative Impact
Clear differences emerged before and after adopting the principle.
Before session splitting (early trial-and-error period):
- Files fixed per session: average 5
- Fix accuracy (manual verification pass rate): ~70%
- Rework rate: 30%+
- Total time per task: Long (including rework)
After session splitting (after establishing the principle):
- Files fixed per session: average 15
- Fix accuracy: ~95%
- Rework rate: Below 5%
- Total time per task: Short (virtually no rework)
3x more files fixed with higher accuracy might sound contradictory. The secret is narrowing scope to conserve context.
When focusing on a single bug pattern, the AI can concentrate context on recognizing and fixing that pattern. Applying the same fix pattern to 15 files has far higher context efficiency than applying different fix patterns to 5 files.
The Evolution of CLAUDE.md
In the process of arriving at the one-session-one-task principle, CLAUDE.md itself changed significantly.
Early stage: Long lists of React rules. "Set useEffect dependency arrays correctly," "Components should have no side effects." Writing these obvious things had little effect. The AI already knows them. Just a waste of context.
Middle stage: Workflow rules. "Run tests before modifying files," "Run bun run check to pass lint after modifications." This was somewhat effective. Clear procedures reduced oversights.
Current stage: Decision criteria and fallbacks. "When in doubt, choose quick-fix," "If the same problem fails twice, /clear." This is the most effective. Not telling the AI "what to do" but "what to do when uncertain."
An important insight from this evolution:
"Hooks are deterministic, CLAUDE.md is advisory."
A Biome pre-commit hook enforcing formatting is deterministic. If a rule is violated, the commit fails. This reliably works. Writing "please maintain formatting" in CLAUDE.md is advisory. Whether the AI complies is probabilistic and depends on context state.
So rules that must be reliably enforced go into hooks. CLAUDE.md is for decision criteria that hooks can't express — task granularity, session splitting, and fallbacks for uncertainty.
One more thing: regularly delete rules that don't work. The longer CLAUDE.md gets, the more each rule's "attention" from context thins out. 5 rules have higher compliance per rule than 10 rules. This is also part of context management.
Summary: Context Is Like Attention
The one-session-one-task principle is ultimately based on the insight that "the context window is like attention."
Humans also lose accuracy with prolonged focus. Doing multiple tasks simultaneously makes both half-baked. Fatigue from previous work affects the next task. Breaks restore capacity.
The AI's context window behaves the same way. Long sessions reduce accuracy. Mixing multiple tasks contaminates context. Previous task information distorts new tasks. /clear resets and restores.
When I recognized this analogy, my approach to working with AI fundamentally changed. I stopped treating AI as a "tireless universal tool" and started treating it as "a brilliant collaborator with limited focus."
When asking a brilliant collaborator to do work, you define the task clearly, narrow the scope, and provide only the necessary information. Not "do everything" but "do just this." When one thing is done, ask for the next.
This principle isn't limited to AI. In human team development, not mixing multiple concerns in a single pull request is fundamental. Code review accuracy drops otherwise. Working with AI follows the same principle.
From the experience of developing 211 components, I can say that the productivity bottleneck is context management. Not prompt sophistication or model capability. How to efficiently use the finite context window — that is the most practical challenge of AI-assisted development, and one session, one task is its simplest answer.