Skip to content

Claude Code Well-Architected Guide

Claude Code is not a chatbot - it reads the codebase, edits files across the repo, and runs shell commands. That makes it closer to a developer with local machine access than a Q&A tool, and it needs a framework that reflects that, the same way cloud teams use a Well-Architected Framework instead of ad hoc best practices.

The EmeSoft Claude Code Well-Architected Guide condenses eight practical concerns into six pillars: Security, Cost, Quality, Context, Validation, Delivery.

Every pillar below follows the same shape: Principle → Do → Don’t → Example Prompt → Checklist. Use the checklists directly in PR templates or Definition-of-Done reviews.

flowchart TB
    CC["Claude Code<br/>(local dev-level access)"]
    SEC["Security"]
    COST["Cost Management"]
    QUAL["Code Quality"]
    CTX["Context Engineering"]
    VAL["Validation<br/>(testing + human review)"]
    DEL["Delivery<br/>(workflow + knowledge sharing)"]
    CC --> SEC & COST & QUAL & CTX
    CTX -->|best context = best output| QUAL
    QUAL --> VAL --> DEL
    classDef pillar fill:#eef6ff,stroke:#3b82f6,color:#1e3a8a;
    class SEC,COST,QUAL,CTX,VAL,DEL pillar;
PillarPrinciple in one lineBiggest risk if ignored
SecurityClaude Code has developer-level local access - scope it to what’s necessary.Secrets, credentials, or client data leak into prompts or logs.
CostMatch model and context size to task complexity.Token spend grows with no quality gain; slow, expensive sessions.
QualityGenerated code meets the same bar as human-written code.Inconsistent, unreviewed, or unmaintainable code enters the repo.
ContextOutput quality is bounded by the quality of the context given.Claude guesses at conventions and domain rules, and guesses wrong.
ValidationAI confidence is not correctness - tests and a named human both gate merge.Code ships without proper testing or review because Claude said it’s fine.
DeliveryClaude has a defined role at each delivery step, and each change leaves docs/knowledge better.Ad hoc usage, undocumented decisions, tribal knowledge trapped in chat logs.

Principle: Claude Code should only access what is necessary to complete the task. Because it can read the codebase, edit files, and execute commands locally, treat every session as a developer session with real permissions - not a sandboxed chat.

Do

  • Scope Claude Code to the specific repo/branch/directory needed for the task - avoid running it from a parent folder that also contains unrelated client repos.
  • Use sample, synthetic, or masked data for local fixtures and debugging instead of production exports. Follow the data-handling tiers in Integration & Governance - Confidential and Restricted data never goes into a prompt.
  • Maintain an explicit allow-list of approved MCP servers and tools per project, reviewed the same way you’d review a new dependency.
  • Configure command permissions (e.g. .claude/settings.json allow/deny rules) so destructive commands - rm -rf, force-push, terraform apply, prod kubectl contexts - require explicit human confirmation rather than running unattended.
  • Treat any credential that was ever pasted into a prompt as compromised: rotate it, even if the session “looked private.”

Don’t

  • Paste API keys, .env contents, connection strings, or tokens into a prompt “just to debug faster.”
  • Point Claude Code at a production database, prod kubeconfig, or prod cloud credentials for troubleshooting.
  • Enable broad, unattended shell/network access (“yolo mode”) on any machine holding client code or data.
  • Auto-approve new MCP servers or plugins that haven’t been vetted by the Architect/Dev Lead.

Example Prompt

Good: "Using the sample dataset in /fixtures/orders-sample.json (no real
customer data), debug why OrderTotal is miscalculated for
multi-currency carts. Do not access any live database."
Risky: "Here's my prod .env and the connection string - connect to the
live orders DB and figure out why totals are wrong."

Checklist

  • No secret, credential, or token appears anywhere in the prompt or session history
  • No production database, API, or environment accessed from a Claude Code session
  • Only pre-approved MCP servers/tools enabled for this project
  • Destructive shell commands require explicit human confirmation
  • PR reviewed by a human before merge

Principle: Every prompt, tool call, and retry costs tokens and time. Efficient context and task scoping is an engineering skill, not an afterthought.

Do

  • Match the model to the task: a fast/cheap tier for mechanical or well-scoped work, the default daily-driver tier for regular development, and the top reasoning tier for hard architecture or ambiguous problems.
  • Point Claude at the specific files or module the task touches - use CLAUDE.md and explicit file references instead of asking it to “read the whole repo” for a one-file change.
  • Break large tickets into smaller, well-defined tasks. Smaller context windows are faster, cheaper, and more accurate than one giant ask.
  • Reuse context across a session - keep a running plan/notes file instead of re-explaining the same background in every prompt.
  • Cap retries: if Claude fails the same task twice, stop and re-scope the prompt or break the task down further rather than retrying blindly.

Don’t

  • Ask Claude to “review the entire codebase” when only one module changed.
  • Run long autonomous/background sessions unattended with no usage or cost monitoring.
  • Re-paste large files repeatedly across prompts instead of referencing them once by path.
  • Default to the most expensive model for trivial, mechanical edits (renames, formatting, boilerplate).

Example Prompt

Good: "In src/orders/pricing.ts only, fix the rounding bug in
calculateMultiCurrencyTotal(). Don't touch other files."
Wasteful: "Read the entire repository and tell me everything that might
be wrong with it."

Checklist

  • Model tier matches task complexity (not used out of habit)
  • Task/prompt scoped to the relevant files or directory only
  • Large tickets broken into smaller units before starting
  • Retry loop capped - re-scope instead of repeating a failing prompt
  • Team/org periodically reviews Claude Code usage and spend

Principle: Claude Code accelerates writing code; it does not replace engineering standards. Generated code must meet the same bar - conventions, architecture, naming, linting, tests - as code a senior developer would write.

Do

  • Point Claude at the project’s existing lint/format config, architecture docs, and naming conventions before generating code (this is where CLAUDE.md earns its keep - see Context Engineering).
  • Ask Claude to match the existing patterns in the surrounding file/module rather than introduce a new pattern.
  • Run the linter, formatter, and static analysis on every AI-generated change before requesting human review.
  • Apply the same PR review checklist to AI-authored diffs as to human-authored ones - no separate, lighter bar.
  • Ask Claude to explain non-obvious logic it generated, either inline as comments or in the PR description.

Don’t

  • Accept generated code that ignores established project patterns just because it runs.
  • Skip lint/build/test steps because “it’s just AI-generated boilerplate.”
  • Let Claude add a new third-party dependency without a license/security/necessity check.
  • Merge code that no one on the team can explain, regardless of who (or what) wrote it.

Example Prompt

Good: "Add a new endpoint following the existing controller pattern in
src/api/controllers/ - same validation, error handling, and
naming style as OrdersController.cs. Run dotnet format and the
analyzer afterward."
Risky: "Just make an endpoint that works, don't worry about how the
rest of the codebase is structured."

Checklist

  • Passes lint, formatter, and static analysis
  • Follows existing naming and architecture conventions
  • No unreviewed new dependency introduced
  • Reviewer can explain what the code does and why, not just that it passed

Principle: Claude Code’s output quality is bounded by the quality of the context it receives. A current, well-structured CLAUDE.md is the single highest-leverage investment a team can make in effective AI-assisted development.

Do

  • Maintain a CLAUDE.md per repository describing project structure, coding conventions, domain rules, Definition of Done, and exactly how to run build/lint/test.
  • Keep CLAUDE.md current - update it in the same PR that changes a convention, the way you’d update a README.
  • Give Claude the smallest sufficient context: link the specific files, ADRs, or spec sections relevant to the task instead of the whole repo history.
  • For non-trivial work, use a written spec/plan (see Agentic & Spec-Driven Dev) as durable, reviewable context instead of relying on chat memory.
  • Layer context deliberately: repo-level CLAUDE.md → task-level plan → prompt-level instruction.

Don’t

  • Leave CLAUDE.md empty, stale, or copy-pasted generically from another project.
  • Rely on conversational memory for constraints that should be written down once (security rules, DoD, domain invariants).
  • Bury critical business rules only in a Slack thread or a teammate’s head.

Example Prompt

Good: "Per CLAUDE.md, this service follows Clean Architecture with
MediatR handlers. Add a new query handler for
GetOrderSummaryByCustomer following the pattern in
GetOrderByIdHandler.cs, and update CLAUDE.md if this introduces
a new convention."
Weak: "Add a feature to get order summaries." (no pointer to
conventions, patterns, or where the domain rules live)

Checklist

  • CLAUDE.md exists, is current, and covers structure, conventions, DoD, and build/test commands
  • Task references specific files/docs rather than “the whole repo”
  • Domain and business rules are documented, not just assumed
  • Non-trivial work is backed by a written spec/plan, not chat history alone

Principle: AI confidence is not correctness. Every Claude-authored change is gated by both automated tests and a named, accountable human - never by “Claude said it’s correct” alone. This folds together Testing & Validation and Human Review & Accountability because in practice they’re the same gate applied by two different checkers.

Do

  • Require unit/integration tests for every Claude-generated change, run both locally and in CI before merge.
  • Have Claude propose test cases - including edge cases - alongside the implementation, then have a human confirm they’re the right tests, not just tests that pass.
  • Name a human owner for every AI-assisted change before it merges, consistent with the governance rule that a human owns every AI output.
  • Use AI-assisted code review as an additional first pass that surfaces issues earlier - not as a replacement for human review.

Don’t

  • Merge because tests pass somewhere nobody actually read or ran.
  • Accept “the logic looks right” without executing the code.
  • Let Claude review and approve its own generated code as the sole gate.
  • Treat a green CI badge as equivalent to human sign-off on business-logic correctness.

Example Prompt

Good: "Generate xUnit tests for calculateMultiCurrencyTotal(),
including edge cases: zero amounts, mixed currencies, and
rounding at the cent boundary. I'll review and add any cases
you missed before we run CI."
Risky: "Tests look fine, merge it." (no human read the tests or the
edge cases they cover)

Checklist

  • Unit/integration tests exist and pass locally and in CI
  • Edge cases were reviewed by a human, not assumed complete
  • A named human has reviewed and approved before merge
  • AI code review is used as a first pass, not the final gate

6. Delivery (Workflow & Knowledge Sharing)

Section titled “6. Delivery (Workflow & Knowledge Sharing)”

Principle: Claude Code should have a defined role at each step of delivery - not be reached for ad hoc - and every change should leave the team more knowledgeable, not just the codebase larger. This folds together Delivery Workflow and Maintainability & Knowledge Sharing because docs and decisions are easiest to capture at the moment of delivery, not after.

Do

  • Use Claude at defined checkpoints: analyze the ticket → propose a plan → implement → self-review the diff → generate test cases → update docs → draft the PR summary.
  • Have Claude draft the PR description, including what changed, why, and any trade-offs considered and rejected.
  • Update README.md, CLAUDE.md, or an ADR as part of the same change - not a “someday” follow-up ticket.
  • Record trade-offs and rejected alternatives so a future reader (human or AI) understands the why, not just the what.

Don’t

  • Use Claude only for the “fun part” (writing code) and skip docs, tests, or the PR summary because they feel like overhead.
  • Ship a change where the only record of intent is a chat transcript no one else can find.
  • Let a PR merge with a one-line “AI-generated” description and no explanation of decisions made.

Example Prompt

Good: "Implementation done. Now draft the PR summary: what changed,
why we chose the retry-with-backoff approach over a circuit
breaker, and update CLAUDE.md's 'Resilience patterns' section
to note this decision."
Incomplete: "Done, just write 'AI-generated fix' as the PR description."

Checklist

  • Ticket analyzed and plan proposed before implementation started
  • Diff self-reviewed by Claude and developer before requesting human review
  • Test cases generated and validated (see Validation)
  • Docs / README.md / CLAUDE.md / ADR updated in the same change
  • PR summary explains what changed, why, and what trade-offs were made

How this fits the rest of EmeSoft’s process

Section titled “How this fits the rest of EmeSoft’s process”

This guide is the Claude-Code-specific operational layer on top of two things the docs already cover more broadly:

  • Integration & Governance sets the company-wide, tool-agnostic rules (data tiers, human-in-the-loop, non-negotiables). This guide applies those rules concretely to Claude Code’s local, agentic access model.
  • Agentic & Spec-Driven Development defines how we structure autonomous agent work with specs. This guide defines the conditions (security, cost, context, validation) under which that work should happen.

For the honest, evidence-based account of what’s actually worked, what’s broken, and what’s still unsolved when using Claude Code and similar tools day to day, see What We Used & How, Problems & Workarounds, and Where AI & Humans Still Struggle.