← writing

The 31% Problem: How to Actually Use Claude Code Well

Faros AI tracked 22,000 developers through 2026 and found pull requests merged with no review at all are up 31.3% as AI coding tools spread. The model isn't the problem, every tool ships the same one. It's a handful of structures most people never turn on. A comprehensive, visual walkthrough of all of them.


Faros AI spent two years tracking telemetry from 22,000 developers across more than 4,000 teams. As AI coding tools spread through 2026, pull requests merged with no review at all, human or agentic, rose 31.3%.1 Bugs per developer rose 54%. The median wait for a first review more than doubled.1 AI accelerated the writing. Nobody built the matching acceleration into checking it.

That gap isn’t a model problem. Most people running Claude Code and someone running it well are pointed at the exact same model. The difference is a handful of structures around it: what it’s told to remember, what it’s allowed to automate, when it reaches outside the repo, and how much autonomy it’s actually given. Turn those on deliberately and review keeps pace with output. Leave them off and you get what the Faros numbers describe: code shipping faster than anyone is checking it.

hooks: enforces all four Memory Skills MCP Agent Subagents
Five structures around one model. Part One covers the three on the left, Part Two covers Subagents and Hooks, and everything after.

Part One: What Claude Code Knows

1. Memory: CLAUDE.md and auto-memory

CLAUDE.md is the file Claude reads before it reads anything else in your repo: architecture, non-negotiables, known gotchas. Write it once and every session inherits it, instead of you re-explaining the same three rules in every conversation.

CLAUDE.md you write it, once auto-memory Claude writes it, over time session start both load, always month six: still knows what bit you in month two
What you decided Claude must always know, plus what Claude has learned about working with you.
CLAUDE.md# Non-negotiables
- Booking writes MUST be atomic (row lock or unique constraint).
  Never check-then-insert.
- Store times in UTC. Render the viewer's local zone.

# Known ceilings
- Resend: 100 emails/day on the free tier.

The part most people miss: Claude Code also keeps a second, separate memory it writes itself, notes on corrections you’ve given it and preferences it’s picked up, without you editing a file by hand. CLAUDE.md is what you decided Claude must always know. Auto-memory is what Claude has learned about working with you specifically. Together they mean a project six months old still starts a session already knowing the one thing that bit you in month two.

Go deeper: Memory docs

2. Skills: a workflow you name once

A skill is a folder with instructions Claude loads on demand, not on every session like CLAUDE.md, only when the task calls for it. The test for whether something deserves to be a skill: did you just explain the same multi-step process for the third time?

explained 3 times, by hand /design-review named once, saved runs itself same 4 steps, every time
A skill turns a process you remember into a process that runs.
.claude/skills/design-review/SKILL.md---
name: design-review
description: Scan every screen in a mockup set for
  inconsistent nav, sidebar, or logo usage.
---
1. List every screen file in the mockup directory.
2. For each, extract the sidebar, nav, and logo regions.
3. Group by visual similarity and flag the outliers.
4. Report which screens don't match the majority.

Once it exists, /design-review runs the same four steps every time, instead of depending on you remembering to ask for all four. It’s the difference between a checklist you keep in your head and one that runs itself.

Go deeper: Skills docs, Plugins (for packaging and sharing skills across a team)

3. MCP: reaching what’s actually live

CLAUDE.md and skills are both static: text you wrote, sitting in the repo. MCP (Model Context Protocol) is how Claude reaches outside the repo, to a database, an API, a live service, and reads the real current state instead of what a comment claims it is.

CLAUDE.md + skills static, written in the past MCP reaches out live database the real, current roles table
Static text says what was true when you wrote it. MCP asks what's true right now.
.mcp.json{
  "mcpServers": {
    "supabase": { "command": "npx", "args": ["-y", "@supabase/mcp-server"] }
  }
}

Connect it, and a question like “what roles exist in this system” gets answered by querying the actual roles table, not by grepping a schema file that might be three migrations out of date. This is also where a lot of the review-gap problem quietly resolves itself: code written against the real, current shape of your data breaks less often than code written against a stale mental model of it.

Go deeper: MCP docs, MCP quickstart

4. Subagents and context: delegating without polluting

The conversation has a limit, and everything you put in it (every file read, every screenshot, every failed attempt) counts against that limit for the rest of the session. A subagent is a separate conversation with its own limit, spawned to do one bounded piece of reading or searching, that reports back a summary instead of dumping everything it saw into your main thread.

main thread, reading directly 16 screens, every file read, filling up fast

main thread, with a subagent summary still mostly empty, 16 screens read somewhere else

Delegating doesn't shrink the work. It keeps the work off the meter that matters.
subagent · Explorespawn -> Explore agent
  task: cross-check 43 requirements against 16 mockup screens
  main thread: never sees a single screenshot
  ✓ 3 mismatches, reported back in one message

The rule of thumb: if a task is “go read a lot of things and tell me what you found,” it belongs in a subagent. If it’s “make this specific edit,” it belongs in the main thread, spawning one for a two-line fix just adds a round trip for nothing.

Go deeper: Subagents docs, Context window

Part Two: How You Run It

5. Hooks: automation that doesn’t depend on the model behaving

Everything so far relies on Claude choosing to follow instructions. A hook doesn’t ask: it’s a shell command that fires automatically on an event you pick, and it runs whether or not the model remembered the rule.

hook · PreToolUsePreToolUse -> edit(app/booking/*.ts)
  checking: atomic capacity write...
  ✗ blocked: check-then-insert found
  -> use a DB transaction or a unique constraint

CLAUDE.md is a rule Claude is asked to follow. A hook is a rule that’s enforced, on every matching event, from every source, model compliance not required. That distinction is the whole reason hooks exist: for anything where “the model usually remembers” isn’t good enough.

Go deeper: Hooks guide, Hooks reference

plan mode proposes, edits nothing default asks before each action auto-accept edits files yes, shell asks gate the ~5% that's irreversible full autonomy nothing waits for you
More autonomy isn't the goal. The right amount, for the right step, is.

6. Permission modes and plan mode: choosing autonomy on purpose

Every session runs at some point on that spectrum, and the failure isn’t picking the wrong end, it’s not picking at all and drifting to whatever the defaults happen to be. Plan mode is the deliberate low end: Claude reads and proposes a full plan, but can’t touch a file until you approve it, exactly the right setting for a change you don’t yet trust it to make unsupervised. Full autonomy is the deliberate high end, appropriate for a sandboxed throwaway branch, not your main one.

The best sessions don’t sit at one point, they gate specifically. Bounded autonomy for the reversible 95% of what an agent does, a real checkpoint for the 5% that isn’t (a production migration, a force-push, a delete). That’s not a compromise between fast and safe. It’s what actually gets you both.

Go deeper: Permission modes, Sandboxing

7. Headless, scheduled, and CI: Claude Code without you watching

Everything above assumes someone’s at the keyboard. Claude Code also runs headless, no terminal UI, just a prompt in and a result out, which is what makes it usable in a script or a pipeline instead of only a conversation.

prompt no one watching claude -p headless run JSON out scriptable CI or cron, on a loop
Headless mode is what turns a conversation into a pipeline step.
headlessclaude -p "run the full test suite, summarize failures" \
  --output-format json > report.json

Point that at a cron schedule or a GitHub Actions workflow and Claude becomes a step in something larger: a nightly dependency audit, a PR that gets a first-pass review before a human ever opens it, a scheduled task that runs the same check every morning without anyone remembering to kick it off.

Go deeper: Headless mode, Scheduled tasks, GitHub Actions

8. Agent teams: when one agent genuinely isn’t enough

Every structure so far assumes one agent, however delegated. Agent teams are more than one agent working the same problem concurrently, each with its own context, coordinating instead of taking turns. They’re still experimental and off by default, one environment variable turns them on.

lead billing/ teammate A auth/ teammate B reporting/ teammate C independent scope no shared files none blocks the others
Bounded scope per teammate is what makes parallel actually faster.
agent teamteam: migrate three independent modules in parallel
  agent A: billing/  agent B: auth/  agent C: reporting/
  each isolated. none blocks on the others finishing.

This is the one place in this guide where the lesson from three-quarters of enterprise agent failures actually applies directly: more agents is not automatically more throughput, it’s more surface for one agent’s mistake to reach the others unchecked. The pattern that works is the same one that works for a team of people: bound each agent’s scope tightly, and don’t let any of them build on another’s output without a real check in between.

Go deeper: Agent teams, Cross-session messaging

9. The terminal is still there

It’s easy to treat Claude Code as the whole environment. It isn’t. It’s one pane among several: the dev server still needs to run, the database logs still need watching, and a background process that Claude kicked off ten minutes ago is still going whether or not you’re looking at it. A status line that shows which branch and which session you’re actually in, and a terminal split into a few purposeful panes instead of one crowded window, is a small thing that stops “which one of these is waiting on me” from becoming its own daily tax.

Go deeper: Terminal configuration, Status line


None of these nine make the model smarter. That’s the point: the model behind the 31.3% Faros measured and the model behind a session where review keeps pace with output are the same model. What’s different is whether memory, skills, MCP, subagents, hooks, permission modes, headless automation, and agent teams are switched on deliberately, or left off while the backlog quietly grows. Review discipline isn’t a property of the model. It’s a property of the system you build around it, one structure at a time.

For the full, current reference on all nine, start at the docs map or the features overview. Questions or corrections welcome, reach out.

Footnotes

  1. Faros AI, The AI Engineering Report 2026: The Acceleration Whiplash (April 2026), telemetry from 22,000 developers across 4,000+ teams. Pull requests merged without any review up 31.3%, bugs per developer up 54%, median time to first review up 156.6%. faros.ai 2

Cite this

Khan, M. (September 7, 2026). The 31% Problem: How to Actually Use Claude Code Well. Moeez Khan. https://moeezkhan.com/writing/how-to-actually-use-claude-code/

Moeez Khan
Moeez Khan

Software Engineer at AWS Transform, building agentic AI for enterprise and mainframe modernization — and writing about making legacy tractable at scale.

← More writing