Highlights
Claude Code is easy to start with, but the same friction shows up quickly. You re-explain the architecture, repeat the same corrections, and point it at the same test project in every session. This first part of a two-part series argues that the fix is the environment around Claude, not a better prompt. It covers working habits that protect context, what belongs in CLAUDE.md and rules files, how to build reference and procedure Skills, and how to use Subagents for investigation and review without flooding the main session. The goal throughout is simple: stop repeating guidance you have already figured out.
Claude Code is easy to start using.
Open a repository, describe a change, and ask Claude to implement it. For a small bug or clearly scoped feature, that may be enough.
The problems arise later. You explain the same architecture again, remind it which test project matters, and correct the same mistake in another session. A teammate starts using Claude Code and repeats the same discovery.
Improving the prompt helps, but only up to a point. The bigger improvement comes from improving the environment around Claude.
Claude Code gives us several ways to do that:
- CLAUDE.md for persistent project instructions
- .claude/rules/ for more focused or path-specific rules
- Skills for reusable knowledge and procedures
- Subagents for focused work in separate contexts
- Hooks for deterministic checks and lifecycle automation
- MCP for external tools and systems
- Plugins for packaging reusable Claude Code configuration
- Worktrees and parallel sessions for isolated concurrent work
- Auto memory for knowledge Claude learns while working
These mechanisms solve different problems, and mixing them creates bloated configurations. Treat configuration like application architecture: each part gets a clear responsibility.
A better question than “How do I write a better prompt?” is:
What information, tools, checks, and workflows should exist around Claude so that I do not need to repeatedly explain the same things?
This is Part 1 of a two-part series covering the foundations: working effectively, managing context, writing a useful CLAUDE.md, and designing Skills and Subagents. Part 2 will cover hooks, MCP, plugins, and team automation. Let’s dive into it then.
Why Does Claude Code Need a Better Setup Than Better Prompts?
A developer who has worked on a project for a year carries knowledge that may never appear in the documentation:
- One service should not be called directly.
- An apparently unused middleware is required for a specific deployment.
- One test project catches regressions in a given module.
- A database operation must go through the unit-of-work pipeline.
- One folder holds the pattern to follow, while a similar one elsewhere is legacy.
Claude can discover some of this by reading the repository, but discovery has a cost. Every file read, search result, command output, message, and instruction consumes context, and a long investigation can fill much of the window before implementation begins.
A useful setup evolves gradually:

Fig: Claude Code configuration evolution
Do not open a new repository and immediately create fifteen Skills, six agents, ten hooks, and a plugin marketplace. Start with the work, notice what repeats, then capture what is genuinely reusable.
On a similar note, this might interest you:
From Copilots to Co-Workers: How AI Agents Will Change the Way Software Is Built
How Do You Use Claude Code Effectively?
Get the working pattern right before adding any configuration. Should Claude understand the code before editing it?
Yes, for non-trivial changes. I prefer this sequence:

Fig: Development sequence
Not every change needs a plan: renaming CustomerCode to CustomerNumber does not. Replacing authentication with refresh token rotation across an Angular app and ASP.NET API does. Plan mode separates investigation from modification:
Investigate the current authentication flow: login, token creation, validation, frontend storage, refresh, logout, related tests. Do not modify anything yet. Then propose the smallest change required to support refresh token rotation.
First understand. Then decide. Then implement.
How Do You Handle Ambiguous Feature Requests?
When the requirement itself is incomplete, ask Claude to interview you before implementation:
I want to add configurable approval workflows.
Before writing code, interview me about:
- Workflow rules
- Permissions
- State transitions
- Failure cases
- Audit requirements
- UI behavior
- Backward compatibility
Do not ask questions that can be answered by reading the repository.
When the requirements are clear, write a self-contained SPEC.md.
This exposes unclear requirements before code exists and produces a durable artifact. A clean session started from SPEC.md usually beats carrying the long interview forward.
How Do You Know Claude Actually Finished the Task?
Give Claude a way to prove completion. Instead of “Implement customer email validation,” add:
Implement customer email validation.
Acceptance criteria:
- Valid email addresses are accepted
- Malformed addresses are rejected
- Empty values return the existing required-field error
- Existing customer tests continue to pass
Add tests for the new cases and run the relevant test project.
Now there is evidence. The same applies to any task:
- Backend: dotnet build, dotnet test
- Frontend: npm run lint, npm test
- Migrations: apply to a clean local database and verify the schema
- UI: run the application and compare the result with the supplied design
The ideal workflow is not this:

Fig: Unverified workflow
It is closer to this verification loop, which separates supervised prompting from a reliable workflow:

Fig: Verification loop
That verification loop is a major difference between supervised prompting and a reliable development workflow.
What Are Completion Conditions for Longer Work?
For larger tasks, goal-based execution replaces repeated “Continue” and “Fix the next failure” prompts with a defined completion condition:
/goal all tests in tests/Customer.Tests pass, dotnet build exits successfully,
and no files outside the customer feature are modified Claude keeps working toward that state while a separate evaluator checks it. The idea is condition-driven development: describe completion in observable results. Good conditions contain the desired state, the command or evidence that proves it, and important constraints. That is far stronger than “Finish the authentication feature.” Keep the task bounded: an open-ended goal wastes time and tokens like an open-ended prompt.
How Do You Manage Context in Claude Code?
A debugging session accumulates reads, search results, compiler output, test logs, failed approaches, and corrections until the useful context is surrounded by noise.
When Should You Use /clear?
Between unrelated tasks, so a finished authentication investigation does not fill a reporting-bug session.
How Do You Use /compact Well?
Compaction preserves important decisions while removing detail. Guide it:
/compact Preserve:
- Modified files
- Architectural decisions
- Remaining tasks
- Commands used for verification
- Unresolved failures
What Is /btw Used For?
Disposable questions, such as a quick syntax check that does not deserve permanent space in the main context.
Should You Rewind Instead of Correcting Claude?
Claude Code maintains checkpoints. If Claude tries a wrong approach and you spend several prompts undoing it, the session holds both the failed approach and the repairs. It is often cleaner to rewind to the checkpoint before the experiment and retry with what you learned. Git is still essential. Checkpoints only shorten feedback loops inside the session.
Why Should You Name Long-Running Sessions?
For substantial work, let a session represent a workstream, such as oauth-refresh, billing-migration, or angular-upgrade. It becomes a working branch of context, which makes resuming easier.
What Should Go in CLAUDE.md?
CLAUDE.md is probably the highest-value starting point in an established repository. Claude reads it as persistent context. The challenge is deciding what deserves to be there.
Which Instructions Belong in CLAUDE.md?
Information that applies broadly:
# Build Backend: `dotnet build` Backend tests: `dotnet test tests/Application.Tests` Frontend: `npm run build` Frontend tests: `npm test` # Architecture - Controllers should remain thin. - Business logic belongs in application services. - Domain projects must not reference Infrastructure. - Reuse the existing repository layer instead of creating another data-access abstraction. # Angular - Use standalone components. - Prefer existing shared components. - Use reactive forms for new forms. - Follow the form pattern under `src/app/shared/forms`. # Workflow - Run the smallest relevant test set while developing. - Run the complete affected test project before finishing. - Do not modify generated API clients manually.
What Should You Leave Out of CLAUDE.md?
General documentation Claude already knows, such as “C# is a statically typed programming language,” plus large directory trees, API documentation, and full architectural explanations. Test every line:
If I delete this instruction, is Claude meaningfully more likely to make a mistake?
If not, cut it. CLAUDE.md loads repeatedly, so every unnecessary instruction is a recurring context cost.
When Should You Use .claude/rules/ Instead?
Some conventions apply to only part of the codebase. API rules do not need to occupy context while editing CSS.
.claude/ ├── CLAUDE.md └── rules/ ├── api.md ├── angular.md ├── database.md └── testing.md
Rules can also be scoped to file patterns.
For example:
--- paths: - "src/Api/**/*.cs" --- # API Rules - Validate request models before calling application services. - Use the existing error response contract. - Do not access DbContext directly from controllers. - Add authorization attributes where required.
These load only when Claude works with API files. A useful separation:

Fig: CLAUDE.md responsibility split
Why Should You Explain the Reason Behind a Rule?
“Do not call SaveChangesAsync() inside repository classes” tells Claude what to do. This is better:
Repositories must not call SaveChangesAsync() directly. The request pipeline commits through UnitOfWorkMiddleware so multiple repository operations can participate in the same transaction.
Now Claude can reason about related changes instead of blindly following a prohibition.
How Is Auto Memory Different From CLAUDE.md?
Auto memory holds what Claude learns during development and does not replace CLAUDE.md. CLAUDE.md contains intentional guidance, such as “All API write operations use the UnitOfWork pipeline.” Auto memory contains accumulated working knowledge, such as:
The integration tests require Redis running locally.
CustomerImportTests are slow and can be run separately.
The legacy billing module uses a different date parser. A rule every developer and every Claude session should follow belongs in version-controlled project configuration. A useful discovery that may help future sessions belongs in memory.
How Do You Create Reusable Skills in Claude Code?
Skills fit information too detailed or task-specific to load every session. A Skill provides reusable knowledge or a reusable procedure.
What Is a Reference Skill?
A reference Skill gives Claude knowledge for certain situations, such as api-conventions or database-migrations:
--- name: api-conventions description: API design and implementation conventions for this project. --- When implementing or modifying API endpoints: - Keep controllers thin. - Use application services for business logic. - Use the shared error contract. - Validate incoming request models. - Reuse existing DTOs when appropriate. - Follow the authorization pattern used by nearby endpoints.
A vague description, like “Useful API information,” gives Claude a weak routing signal. This is better:
API implementation conventions for controllers, request validation, authorization, error responses, and DTO usage in this repository.
What Is a Procedure Skill?
A procedure Skill describes a repeatable action, such as /fix-issue, /review-pr, or /prepare-release:
--- name: implement-feature description: Implement an application feature using existing project patterns. --- 1. Read the requirement carefully. 2. Find the closest existing implementation. 3. Identify affected layers before editing. 4. Implement the smallest change that satisfies the requirement. 5. Add or update tests. 6. Run the smallest relevant test set while developing. 7. Run the complete affected test project before finishing. 8. Review the diff for unrelated changes. 9. Report verification evidence.
Should Claude Invoke Every Skill Automatically?
No. You do not want Claude deciding, “This looks good, I should deploy.” For actions with side effects, such as deploy, commit, publish-package, create-release, send-message, and update-production-data, require explicit invocation:
disable-model-invocation: true
T Skills that are only background knowledge can be hidden from direct invocation while staying available to Claude. The distinction is knowledge Claude may load versus an action the developer starts.
How Do You Limit What a Skill Is Allowed to Do?
A Skill can define tools usable without repeated approval. For a commit Skill, limit that to git status, git add, and git commit instead of broadly disabling permission checks:
Give the workflow the smallest useful capability.
How Do You Stop a Skill From Flooding Your Context?
Fork it. A PR review Skill may inspect the entire diff, related files, test coverage, and git history. The main conversation does not need that raw investigation:
context: fork
That gives us a useful pattern:

Fig: Forked Skill review
This preserves substantial main-session context.
Can a Skill Use Current Repository State?
Yes. A Skill can inject command output when invoked, such as git diff, git status, and gh pr diff.

Fig: Skill repository state
The Skill stays reusable while the context stays fresh.
How Do Supporting Files Keep a Skill Small?
A Skill does not need everything in SKILL.md:
feature-development/ ├── SKILL.md ├── references/ │ ├── backend.md │ ├── frontend.md │ ├── database.md │ └── testing.md ├── examples/ │ └── complete-feature.md └── scripts/ └── validate.ps1
SKILL.md stays the entry point and routes Claude: backend work reads references/backend.md, Angular reads references/frontend.md, database changes read references/database.md, and before completing it runs scripts/validate.ps1. This keeps hundreds of lines out of active context, a pattern I think of as progressive disclosure:

Fig: Progressive disclosure
How Do You Design Specialized Subagents?
Use subagents when work benefits from its own context, not because multiple agents sound sophisticated.
When Should You Use a Subagent for Investigation?
Suppose Claude must understand a legacy pricing engine: fifteen services, configuration, database models, tests, git history, and feature flags. Only a few conclusions matter to the implementation.
Without a subagent:

Fig: Cluttered context
With a subagent:

Fig: Research subagent
Which Subagents Are Worth Creating?
Three or four, each with a narrow responsibility, is practical:
- Explorer: understands a part of the repository and reports relevant architecture, dependencies, existing patterns, and likely files involved. It usually needs read-oriented tools.
- Code reviewer: reviews the current diff for correctness, requirement gaps, unintended behavior, and unnecessary changes. It generally does not need permission to edit code.
- Test reviewer: determines whether meaningful behavior or edge cases are missing test coverage.
- Security reviewer: reviews security-sensitive changes for authentication, authorization, injection, secret handling, unsafe data flow, and related risks.
Can a Subagent Use Preloaded Skills?
An API implementation agent may always need api-conventions, error-handling, and testing-standards. Load them at startup.

Fig: Preloaded Skills agent
The agent defines the responsibility. The Skills provide the knowledge.
Should Subagents Have Persistent Memory?
A project-level code reviewer could gradually remember recurring architectural mistakes, common test gaps, modules with unusual conventions, and known legacy patterns. Be careful: memory should not quietly become the source of critical rules. Important standards should stay visible and version controlled. Subagent memory suits working knowledge, not policy.
How Do Worktrees Help Parallel Claude Sessions?
Two sessions editing the same checkout conflict quickly. Git worktrees give each worker its own checkout and branch.

Fig: Isolated worktrees
Independent tasks can then run at the same time. Subagents can also work in isolated worktrees, which I would use whenever a delegated agent may make substantial changes.
When Are Parallel Sessions Better Than More Agents?
Run two sessions: A implements, B reviews with fresh context and no stake in the code. The same works for tests: A writes tests from requirements, B implements code that passes them. Fresh context reduces defending assumptions made during implementation.
How Do You Run an Adversarial Review?
For important changes, I like the writer-reviewer pattern.

Fig: Fresh-context reviewer
“Find problems with this code” will usually produce something, even if low-value. A better instruction:
Review this diff against the stated requirements.
Report only findings that affect:
- Correctness
- Security
- Test coverage
- Compatibility
- Explicit project conventions
Do not report subjective style preferences unless they violate a project rule.
That reduces review noise.
Should You Use Agent Teams?
Claude Code has experimental support for teams of independent sessions. Unlike subagents, team members communicate and coordinate through shared tasks, which helps with genuinely parallel problems:

Fig: Agent team lead
Competing debugging hypotheses, each explored independently, are another strong use case:

Fig: Parallel debugging agents
However, agent teams use more tokens, add coordination overhead, and remain experimental. For sequential work, or tasks needing the same files, one session or a few subagents are simpler. The principle throughout Claude Code:
Parallelism is useful when the work is actually parallel.
Extra agents on a sequential problem add complexity, not speed.

Choosing between agent frameworks? Top 15 Agentic AI Frameworks at a Glance
What Comes Next After Context, Skills, and Subagents?
Claude now has cleaner context, a focused CLAUDE.md, reusable Skills, and Subagents. But everything here is still guidance. Claude will usually follow it, and occasionally it will not. Part 2 covers making important rules deterministic with hooks, connecting external systems with MCP, packaging mature workflows as plugins, and scaling across a team.
Lastly,
Key takeaways:
- Knowledge needs ownership: Reusable project guidance prevents repeated discovery, but outdated rules can spread mistakes across sessions.
- Context reduction risks omissions: Compaction and subagent summaries should retain unresolved failures, not just conclusions.
- Passing tests is insufficient: Email-validation criteria demonstrate verification, but incomplete requirements still produce gaps.
- Guidance is not enforcement: The conclusion defers deterministic controls to Part 2.
- Parallelism shifts complexity: Worktrees isolate edits, not incompatible design decisions.
Part 2 coming soon! Want AI-native engineering workflows like these built into your own product? Talk to our Product EngineeringAI team. Contact us today!