[{"data":1,"prerenderedAt":1681},["ShallowReactive",2],{"docs:\u002Ffoundations":3},{"id":4,"title":5,"accent":6,"body":7,"description":1645,"estReadTime":1646,"extension":1647,"eyebrow":1648,"icon":1649,"intro":1650,"lastUpdated":1650,"meta":1651,"navigation":363,"next":1652,"path":1655,"prev":1650,"review":1650,"seo":1656,"stem":6,"tocItems":1670,"__hash__":1680},"docs\u002Ffoundations.md","Foundations","foundations",{"type":8,"value":9,"toc":1624},"minimark",[10,19,97,177,320,453,749,1050,1307,1395,1620],[11,12,13,14,18],"p",{},"There's a cliff between people who \"use Claude Code sometimes\" and people who ship real systems with it every day. The cliff isn't about prompt-writing talent. It's about ",[15,16,17],"strong",{},"context architecture"," — knowing what Claude sees, when it sees it, and how the harness around the model decides what to do next. This section is about getting you on the right side of that cliff.",[20,21,24,35,51,59,64,67,94],"docs-section",{"id":22,"title":23},"mental-model","The Mental Model Shift",[11,25,26,27,30,31,34],{},"The single biggest gap in 2026 isn't prompt quality — it's thinking about Claude Code as a ",[15,28,29],{},"chatbot"," instead of as ",[15,32,33],{},"infrastructure",". A chatbot is a thing you type at. A piece of infrastructure is a thing you configure, shape, and build guardrails around. Claude Code is the latter.",[11,36,37,38,42,43,46,47,50],{},"Treat it like software you're setting up for your team. The outputs you get out are bounded by the context you put in — the ",[39,40,41],"code",{},"CLAUDE.md",", the ",[39,44,45],{},".gitignore"," rules Claude respects, the ",[39,48,49],{},"permissions.deny"," list, the hooks you wire into file-write events, the skills and subagents you've defined, the MCP servers you've connected. None of those exist by default. Setting them up is the job.",[52,53,56],"docs-callout",{"title":54,"variant":55},"The 80%²⁰ math","tip",[11,57,58],{},"If Claude makes the right call 80% of the time on any single decision, and a typical feature has 20 decisions, the odds of it getting all of them right are 0.8²⁰ ≈ 1%. Anthropic's internal testing found that unguided attempts succeed about 33% of the time. Planning collapses those ambiguous decisions into a spec you've reviewed — each one lands near 100%.",[60,61,63],"h3",{"id":62},"context-architecture-prompt-cleverness","Context architecture > prompt cleverness",[11,65,66],{},"People obsess over prompt phrasing when the real leverage is further upstream:",[68,69,70,77,87],"ul",{},[71,72,73,74,76],"li",{},"Is Claude reading a 400-line ",[39,75,41],{}," on every turn when only 50 lines are load-bearing? That's wasted context.",[71,78,79,80,83,84,86],{},"Is it loading ",[39,81,82],{},"node_modules"," tree output because your ",[39,85,45],{}," doesn't cover it (or because you explicitly pointed at the path)? That's wasted context.",[71,88,89,90,93],{},"Is it re-reading ",[39,91,92],{},"package.json"," on every message because there's no tool memory between calls? That's wasted context.",[11,95,96],{},"Fix those three and the prompts you were worried about start working.",[20,98,101,112,122,142,146],{"id":99,"title":100},"how-it-works","How Claude Code Works",[11,102,103,104,107,108,111],{},"Claude Code is two things fused together: a ",[15,105,106],{},"harness"," that runs on your machine, and the ",[15,109,110],{},"Claude model"," that runs in Anthropic's data centers. Everything you think of as \"intelligence\" lives in the model. Everything you think of as \"capability\" — reading files, running shells, editing code, executing hooks — lives in the harness.",[11,113,114,115,117,118,121],{},"When you type a message, the harness packages up a request: your message, the conversation history, the system prompt, the ",[39,116,41],{},", the list of available tools, and ships it to the model. The model replies with either text for you or a tool call. If it's a tool call, the harness executes it locally, captures the result, and sends that back to the model for the next turn. This loop continues until the model produces a final answer. That loop is the ",[15,119,120],{},"agentic loop",", and it's where most of the interesting behavior comes from.",[52,123,126,136],{"title":124,"variant":125},"What runs where","info",[11,127,128,131,132,135],{},[15,129,130],{},"Your machine:"," the CLI, the file reads\u002Fwrites, hooks, shell commands, MCP servers, sandboxing, permission prompts. Your code never leaves your machine unless a tool specifically sends it (e.g. the model sees a file you ",[39,133,134],{},"cat"," out).",[11,137,138,141],{},[15,139,140],{},"Anthropic's servers:"," the model inference. Prompts and tool results travel there for reasoning. Nothing writes to your disk from there — the harness is what writes.",[60,143,145],{"id":144},"tools-read-only-vs-write","Tools: read-only vs write",[11,147,148,149,152,153,152,156,152,159,162,163,152,166,152,169,172,173,176],{},"The harness exposes tools in two flavors. Read-only tools (",[39,150,151],{},"Read",", ",[39,154,155],{},"Glob",[39,157,158],{},"Grep",[39,160,161],{},"WebFetch",") never modify your system — they just return information. Write tools (",[39,164,165],{},"Edit",[39,167,168],{},"Write",[39,170,171],{},"Bash",") change state. In ",[15,174,175],{},"Plan Mode"," (covered in Workflows), only read-only tools are available, which is why it's safe to let Claude explore without supervision.",[20,178,181,184,187,202,206,209,239,246,253,314],{"id":179,"title":180},"context-window","The Context Window",[11,182,183],{},"Claude's context window is 200K tokens. Sounds huge. It fills faster than you'd think, and it's the single most important resource you manage.",[11,185,186],{},"The system prompt plus tool definitions take ~30–50K tokens before you've typed anything. Add a 5K CLAUDE.md, a few file reads, a couple of command outputs, and you're at 80K before the real work begins. Once the window crosses ~70–80% full, performance degrades visibly: Claude forgets earlier instructions, ignores CLAUDE.md rules, repeats itself, and makes more mistakes. More mistakes mean more rework, more rework means more tokens burned — a vicious cycle.",[52,188,191],{"title":189,"variant":190},"The 80% threshold","warning",[11,192,193,194,197,198,201],{},"When ",[39,195,196],{},"\u002Fcontext"," shows you're past 80%, stop adding. Finish the current task, save any breadcrumbs you need in a file, and ",[39,199,200],{},"\u002Fclear"," before starting the next one. Continuing past 80% is almost always more expensive than a clean restart.",[60,203,205],{"id":204},"monitor-whats-actually-in-there","Monitor what's actually in there",[11,207,208],{},"Two commands tell you where your tokens went:",[210,211,216],"pre",{"className":212,"code":213,"language":214,"meta":215,"style":215},"language-bash shiki shiki-themes github-light","\u002Fcost       # total tokens used this session, in dollars\n\u002Fcontext    # breakdown: system prompt, CLAUDE.md, tools, conversation, files\n","bash","",[39,217,218,231],{"__ignoreMap":215},[219,220,223,227],"span",{"class":221,"line":222},"line",1,[219,224,226],{"class":225},"s7eDp","\u002Fcost",[219,228,230],{"class":229},"sAwPA","       # total tokens used this session, in dollars\n",[219,232,234,236],{"class":221,"line":233},2,[219,235,196],{"class":225},[219,237,238],{"class":229},"    # breakdown: system prompt, CLAUDE.md, tools, conversation, files\n",[11,240,241,242,245],{},"For continuous visibility, configure the ",[15,243,244],{},"StatusLine"," to show the current token percentage as you work. Most people discover after one week of watching it that half their \"Claude is being weird\" complaints were really \"my context was at 90% full.\"",[11,247,248,249,252],{},"Drop this into ",[39,250,251],{},"~\u002F.claude\u002Fsettings.json"," (create it if it doesn't exist):",[210,254,258],{"className":255,"code":256,"language":257,"meta":215,"style":215},"language-json shiki shiki-themes github-light","{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"npx ccusage statusline\"\n  }\n}\n","json",[39,259,260,266,275,291,302,308],{"__ignoreMap":215},[219,261,262],{"class":221,"line":222},[219,263,265],{"class":264},"sgsFI","{\n",[219,267,268,272],{"class":221,"line":233},[219,269,271],{"class":270},"sYu0t","  \"statusLine\"",[219,273,274],{"class":264},": {\n",[219,276,278,281,284,288],{"class":221,"line":277},3,[219,279,280],{"class":270},"    \"type\"",[219,282,283],{"class":264},": ",[219,285,287],{"class":286},"sYBdl","\"command\"",[219,289,290],{"class":264},",\n",[219,292,294,297,299],{"class":221,"line":293},4,[219,295,296],{"class":270},"    \"command\"",[219,298,283],{"class":264},[219,300,301],{"class":286},"\"npx ccusage statusline\"\n",[219,303,305],{"class":221,"line":304},5,[219,306,307],{"class":264},"  }\n",[219,309,311],{"class":221,"line":310},6,[219,312,313],{"class":264},"}\n",[11,315,316,319],{},[39,317,318],{},"ccusage"," is a community tool that reads your session and prints tokens used, percentage of window, and cost. Any command that prints a single line to stdout works here — you can swap in your own script later.",[20,321,324,327,331,400,403,407,413,417,428,432,440,444,447],{"id":322,"title":323},"setup","Setup & Installation",[11,325,326],{},"Claude Code ships in five surfaces. They share the same underlying engine — pick based on where you already live.",[60,328,330],{"id":329},"terminal-the-primary-one","Terminal (the primary one)",[210,332,334],{"className":212,"code":333,"language":214,"meta":215,"style":215},"# macOS \u002F Linux\ncurl -fsSL https:\u002F\u002Fclaude.ai\u002Finstall.sh | sh\n\n# npm (any platform)\nnpm install -g @anthropic-ai\u002Fclaude-code\n\n# First run — will walk you through auth\nclaude\n",[39,335,336,341,359,365,370,384,388,394],{"__ignoreMap":215},[219,337,338],{"class":221,"line":222},[219,339,340],{"class":229},"# macOS \u002F Linux\n",[219,342,343,346,349,352,356],{"class":221,"line":233},[219,344,345],{"class":225},"curl",[219,347,348],{"class":270}," -fsSL",[219,350,351],{"class":286}," https:\u002F\u002Fclaude.ai\u002Finstall.sh",[219,353,355],{"class":354},"sD7c4"," |",[219,357,358],{"class":225}," sh\n",[219,360,361],{"class":221,"line":277},[219,362,364],{"emptyLinePlaceholder":363},true,"\n",[219,366,367],{"class":221,"line":293},[219,368,369],{"class":229},"# npm (any platform)\n",[219,371,372,375,378,381],{"class":221,"line":304},[219,373,374],{"class":225},"npm",[219,376,377],{"class":286}," install",[219,379,380],{"class":270}," -g",[219,382,383],{"class":286}," @anthropic-ai\u002Fclaude-code\n",[219,385,386],{"class":221,"line":310},[219,387,364],{"emptyLinePlaceholder":363},[219,389,391],{"class":221,"line":390},7,[219,392,393],{"class":229},"# First run — will walk you through auth\n",[219,395,397],{"class":221,"line":396},8,[219,398,399],{"class":225},"claude\n",[11,401,402],{},"On first run you'll be prompted to authenticate (browser OAuth or API key depending on your plan). The terminal CLI is the one every other surface is built on — features land here first.",[60,404,406],{"id":405},"vs-code-extension","VS Code extension",[11,408,409,410,412],{},"Install \"Claude Code\" from the Extensions marketplace. Opens a Claude panel inside VS Code with the same engine and settings as the CLI. The editor surface adds in-file diffs, inline diagnostics, and IDE-native approvals. Your ",[39,411,41],{},", settings, and skills apply identically.",[60,414,416],{"id":415},"desktop-app","Desktop app",[11,418,419,420,427],{},"A native Mac\u002FWindows app at ",[421,422,426],"a",{"href":423,"rel":424},"https:\u002F\u002Fclaude.ai\u002Fdownload",[425],"nofollow","claude.ai\u002Fdownload",". Same engine, but designed for people who don't live in a terminal. Useful for sharing Claude Code with non-CLI folks on your team.",[60,429,431],{"id":430},"web","Web",[11,433,434,439],{},[421,435,438],{"href":436,"rel":437},"https:\u002F\u002Fclaude.ai\u002Fcode",[425],"claude.ai\u002Fcode"," runs Claude Code in a cloud sandbox — no local install, spawns VM-isolated environments. Good for one-off tasks, reviewing PRs, and \"I'm on a Chromebook\" scenarios.",[60,441,443],{"id":442},"jetbrains","JetBrains",[11,445,446],{},"Plugin available for IntelliJ, WebStorm, PyCharm, GoLand, and the rest of the JetBrains family. Install from the Plugin Marketplace.",[52,448,450],{"title":449,"variant":55},"Start in the terminal",[11,451,452],{},"Even if you prefer VS Code, spend your first few days in the terminal. The CLI's feedback is more honest — you see exactly what commands it runs, what files it touches, and where context goes. Once you trust the loop, graduate to whichever surface suits your flow.",[20,454,457,462,476,480,483,520,529,533,564,568,585,589,595,733,736],{"id":455,"title":456},"claude-md","CLAUDE.md Deep Dive",[11,458,459,461],{},[39,460,41],{}," is your project's memory — a markdown file at the repo root that Claude loads into every session as system context. It's the difference between \"Claude who learned your codebase the hard way\" and \"Claude who already knows your conventions.\"",[52,463,465],{"title":464,"variant":190},"Keep it under 5,000 tokens",[11,466,467,468,470,471,475],{},"Every token in ",[39,469,41],{}," is consumed at the start of ",[472,473,474],"em",{},"every"," session. A 15K CLAUDE.md burns ~$0.05\u002Fsession before you've typed anything, and it eats context you need for actual work. Under 5K is the target. Under 3K is better.",[60,477,479],{"id":478},"the-whatwhyhow-framework","The WHAT–WHY–HOW framework",[11,481,482],{},"Good CLAUDE.md entries answer three questions in order:",[68,484,485,498,507],{},[71,486,487,490,491],{},[15,488,489],{},"WHAT"," — the rule. ",[472,492,493,494,497],{},"\"All API errors are thrown as typed exceptions from ",[39,495,496],{},"errors.ts",".\"",[71,499,500,503,504],{},[15,501,502],{},"WHY"," — the reason. ",[472,505,506],{},"\"So callers don't have to check status codes; the router catches and formats at the edge.\"",[71,508,509,512,513],{},[15,510,511],{},"HOW"," — the concrete application. ",[472,514,515,516,519],{},"\"Use ",[39,517,518],{},"throw new ApiError(...)","; don't return error objects from service functions.\"",[11,521,522,523,525,526,528],{},"Without the ",[15,524,502],{},", Claude follows the rule rigidly and fails on edge cases. Without the ",[15,527,511],{},", Claude agrees and does it wrong anyway. The combination gives it enough to judge unfamiliar situations.",[60,530,532],{"id":531},"what-belongs-in-claudemd","What belongs in CLAUDE.md",[68,534,535,538,541,544,551,554],{},[71,536,537],{},"The stack (languages, frameworks, major libraries)",[71,539,540],{},"How the repo is laid out (one-line per top-level folder)",[71,542,543],{},"Non-obvious conventions (error handling, state management, tests)",[71,545,546,547,550],{},"Hard rules (",[472,548,549],{},"\"never call X directly; always go through Y\"",")",[71,552,553],{},"Where to look for domain docs (referenced, not inlined)",[71,555,556,557,152,560,563],{},"The commands you'd run: ",[39,558,559],{},"npm run dev",[39,561,562],{},"npm test",", etc.",[60,565,567],{"id":566},"what-does-not-belong","What does NOT belong",[68,569,570,573,576,579,582],{},[71,571,572],{},"Full API references — link to the file instead",[71,574,575],{},"Examples Claude can derive by reading code",[71,577,578],{},"Anything that changes often (current sprint goals, in-progress work)",[71,580,581],{},"Full architecture diagrams in ASCII — one-sentence summaries, then link",[71,583,584],{},"Boilerplate like \"please be helpful\" — Claude already is",[60,586,588],{"id":587},"tiered-architecture","Tiered architecture",[11,590,591,592,594],{},"When your project is big enough that 5K isn't enough, go tiered. Keep ",[39,593,41],{}," small and point to deeper docs that load only when relevant:",[210,596,601],{"className":597,"code":598,"filename":599,"language":600,"meta":215,"style":215},"language-markdown shiki shiki-themes github-light","# Project: Shipping Platform\n\nNode.js + Fastify + Postgres. Strict TypeScript.\n\n## Conventions\n\n- All errors throw, never return. See `docs\u002Ferrors.md` when working with error handling.\n- Payments logic is sensitive — read `docs\u002Fpayments-architecture.md` before touching `src\u002Fpayments\u002F`.\n- Tests colocated with code: `foo.ts` and `foo.test.ts`.\n\n## Commands\n\n- `npm run dev` — local server\n- `npm test` — unit + integration\n- `npm run db:migrate` — apply new migrations\n","CLAUDE.md (abridged)","markdown",[39,602,603,609,613,618,622,627,631,646,665,684,689,695,700,711,722],{"__ignoreMap":215},[219,604,605],{"class":221,"line":222},[219,606,608],{"class":607},"surfw","# Project: Shipping Platform\n",[219,610,611],{"class":221,"line":233},[219,612,364],{"emptyLinePlaceholder":363},[219,614,615],{"class":221,"line":277},[219,616,617],{"class":264},"Node.js + Fastify + Postgres. Strict TypeScript.\n",[219,619,620],{"class":221,"line":293},[219,621,364],{"emptyLinePlaceholder":363},[219,623,624],{"class":221,"line":304},[219,625,626],{"class":607},"## Conventions\n",[219,628,629],{"class":221,"line":310},[219,630,364],{"emptyLinePlaceholder":363},[219,632,633,637,640,643],{"class":221,"line":390},[219,634,636],{"class":635},"sqxcx","-",[219,638,639],{"class":264}," All errors throw, never return. See ",[219,641,642],{"class":270},"`docs\u002Ferrors.md`",[219,644,645],{"class":264}," when working with error handling.\n",[219,647,648,650,653,656,659,662],{"class":221,"line":396},[219,649,636],{"class":635},[219,651,652],{"class":264}," Payments logic is sensitive — read ",[219,654,655],{"class":270},"`docs\u002Fpayments-architecture.md`",[219,657,658],{"class":264}," before touching ",[219,660,661],{"class":270},"`src\u002Fpayments\u002F`",[219,663,664],{"class":264},".\n",[219,666,668,670,673,676,679,682],{"class":221,"line":667},9,[219,669,636],{"class":635},[219,671,672],{"class":264}," Tests colocated with code: ",[219,674,675],{"class":270},"`foo.ts`",[219,677,678],{"class":264}," and ",[219,680,681],{"class":270},"`foo.test.ts`",[219,683,664],{"class":264},[219,685,687],{"class":221,"line":686},10,[219,688,364],{"emptyLinePlaceholder":363},[219,690,692],{"class":221,"line":691},11,[219,693,694],{"class":607},"## Commands\n",[219,696,698],{"class":221,"line":697},12,[219,699,364],{"emptyLinePlaceholder":363},[219,701,703,705,708],{"class":221,"line":702},13,[219,704,636],{"class":635},[219,706,707],{"class":270}," `npm run dev`",[219,709,710],{"class":264}," — local server\n",[219,712,714,716,719],{"class":221,"line":713},14,[219,715,636],{"class":635},[219,717,718],{"class":270}," `npm test`",[219,720,721],{"class":264}," — unit + integration\n",[219,723,725,727,730],{"class":221,"line":724},15,[219,726,636],{"class":635},[219,728,729],{"class":270}," `npm run db:migrate`",[219,731,732],{"class":264}," — apply new migrations\n",[11,734,735],{},"Claude reads the referenced files only when it needs to. A developer working on the frontend never pays the token cost of payment docs.",[52,737,739],{"title":738,"variant":55},"Personal vs project CLAUDE.md",[11,740,741,742,744,745,748],{},"There are two of these. Project ",[39,743,41],{}," lives in the repo root and applies only there. Personal ",[39,746,747],{},"~\u002F.claude\u002FCLAUDE.md"," applies across every project. Put preferences there (commit style, how you like to be addressed, verbosity preference) — don't pollute the project file with those.",[20,750,753,756,771,778,799,808,871,878,899,909,986,989,1018,1022,1034],{"id":751,"title":752},"hiding-files","Hiding Files from Claude",[11,754,755],{},"Claude Code has two official mechanisms for keeping files out of its reach, and knowing which to reach for saves a lot of \"why can Claude see my secrets\" moments.",[11,757,758,764,765,767,768,770],{},[15,759,760,763],{},[39,761,762],{},".claudeignore"," is not a real feature."," You'll see it referenced in community blog posts, npm packages, and PreToolUse-hook templates — it's a workaround people built, not something Anthropic ships. The authoritative surfaces are ",[39,766,45],{}," respect and ",[39,769,49],{},". Use those instead.",[60,772,774,775,777],{"id":773},"mechanism-1-gitignore-respect","Mechanism 1 — ",[39,776,45],{}," respect",[11,779,780,781,783,784,152,786,788,789,152,792,152,795,798],{},"Claude Code respects your ",[39,782,45],{}," for search-style operations. The effect: ",[39,785,155],{},[39,787,158],{},", and directory listings skip anything gitignored. For most projects this covers the noise automatically — ",[39,790,791],{},"node_modules\u002F",[39,793,794],{},"dist\u002F",[39,796,797],{},".next\u002F",", build artifacts, and log files are already gitignored, and Claude treats them as invisible to exploration tools.",[11,800,801,802,804,805,807],{},"The win here is passive. If your repo has a sane ",[39,803,45],{},", you've already done the single biggest thing to keep Claude's searches clean. The only action item is to glance at your ",[39,806,45],{}," once and make sure it covers build outputs and caches for your stack.",[210,809,814],{"className":810,"code":811,"filename":812,"language":813,"meta":215,"style":215},"language-plaintext shiki shiki-themes github-light","node_modules\u002F\nvendor\u002F\n.venv\u002F\ndist\u002F\nbuild\u002F\n.next\u002F\n.nuxt\u002F\n.output\u002F\n.cache\u002F\n*.log\n**\u002Fgenerated\u002F\n",".gitignore — the token-saving entries for most stacks","plaintext",[39,815,816,821,826,831,836,841,846,851,856,861,866],{"__ignoreMap":215},[219,817,818],{"class":221,"line":222},[219,819,820],{},"node_modules\u002F\n",[219,822,823],{"class":221,"line":233},[219,824,825],{},"vendor\u002F\n",[219,827,828],{"class":221,"line":277},[219,829,830],{},".venv\u002F\n",[219,832,833],{"class":221,"line":293},[219,834,835],{},"dist\u002F\n",[219,837,838],{"class":221,"line":304},[219,839,840],{},"build\u002F\n",[219,842,843],{"class":221,"line":310},[219,844,845],{},".next\u002F\n",[219,847,848],{"class":221,"line":390},[219,849,850],{},".nuxt\u002F\n",[219,852,853],{"class":221,"line":396},[219,854,855],{},".output\u002F\n",[219,857,858],{"class":221,"line":667},[219,859,860],{},".cache\u002F\n",[219,862,863],{"class":221,"line":686},[219,864,865],{},"*.log\n",[219,867,868],{"class":221,"line":691},[219,869,870],{},"**\u002Fgenerated\u002F\n",[60,872,874,875,877],{"id":873},"mechanism-2-permissionsdeny-for-sensitive-paths","Mechanism 2 — ",[39,876,49],{}," for sensitive paths",[11,879,880,882,883,886,887,890,891,894,895,898],{},[39,881,45],{}," cleans up noisy searches. It's the wrong tool for ",[15,884,885],{},"secrets",", because an explicit ",[39,888,889],{},"Read(.\u002F.env)"," can still slip through, and because you can't always gitignore what you want to hide — a ",[39,892,893],{},"notes\u002Fprivate\u002F"," folder you keep locally, a ",[39,896,897],{},"fixtures\u002Fcustomer-data\u002F"," directory you scrub before commit, credentials files you intentionally track.",[11,900,901,902,904,905,908],{},"For anything that should be strictly off-limits, use ",[39,903,49],{}," in ",[39,906,907],{},".claude\u002Fsettings.json",":",[210,910,912],{"className":255,"code":911,"filename":907,"language":257,"meta":215,"style":215},"{\n  \"permissions\": {\n    \"deny\": [\n      \"Read(.\u002F.env)\",\n      \"Read(.\u002F.env.*)\",\n      \"Read(.\u002Fnotes\u002Fprivate\u002F**)\",\n      \"Read(.\u002Ffixtures\u002Fcustomer-data\u002F**)\",\n      \"Bash(cat .env*)\",\n      \"Bash(cat **\u002Fid_rsa*)\"\n    ]\n  }\n}\n",[39,913,914,918,925,933,940,947,954,961,968,973,978,982],{"__ignoreMap":215},[219,915,916],{"class":221,"line":222},[219,917,265],{"class":264},[219,919,920,923],{"class":221,"line":233},[219,921,922],{"class":270},"  \"permissions\"",[219,924,274],{"class":264},[219,926,927,930],{"class":221,"line":277},[219,928,929],{"class":270},"    \"deny\"",[219,931,932],{"class":264},": [\n",[219,934,935,938],{"class":221,"line":293},[219,936,937],{"class":286},"      \"Read(.\u002F.env)\"",[219,939,290],{"class":264},[219,941,942,945],{"class":221,"line":304},[219,943,944],{"class":286},"      \"Read(.\u002F.env.*)\"",[219,946,290],{"class":264},[219,948,949,952],{"class":221,"line":310},[219,950,951],{"class":286},"      \"Read(.\u002Fnotes\u002Fprivate\u002F**)\"",[219,953,290],{"class":264},[219,955,956,959],{"class":221,"line":390},[219,957,958],{"class":286},"      \"Read(.\u002Ffixtures\u002Fcustomer-data\u002F**)\"",[219,960,290],{"class":264},[219,962,963,966],{"class":221,"line":396},[219,964,965],{"class":286},"      \"Bash(cat .env*)\"",[219,967,290],{"class":264},[219,969,970],{"class":221,"line":667},[219,971,972],{"class":286},"      \"Bash(cat **\u002Fid_rsa*)\"\n",[219,974,975],{"class":221,"line":686},[219,976,977],{"class":264},"    ]\n",[219,979,980],{"class":221,"line":691},[219,981,307],{"class":264},[219,983,984],{"class":221,"line":697},[219,985,313],{"class":264},[11,987,988],{},"Two things worth noticing:",[68,990,991,1008],{},[71,992,993,996,997,1000,1001,1003,1004,1007],{},[15,994,995],{},"Block the shell path too."," A clever Claude might try ",[39,998,999],{},"cat .env"," instead of ",[39,1002,889],{},". Denying the ",[39,1005,1006],{},"Bash(...)"," pattern closes that backdoor.",[71,1009,1010,1013,1014,1017],{},[15,1011,1012],{},"Paths are project-root relative."," ",[39,1015,1016],{},".\u002Fpath\u002F**"," is the convention — anchored to the project root, glob-expanded from there.",[60,1019,1021],{"id":1020},"when-to-use-which","When to use which",[11,1023,1024,1025,1027,1028,1030,1031,1033],{},"For noise you already gitignore, do nothing — ",[39,1026,45],{}," respect handles it. For secrets, credentials, and PII, use ",[39,1029,49],{}," plus a Bash-pattern deny for the shell surface. For large committed files you don't want re-read (generated docs, fixture dumps) — gitignore them if they're truly generated; ",[39,1032,151],{},"-deny them if they're committed intentionally but don't belong in context.",[52,1035,1037],{"title":1036,"variant":190},".claudeignore looks helpful. It isn't.",[11,1038,1039,1040,1042,1043,1046,1047,1049],{},"Community tooling has produced ",[39,1041,762],{}," npm packages and PreToolUse hooks that ",[472,1044,1045],{},"simulate"," the behavior. They work, roughly, for some setups. But they're not reading the same rules Claude itself reads — the authoritative surface is ",[39,1048,49],{},". Pick the documented path; you'll thank yourself the first time a workaround breaks on an upgrade.",[20,1051,1054,1057,1134,1295],{"id":1052,"title":1053},"config","Configuration Layers",[11,1055,1056],{},"Claude Code reads configuration from four places. Each overrides the one above it, so the most specific wins.",[1058,1059,1060,1076],"table",{},[1061,1062,1063],"thead",{},[1064,1065,1066,1070,1073],"tr",{},[1067,1068,1069],"th",{},"Layer",[1067,1071,1072],{},"Location",[1067,1074,1075],{},"What goes here",[1077,1078,1079,1092,1104,1117],"tbody",{},[1064,1080,1081,1085,1089],{},[1082,1083,1084],"td",{},"User defaults",[1082,1086,1087],{},[39,1088,251],{},[1082,1090,1091],{},"Your preferences across all projects — theme, default model, personal hooks, personal MCP servers",[1064,1093,1094,1097,1101],{},[1082,1095,1096],{},"Project settings",[1082,1098,1099],{},[39,1100,907],{},[1082,1102,1103],{},"Project rules the whole team shares — permissions, project-specific hooks, MCP servers",[1064,1105,1106,1109,1114],{},[1082,1107,1108],{},"Project local",[1082,1110,1111],{},[39,1112,1113],{},".claude\u002Fsettings.local.json",[1082,1115,1116],{},"Your local overrides for this project — gitignored, not shared",[1064,1118,1119,1122,1125],{},[1082,1120,1121],{},"CLI flags \u002F env",[1082,1123,1124],{},"on the command line",[1082,1126,1127,1128,152,1131],{},"One-off overrides: ",[39,1129,1130],{},"--model opus",[39,1132,1133],{},"DEBUG=true claude",[210,1135,1137],{"className":255,"code":1136,"filename":907,"language":257,"meta":215,"style":215},"{\n  \"model\": \"sonnet\",\n  \"permissions\": {\n    \"allow\": [\"Bash(npm test)\", \"Bash(npm run lint)\", \"Read\"],\n    \"deny\": [\"Bash(rm -rf *)\", \"Bash(git push --force*)\"],\n    \"ask\": [\"Bash(git push*)\"]\n  },\n  \"hooks\": {\n    \"PostToolUse\": [\n      {\n        \"matcher\": \"Edit|Write\",\n        \"hooks\": [{ \"type\": \"command\", \"command\": \"npx prettier --write $CLAUDE_FILE_PATHS\" }]\n      }\n    ]\n  }\n}\n",[39,1138,1139,1143,1155,1161,1185,1201,1214,1219,1226,1233,1238,1250,1277,1282,1286,1290],{"__ignoreMap":215},[219,1140,1141],{"class":221,"line":222},[219,1142,265],{"class":264},[219,1144,1145,1148,1150,1153],{"class":221,"line":233},[219,1146,1147],{"class":270},"  \"model\"",[219,1149,283],{"class":264},[219,1151,1152],{"class":286},"\"sonnet\"",[219,1154,290],{"class":264},[219,1156,1157,1159],{"class":221,"line":277},[219,1158,922],{"class":270},[219,1160,274],{"class":264},[219,1162,1163,1166,1169,1172,1174,1177,1179,1182],{"class":221,"line":293},[219,1164,1165],{"class":270},"    \"allow\"",[219,1167,1168],{"class":264},": [",[219,1170,1171],{"class":286},"\"Bash(npm test)\"",[219,1173,152],{"class":264},[219,1175,1176],{"class":286},"\"Bash(npm run lint)\"",[219,1178,152],{"class":264},[219,1180,1181],{"class":286},"\"Read\"",[219,1183,1184],{"class":264},"],\n",[219,1186,1187,1189,1191,1194,1196,1199],{"class":221,"line":304},[219,1188,929],{"class":270},[219,1190,1168],{"class":264},[219,1192,1193],{"class":286},"\"Bash(rm -rf *)\"",[219,1195,152],{"class":264},[219,1197,1198],{"class":286},"\"Bash(git push --force*)\"",[219,1200,1184],{"class":264},[219,1202,1203,1206,1208,1211],{"class":221,"line":310},[219,1204,1205],{"class":270},"    \"ask\"",[219,1207,1168],{"class":264},[219,1209,1210],{"class":286},"\"Bash(git push*)\"",[219,1212,1213],{"class":264},"]\n",[219,1215,1216],{"class":221,"line":390},[219,1217,1218],{"class":264},"  },\n",[219,1220,1221,1224],{"class":221,"line":396},[219,1222,1223],{"class":270},"  \"hooks\"",[219,1225,274],{"class":264},[219,1227,1228,1231],{"class":221,"line":667},[219,1229,1230],{"class":270},"    \"PostToolUse\"",[219,1232,932],{"class":264},[219,1234,1235],{"class":221,"line":686},[219,1236,1237],{"class":264},"      {\n",[219,1239,1240,1243,1245,1248],{"class":221,"line":691},[219,1241,1242],{"class":270},"        \"matcher\"",[219,1244,283],{"class":264},[219,1246,1247],{"class":286},"\"Edit|Write\"",[219,1249,290],{"class":264},[219,1251,1252,1255,1258,1261,1263,1265,1267,1269,1271,1274],{"class":221,"line":697},[219,1253,1254],{"class":270},"        \"hooks\"",[219,1256,1257],{"class":264},": [{ ",[219,1259,1260],{"class":270},"\"type\"",[219,1262,283],{"class":264},[219,1264,287],{"class":286},[219,1266,152],{"class":264},[219,1268,287],{"class":270},[219,1270,283],{"class":264},[219,1272,1273],{"class":286},"\"npx prettier --write $CLAUDE_FILE_PATHS\"",[219,1275,1276],{"class":264}," }]\n",[219,1278,1279],{"class":221,"line":702},[219,1280,1281],{"class":264},"      }\n",[219,1283,1284],{"class":221,"line":713},[219,1285,977],{"class":264},[219,1287,1288],{"class":221,"line":724},[219,1289,307],{"class":264},[219,1291,1293],{"class":221,"line":1292},16,[219,1294,313],{"class":264},[52,1296,1298],{"title":1297,"variant":125},"Check it in",[11,1299,1300,1302,1303,1306],{},[39,1301,907],{}," should be committed. It encodes how your team agrees Claude should behave on this project. Put personal adjustments in ",[39,1304,1305],{},"settings.local.json"," (gitignored).",[20,1308,1311,1314,1370,1388],{"id":1309,"title":1310},"models","Models",[11,1312,1313],{},"Claude Code supports three model tiers. Knowing when to reach for each is worth 40% on your bill.",[1058,1315,1316,1329],{},[1061,1317,1318],{},[1064,1319,1320,1323,1326],{},[1067,1321,1322],{},"Model",[1067,1324,1325],{},"Sweet spot",[1067,1327,1328],{},"Avoid for",[1077,1330,1331,1344,1357],{},[1064,1332,1333,1338,1341],{},[1082,1334,1335],{},[15,1336,1337],{},"Opus 4.7",[1082,1339,1340],{},"Architecture decisions, security reviews, multi-file refactors, ambiguous problems",[1082,1342,1343],{},"Rote work — it's expensive, and Sonnet handles it fine",[1064,1345,1346,1351,1354],{},[1082,1347,1348],{},[15,1349,1350],{},"Sonnet 4.6",[1082,1352,1353],{},"Day-to-day implementation, bug fixes, feature work, test writing",[1082,1355,1356],{},"Novel architectural calls where judgment matters",[1064,1358,1359,1364,1367],{},[1082,1360,1361],{},[15,1362,1363],{},"Haiku 4.5",[1082,1365,1366],{},"Fast exploration, linting, simple transformations, subagent tasks",[1082,1368,1369],{},"Anything requiring judgment on tradeoffs",[52,1371,1373],{"title":1372,"variant":55},"The hybrid pattern",[11,1374,1375,1376,1379,1380,1383,1384,1387],{},"Use Opus for the ",[15,1377,1378],{},"plan"," and Sonnet for the ",[15,1381,1382],{},"implementation",". Opus makes the architectural calls in Plan Mode (cheap — just text), then you switch to Sonnet with ",[39,1385,1386],{},"\u002Fmodel sonnet"," for the execution phase. You get Opus-level judgment at Sonnet-level cost.",[11,1389,1390,1391,1394],{},"Default model depends on your plan. Free users get Haiku. Pro gets Sonnet. Max gets Opus by default. You can always switch mid-session with ",[39,1392,1393],{},"\u002Fmodel",".",[20,1396,1399,1402,1406,1434,1445,1449,1455,1610],{"id":1397,"title":1398},"safety","Permissions & Safety",[11,1400,1401],{},"Claude Code ships with sandboxing enabled. By default, every tool call that could modify your system (shell commands, file writes) requires approval the first time Claude tries it in a session. This is slow but safe. As you gain confidence, tune the permissions.",[60,1403,1405],{"id":1404},"the-three-permission-modes","The three permission modes",[68,1407,1408,1414,1424],{},[71,1409,1410,1413],{},[15,1411,1412],{},"Ask"," (default) — Claude pauses and asks before running anything it hasn't run before",[71,1415,1416,1419,1420,1423],{},[15,1417,1418],{},"Allowlist"," — you pre-approve patterns in ",[39,1421,1422],{},"settings.json","; Claude proceeds without asking for those",[71,1425,1426,1429,1430,1433],{},[15,1427,1428],{},"Skip all"," — ",[39,1431,1432],{},"--dangerously-skip-permissions","; Claude never asks. Use only in isolated environments",[52,1435,1438],{"title":1436,"variant":1437},"--dangerously-skip-permissions is named that for a reason","danger",[11,1439,1440,1441,1444],{},"Never run it against your main development machine. Use it in containers, VMs, or dedicated worktrees — anywhere a bad ",[39,1442,1443],{},"rm"," wouldn't ruin your day. The Docker image and cloud sandbox surfaces enable it safely because blast radius is contained.",[60,1446,1448],{"id":1447},"the-allow-deny-ask-lists","The allow \u002F deny \u002F ask lists",[11,1450,1451,1452,1454],{},"In ",[39,1453,907],{}," you can pre-approve or pre-block patterns. A good starting set for most projects:",[210,1456,1459],{"className":255,"code":1457,"filename":1458,"language":257,"meta":215,"style":215},"{\n  \"permissions\": {\n    \"allow\": [\n      \"Read\",\n      \"Glob\",\n      \"Grep\",\n      \"Bash(npm run lint)\",\n      \"Bash(npm test*)\",\n      \"Bash(git status)\",\n      \"Bash(git diff*)\",\n      \"Bash(git log*)\"\n    ],\n    \"ask\": [\n      \"Bash(git push*)\",\n      \"Bash(git checkout*)\",\n      \"Write\"\n    ],\n    \"deny\": [\n      \"Bash(rm -rf*)\",\n      \"Bash(git push --force*)\",\n      \"Bash(git reset --hard*)\"\n    ]\n  }\n}\n","settings.json permissions",[39,1460,1461,1465,1471,1477,1484,1491,1498,1505,1512,1519,1526,1531,1536,1542,1549,1556,1561,1566,1573,1581,1589,1595,1600,1605],{"__ignoreMap":215},[219,1462,1463],{"class":221,"line":222},[219,1464,265],{"class":264},[219,1466,1467,1469],{"class":221,"line":233},[219,1468,922],{"class":270},[219,1470,274],{"class":264},[219,1472,1473,1475],{"class":221,"line":277},[219,1474,1165],{"class":270},[219,1476,932],{"class":264},[219,1478,1479,1482],{"class":221,"line":293},[219,1480,1481],{"class":286},"      \"Read\"",[219,1483,290],{"class":264},[219,1485,1486,1489],{"class":221,"line":304},[219,1487,1488],{"class":286},"      \"Glob\"",[219,1490,290],{"class":264},[219,1492,1493,1496],{"class":221,"line":310},[219,1494,1495],{"class":286},"      \"Grep\"",[219,1497,290],{"class":264},[219,1499,1500,1503],{"class":221,"line":390},[219,1501,1502],{"class":286},"      \"Bash(npm run lint)\"",[219,1504,290],{"class":264},[219,1506,1507,1510],{"class":221,"line":396},[219,1508,1509],{"class":286},"      \"Bash(npm test*)\"",[219,1511,290],{"class":264},[219,1513,1514,1517],{"class":221,"line":667},[219,1515,1516],{"class":286},"      \"Bash(git status)\"",[219,1518,290],{"class":264},[219,1520,1521,1524],{"class":221,"line":686},[219,1522,1523],{"class":286},"      \"Bash(git diff*)\"",[219,1525,290],{"class":264},[219,1527,1528],{"class":221,"line":691},[219,1529,1530],{"class":286},"      \"Bash(git log*)\"\n",[219,1532,1533],{"class":221,"line":697},[219,1534,1535],{"class":264},"    ],\n",[219,1537,1538,1540],{"class":221,"line":702},[219,1539,1205],{"class":270},[219,1541,932],{"class":264},[219,1543,1544,1547],{"class":221,"line":713},[219,1545,1546],{"class":286},"      \"Bash(git push*)\"",[219,1548,290],{"class":264},[219,1550,1551,1554],{"class":221,"line":724},[219,1552,1553],{"class":286},"      \"Bash(git checkout*)\"",[219,1555,290],{"class":264},[219,1557,1558],{"class":221,"line":1292},[219,1559,1560],{"class":286},"      \"Write\"\n",[219,1562,1564],{"class":221,"line":1563},17,[219,1565,1535],{"class":264},[219,1567,1569,1571],{"class":221,"line":1568},18,[219,1570,929],{"class":270},[219,1572,932],{"class":264},[219,1574,1576,1579],{"class":221,"line":1575},19,[219,1577,1578],{"class":286},"      \"Bash(rm -rf*)\"",[219,1580,290],{"class":264},[219,1582,1584,1587],{"class":221,"line":1583},20,[219,1585,1586],{"class":286},"      \"Bash(git push --force*)\"",[219,1588,290],{"class":264},[219,1590,1592],{"class":221,"line":1591},21,[219,1593,1594],{"class":286},"      \"Bash(git reset --hard*)\"\n",[219,1596,1598],{"class":221,"line":1597},22,[219,1599,977],{"class":264},[219,1601,1603],{"class":221,"line":1602},23,[219,1604,307],{"class":264},[219,1606,1608],{"class":221,"line":1607},24,[219,1609,313],{"class":264},[52,1611,1613],{"title":1612,"variant":55},"Let experience shape it",[11,1614,1615,1616,1619],{},"Start strict — only pre-approve read-only tools. Each time a safe command gets prompted and you approve it, consider whether it belongs in ",[39,1617,1618],{},"allow",". After a week, your permissions are shaped to how you actually work, and you almost never see prompts.",[1621,1622,1623],"style",{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .surfw, html code.shiki .surfw{--shiki-default:#005CC5;--shiki-default-font-weight:bold}html pre.shiki code .sqxcx, html code.shiki .sqxcx{--shiki-default:#E36209}",{"title":215,"searchDepth":233,"depth":233,"links":1625},[1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1640,1642,1643,1644],{"id":62,"depth":277,"text":63},{"id":144,"depth":277,"text":145},{"id":204,"depth":277,"text":205},{"id":329,"depth":277,"text":330},{"id":405,"depth":277,"text":406},{"id":415,"depth":277,"text":416},{"id":430,"depth":277,"text":431},{"id":442,"depth":277,"text":443},{"id":478,"depth":277,"text":479},{"id":531,"depth":277,"text":532},{"id":566,"depth":277,"text":567},{"id":587,"depth":277,"text":588},{"id":773,"depth":277,"text":1639},"Mechanism 1 — .gitignore respect",{"id":873,"depth":277,"text":1641},"Mechanism 2 — permissions.deny for sensitive paths",{"id":1020,"depth":277,"text":1021},{"id":1404,"depth":277,"text":1405},{"id":1447,"depth":277,"text":1448},"The mental model, how the harness actually works, and the configuration layers you'll touch in your first week. Every other section assumes the ideas here.","25 min","md","Start here","LucideBookOpen",null,{},{"title":1653,"path":1654},"Workflows","\u002Fworkflows","\u002Ffoundations",{"title":1657,"description":1658,"keywords":1659,"proficiencyLevel":1668,"timeRequired":1669},"Foundations — Mental Model & Setup for Claude Code","The mindset shift, how the Claude Code harness works, the context window, setup, CLAUDE.md, file-hiding rules, configuration layers, models, and permissions — everything you need before writing your first prompt.",[1660,1661,1662,1663,1664,1665,1666,1667],"claude code foundations","claude md","permissions deny","context window","claude code setup","claude models","permissions","mental model","Beginner","PT25M",[1671,1672,1673,1674,1675,1676,1677,1678,1679],{"id":22,"title":23,"level":233},{"id":99,"title":100,"level":233},{"id":179,"title":180,"level":233},{"id":322,"title":323,"level":233},{"id":455,"title":456,"level":233},{"id":751,"title":752,"level":233},{"id":1052,"title":1053,"level":233},{"id":1309,"title":1310,"level":233},{"id":1397,"title":1398,"level":233},"lsO0U98enbsFKoylndBOv8ZfwmNjtTA6L_JDki9F1_g",1777109528355]