Have you noticed that many AI coding tools always feel like they’re “almost there”? The model says “tests passed,” but didn’t actually run them. Says “code modified,” but modified the wrong file. Says “fix complete,” but introduced three new bugs.

The root cause of these problems isn’t that the model isn’t smart enough - it’s the lack of “engineering” constraints. Today, let’s talk about Claude Code’s six production-grade patterns - seemingly too simple to mention, but repeatedly validated as necessary in actual production.

Pattern 1: Read Before Edit

Have you ever tried assembling IKEA furniture without reading the manual? Ends up with screws in wrong holes, panels mounted backwards, and three spare parts left over.

AI models can do the same thing - attempting edits without reading the current file content. They might proceed based on outdated or incorrect assumptions, resulting in messed up code.

Dual-Layer Protection Design

Claude Code addresses this through “soft and hard measures”:

Soft constraint (prompt layer): FileEditTool description explicitly states:

“You must have used the Read tool at least once in the conversation before editing. If you attempt to edit without reading the file, the tool will return an error.”

Hard constraint (code layer): FileEditTool’s call() method checks before executing edits - whether the current conversation contains a Read call for the target file. Returns error if not.

Why dual-layer? Prompts are “soft constraints” - the model usually complies, but under specific conditions (instructions “forgotten” due to long context, attention drift over multiple turns), it might be ignored. The code layer is a “hard constraint” - even if the model ignores the prompt, the tool itself refuses to execute.

This is like: traffic signs reminding “don’t run red lights” are soft constraints, the speed bump at the intersection is a hard constraint - you stop when you see the sign, and even if you don’t see it, the bump stops you anyway.

Pattern 2: Graduated Autonomy

Have you ever had this conflict: wanting AI to work automatically for efficiency, but afraid it’ll mess things up requiring cleanup?

Claude Code’s design philosophy: autonomy isn’t “all or nothing,” but a continuous spectrum, with safety nets at every position.

Permission Mode Gradient

default  acceptEdits  plan  bypassPermissions  auto  dontAsk
                                                    
                                                    └── Fully autonomous
                                            └── Classifier auto-decides
                                 └── Skip permission checks
                       └── Plan only, don't execute
             └── Auto-accept edits, confirm others
   └── Confirm each step

The key design is “automation with fallback.” The auto mode uses the YOLO classifier to automatically make permission decisions, but has two safety valves:

export const DENIAL_LIMITS = {
  maxConsecutive: 3,  // 3 consecutive denials
  maxTotal: 20,       // 20 total denials
} as const

export function shouldFallbackToPrompting(state: DenialTrackingState): boolean {
  return (
    state.consecutiveDenials >= DENIAL_LIMITS.maxConsecutive ||
    state.totalDenials >= DENIAL_LIMITS.maxTotal
  )
}

When the classifier denies 3 consecutive times or 20 total times, the system permanently falls back to manual user confirmation. This means even in the most autonomous mode, the capability to fall back to human decision is preserved.

This is like self-driving cars - normally drives itself, but prompts human takeover when encountering complex situations, rather than stubbornly driving into a wall.

Pattern 3: Defensive Git

Have you ever been burned by Git? Trying to “fix the last commit” with amend, and it wiped out someone else’s work. Wanting to quickly commit with --no-verify, bypassing the team’s code checks. Wanting to batch-add with git add ., and accidentally committing the .env file.

AI models make these mistakes too, because training data contains lots of Git tutorials recommending amend to “fix the last commit” - without distinguishing between hook failure and normal commit scenarios.

Git Safety Protocol

Claude Code embeds a complete Git safety protocol in BashTool prompts:

  • Never skip hooks (--no-verify): pre-commit hooks are the project’s quality gate
  • Never amend (unless user explicitly requests): git commit --amend modifies the previous commit; using it after hook failure will overwrite the user’s prior commit
  • Prefer specifying files: git add <specific-files> instead of git add -A, avoid accidentally adding sensitive files
  • Never force push to main/master: warn even if user requests it
  • Create new commit instead of amend: when hook fails, commit hasn’t happened - at this point --amend modifies the previous commit, potentially destroying prior work or losing changes

The last point is especially important. The prompt explicitly explains the causality:

“pre-commit hook failure means the commit didn’t happen - so --amend modifies the previous commit, potentially destroying prior work or losing changes. Fix the issue, re-stage, create a new commit.”

This is like equipping a new driver with a co-pilot brake - not distrust, but preventing wrong pedal presses at critical moments.

Pattern 4: Structured Verification

Have you ever met someone like this: says “done,” but when you ask “did tests pass?”, says “probably.” When you ask “did you run it?”, says “no, but it looks right.”

AI models can do the same - claiming “tests passed” or “code is correct” without actually running verification.

Verification Chain Mechanism

Claude Code establishes an explicit verification chain in system prompts: Run tests → Check output → Report faithfully.

This simple process is reinforced through multiple mechanisms:

Reversibility awareness: Operations are risk-stratified:

Operation TypeExamplesRequired Model Behavior
Reversible operationsEdit files, create files, read-only commandsExecute directly
Irreversible operationsDelete files, force push, send messagesConfirm then execute
High-risk operationsrm -rf, DROP TABLE, kill processesExplain risk + confirm

Scope constraints: Model is told “authorization for X doesn’t extend to Y” - fixing a bug doesn’t authorize modifying test cases or skipping tests.

ant-only reinforcement instructions:

// @[MODEL LAUNCH]: capy v8 thoroughness counterweight
`Before reporting a task complete, verify it actually works: run the
test, execute the script, check the output. Minimum complexity means
no gold-plating, not skipping the finish line. If you can't verify
(no test exists, can't run the code), say so explicitly rather than
claiming success.`

The @[MODEL LAUNCH] comment indicates this is model-version-related behavior correction - the team re-evaluates whether this instruction is still needed when the model is upgraded.

This is like: not asking “did you complete the task,” but requiring “show me the test output” - claims without evidence don’t count.

Pattern 5: Scope-Matched Response

Have you ever met someone like this: you asked them to fix a faucet, and they,顺便 renovated the kitchen, and “helpfully” replaced the flooring - resulting in a two-week delay and triple the budget.

AI models have this problem too - “while I’m at it” doing extra things: refactoring while fixing bugs, updating documentation while adding features. Well-intentioned but causing uncontrolled scope creep.

Minimalist Instruction Group

Claude Code’s system prompts contain extremely specific scope restrictions:

“Don’t add features, refactor code, or make ‘improvements’ beyond what was asked. A bug fix doesn’t need surrounding code cleaned up. A simple feature doesn’t need extra configurability. Don’t add docstrings, comments, or type annotations to code you didn’t change.”

“Don’t add error handling, fallbacks, or validation for scenarios that can’t happen. Trust internal code and framework guarantees.”

“Don’t create helpers, utilities, or abstractions for one-time operations. Don’t design for hypothetical future requirements. … Three similar lines of code is better than a premature abstraction.”

Notice the specificity of these instructions - not abstract “keep it simple,” but verifiable rules:

  • “Don’t add docstrings to code you didn’t modify”
  • “Three lines of repetition is better than premature abstraction”
  • “Don’t add error handling for scenarios that can’t happen”

This is like: hiring a worker to fix the faucet, contract explicitly states “only fix the faucet, don’t touch anything else” - the more specific, the less room for argument.

Pattern 6: Tool-Level Prompts Over General Instructions

Have you ever tried calling someone’s name in a crowd? They might not hear, or heard but thought you were calling someone else.

Putting instructions in the system prompt is like calling out in a crowd - too much content, model has difficulty recalling the right instruction at the right moment.

Timing-Aligned Design

Claude Code equips each tool with its own behavior harness, rather than stuffing all instructions into the system prompt:

LocationContent
System PromptGeneral behavior instructions, output format, safety principles
BashTool DescriptionGit safety protocol, sandbox config, background task instructions
FileEditTool Description“Read before edit”, minimal unique old_string, replace_all usage
FileReadTool DescriptionDefault line count, offset/limit pagination, PDF page ranges
GrepTool Descriptionripgrep syntax, multiline matching, “always use Grep not grep”
AgentTool DescriptionFork guidance, isolation mode, “don’t peek at fork output”
SkillTool DescriptionBudget constraints, three-level truncation cascade, built-in skill priority

The advantage of tool-level prompts is timing alignment: when the model decides to call BashTool, BashTool’s description (including Git safety protocol) is in its attention focus. If the Git safety protocol were in the system prompt, the model would need to “recall” it from thousands of tokens of context - unreliable in long sessions.

Another advantage is cache efficiency. Modifying tool descriptions only affects the tool list hash, not the system prompt segment. The perToolHashes in cache break detection precisely tracks which tool’s description changed, rather than invalidating the entire cache prefix.

This is like: not writing “pay attention to paper orientation when using the photocopier” in the employee handbook, but posting a note next to the photocopier - visible when needed, not buried in a manual.

How the Six Patterns Relate

Before Execution ─────── During Execution ─────── After Execution
     │                         │                      │
     ├─ Read Before Edit        ├─ Defensive Git       └─ Structured Verification
     └─ Scope-Matched Response  └─ Graduated Autonomy
          └──────────────────────────┐
                        Throughout: Tool-Level Prompts

Tool-level prompts run throughout - the other five patterns are all implemented through tool prompts.

Read before edit and scope-matched response constrain pre-execution preparation. Defensive Git and graduated autonomy control safety boundaries during execution. Structured verification ensures post-execution correctness.

Dual-Layer Constraints: Design Wisdom Running Through All Patterns

A common theme behind these six patterns: dual-layer constraints.

  • Problem solved: Prompts alone can’t 100% guarantee model compliance with rules
  • Core approach: For high-risk behaviors, use prompts for “soft constraints” and code for “hard constraints”
  • Code template: Tool description states rules → call() method checks preconditions → Returns error if unmet

This is like:

  • Soft constraint: “No smoking” sign
  • Hard constraint: Sprinkler system automatically sprays when smoke detected

Combining both truly reduces risk.

Practical: Applying These Patterns

1. Implement Dual-Layer Constraints for Critical Behaviors

If violating a behavior causes irreversible consequences, don’t rely on prompts alone - add precondition checks in tool code.

2. Design Permission Gradients Instead of Binary Switches

Provide at least 3 autonomy levels for your Agent:

  • Manual confirmation: ask user at every step
  • Classifier auto-decision (with fallback): AI-assisted but with safety net
  • Fully autonomous: trust AI but retain circuit breaker

3. Explicitly Explain Causality in Git Operation Prompts

“Don’t amend” isn’t enough - explain “after hook failure, amend modifies the previous commit, causing loss of changes.”

4. Require Model to Show Verification Output

Don’t accept “tests passed” as text report - require actual test output display. Claims without evidence equal not done.

5. Replace Vague Instructions with Specific Rules

Replace “maintain code quality” with:

  • “Don’t add comments to unmodified code”
  • “Three lines of repetition is better than premature abstraction”
  • “Don’t add error handling for impossible scenarios”

6. Attach Behavior Instructions to Corresponding Tools

Git safety rules go in Bash tool description, file operation rules go in file tool description - don’t pile everything in the system prompt.

Summary

Six production-grade AI coding patterns:

PatternCore ApproachProblem Solved
Read Before EditPrompt soft constraint + code hard constraintAI edits without reading
Graduated AutonomyMulti-level permissions + classifier + denial tracking fallbackBalance between autonomy and risk
Defensive GitComplete safety protocol in tool promptsAI chooses “shortest path” causing data loss
Structured VerificationRun → Check → Report + reversibility classificationAI claims verification without actual execution
Scope-Matched ResponseSpecific, verifiable scope limitation instructionsAI “while I’m at it” does extra things
Tool-Level PromptsBehavior instructions attached to corresponding toolsGeneral instructions have low compliance in long sessions

Common themes of these patterns:

  1. Production-grade doesn’t mean complex - many are simple constraints too trivial to mention
  2. Dual-layer constraints优于单层 - soft constraint reminds, hard constraint backs up
  3. Specific优于abstract - “don’t add comments to unmodified code"优于"keep it simple”
  4. Timing alignment优于centralized storage - instructions appear when needed, not hidden in a manual

Understanding these patterns enables you to:

  • Build more reliable, predictable AI coding systems
  • Find balance between model capability and engineering constraints
  • Apply Claude Code’s production experience to your own projects

Next: Shortcomings - What Claude Code Still Does imperfectly.