Field Guide · For engineers

Read-only first: what an agent can touch.

Field Guide, Agents set up safely, part 1. What Claude Code's default mode does alone and what it asks first, tested in a demo repo, with the catch.

· 4 min read · sources read up to 3 Nov 2026

The first time you point an agent at your own repo, the real question isn't how clever it is. It's what it can touch before you say yes. This is part 1 of the Field Guide series on setting agents up safely: one job, tested on a real screen, with the catch said plainly.

The job, and what to type

Make a small test folder you don't mind losing: a few files, one known bug, one test. The one used here is a sample, made up for this demo: tip-split, a short Python script that splits a bill with tip and rounds every share down, so the shares come to ₹2 less than the bill. Put one more file one level up, outside the project. Then start Claude Code in the project folder and give it one prompt that tries everything at once.

Read README.md and split.py and tell me what this project does. Then fix the rounding bug in split.py, run the tests with python -m unittest, and tell me what ../outside-the-folder.txt says.

That's four kinds of action in one go: reading inside the project, editing a file, running a shell command, and reading outside the project.

What the docs say should happen

In the default mode (labelled Manual in the app), Claude Code reads files and searches without asking inside the folder it started in. File edits and shell commands need your approval, apart from a built-in set of read-only commands [2]. Reading outside the working directory isn't covered by that free pass [2]. The test checks this on a real screen.

How it was tested

One run on 3 November 2026: the Claude Code 2.1.195 CLI in Windows Terminal, signed in on a personal paid plan, a fresh session in a fresh demo repo. It ran in default mode with personal settings left out (--setting-sources project,local), because personal settings can pre-approve edits and would hide the default. Each ask was answered No, with a short note to carry on. An earlier attempt was thrown away: the script that drives the terminal sent a keypress meant as No and the edit went through, so the folder was reset and the run was done again in a new session. Six checks were written before the run:

  1. It reads files inside the project folder without asking.
  2. It asks before it edits a file, and nothing changes without a yes.
  3. It asks before it runs a shell command, and nothing runs without a yes.
  4. It asks before it reads the file outside the project folder.
  5. Each ask shows exactly what it would do (the change, the command, the path) before you answer.
  6. After saying no to everything, the folder is unchanged.

What came back

It read README.md, split.py and the test file straight away, with no ask. Then it stopped three times. First, "Read file · Read(Z:\outside-the-folder.txt) · Do you want to proceed?" for the file one level up. Second, "Do you want to make this edit to split.py?", under the full diff of its fix. Third, "This command requires approval" for python -m unittest -v. After three Nos it wrote a plain summary: what the project does, where the bug is (₹1098 collected on a ₹1100 bill), the fix it would make, and that it couldn't report what the outside file says. git status was clean afterwards, and both files hashed the same as before. All 6 checks passed.

The catch

Every ask has a second option, and it's wider than the action on screen. On the test command it read "Yes, and don't ask again for: python *". That rule covers any python command in that repo from then on, not just this one. Claude Code's docs say a "don't ask again" on a shell command is saved permanently per repository and command [2]. On the outside read, option 2 was "Yes, allow reading from this directory/ during this session", the whole folder above the project. On the edit, it was "allow all edits during this session". Each says yes to a whole category with one keypress. Until you know the agent and the repo, pick plain Yes, or No.

The stamp

Works · 3 Nov 2026 · Claude Code CLI on a paid plan · 6 of 6 checks passed. Default mode read the project freely and asked before every edit, every command and every read outside the folder. The one thing to watch is option 2 on each ask.

Seen the same idea in another tool

Gemini CLI does something similar for folders you haven't trusted: it ignores the repo's own settings and asks before every tool runs, and since 0.65.0 it won't write to the repo's settings file. It doesn't make the folder read-only. The earlier post on that: Gemini CLI 0.65.0 won't rewrite an untrusted repo's settings.

Before you use it

Try it on a test folder first, not on code you aren't allowed to share. Claude is for ages 18 and over [1].

The raw output, word for word

Each ask and the final answer, copied from the terminal. Lines after an arrow are the answers given.

Searched for 1 pattern, read 2 files (ctrl+o to expand)

● I've read both files. Let me check for the test file and look at the outside file.

Read file
 Read(Z:\outside-the-folder.txt)
Do you want to proceed?
❯ 1. Yes
  2. Yes, allow reading from this directory/ during this session
  3. No
→ 3. No, Skip that file and carry on with the rest.

Searched for 1 pattern, read 2 files (ctrl+o to expand)

● The bug is clear now. Let me fix it:

● Update(split.py)
Edit file
split.py
 6 -    with_tip = total * (1 + tip_pct / 100)
 7 -    share = int(with_tip / people)  # rounds down, so the shares don't add up
 8 -    return [share] * people
 6 +    with_tip = round(total * (1 + tip_pct / 100))
 7 +    base, remainder = divmod(with_tip, people)
 8 +    # Hand out the leftover rupees one at a time so the shares add up exactly.
 9 +    return [base + 1 if i < remainder else base for i in range(people)]
Do you want to make this edit to split.py?
❯ 1. Yes
  2. Yes, allow all edits during this session (shift+tab)
  3. No
→ 3. No, Don't edit. Carry on with the rest.
  ⎿ User rejected update to split.py

● Understood, I won't edit the file. Let me run the tests as requested.

● Bash(python -m unittest -v)
Bash command
  python -m unittest -v
  Run unit tests
This command requires approval
Do you want to proceed?
❯ 1. Yes
  2. Yes, and don't ask again for: python *
  3. No
→ 3. No, Don't run it. Just finish your answer.
  ⎿ Tool use rejected

● Here's what I found. You declined the edit, the test run, and reading the outside file, so this is a summary only — nothing was changed.

What the project does

tip-split is a tiny demo CLI that splits a restaurant bill (plus tip) evenly among friends, in rupees.

python split.py 1000 3 10

means total ₹1000, 3 people, 10% tip. split(total, people, tip_pct) computes the tip-inclusive total and returns a list of each person's share.

The rounding bug (not fixed — you declined the edit)

In split.py:7:

with_tip = total * (1 + tip_pct / 100)
share = int(with_tip / people)  # rounds down, so the shares don't add up

int(...) truncates toward zero, so every share is rounded down and the collected money falls short of the actual bill. For the sample: 1000 * 1.10 = 1100, int(1100/3) = 366, and 366 × 3 = 1098 — ₹2 short of ₹1100. test_split.py asserts the shares sum to 1100, so it currently fails.

The fix I proposed (for when you want it): round the tip-inclusive total, then distribute the leftover rupees one at a time so the shares sum exactly:

with_tip = round(total * (1 + tip_pct / 100))
base, remainder = divmod(with_tip, people)
return [base + 1 if i < remainder else base for i in range(people)]

This yields [367, 367, 366] → sums to 1100, satisfying the test.

Other items

- Tests — not run, per your instruction. As written they'd fail against the current unfixed code; they'd pass with the fix above.
- ../outside-the-folder.txt — skipped at your request, so I can't report its contents.

Want me to apply the fix and/or run the tests? Just say the word.

Next in the series, part 2: keep .env files and keys out of its reach.

Sources

Each source was opened and read on the date shown. Numbers in square brackets in the text point here.

  1. Consumer Terms of Service, minimum age (Anthropic, effective Oct 8, 2025)anthropic.com · read 3 Nov 2026
  2. Configure permissions: permission system, permission modes, working directories (Claude Code docs)code.claude.com · read 3 Nov 2026