Your first session with a coding agent
In this lesson we run one complete session with a coding agent. We open it in a small repository and ask it to explain the code. We point it at a failing test and let it make one change. Then we read the diff before we accept it. The repository is a fixture that ships with this course, so nothing you do here can touch your own work.
A coding agent is an agent that works in your terminal or editor with the tools a programmer has: it reads and edits files, and it runs commands. Claude Code is one example; there are others, and this lesson uses none of their specific features. Wherever it says “your coding agent”, use the one you have installed. If yours is Claude Code, the vendor’s own short course covers installing it and the commands this lesson leaves out, so read it after this lesson [1]. If you get stuck, the site’s tutor can give you hints on this lesson inside your own agent. How to study with the tutor explains the setup.
The fixture
Section titled “The fixture”The fixture is a to-do list command in about seventy lines of Python. It
lives in the course repository under
site/examples/coding-with-agents/first-session/fixture-repo/. Copy that
directory somewhere, or work in a clone of the course repository; either
way, git checkout -- . inside it puts every file back the way it was. Expect
to reset it at least once.
Inside are five files: todo.py, the program; test_todo.py, its
tests; todos.json, a committed list of three items; README.md; and
AGENTS.md, four lines of instructions for the agent. Change into the
directory, then run the program before you run the agent. You want to know
what “working” looks like before someone else changes it.
The program needs Python 3.9 or newer and nothing else. On a Mac, the
python3 that comes with the system is enough. On a fresh Mac the first
python3 command may open a dialog from Apple offering to install its
developer tools for the terminal (the Xcode Command Line Tools). Accept it,
wait for the install to finish, and run the command again.
Show the list
Section titled “Show the list”Run this, and compare what you see with the output below.
python3 todo.py list1. [ ] Buy milk 2. [x] Call the plumber 3. [ ] Water the plants
Output verified in CI from site/examples/coding-with-agents/first-session/list.py.
The examples in this lesson aren’t graded. Each one is a command you run in the fixture, with the output the course itself checks on every build. The checkpoints come later, and they ask about the session, because working with the agent is what this lesson teaches.
Start the agent and ask it to explain
Section titled “Start the agent and ask it to explain”Start your coding agent from inside fixture-repo. The directory you start
in is the agent’s world: it reads and edits files there, and it runs
commands there. Starting one level too high hands it your whole home directory.
Your first message isn’t a task. It is a question, and its purpose is to check that the agent is looking at the same code you are.
Explain what this repository does and how the pieces fit together. Don’t change anything.
This is a small command-line to-do list. todo.py stores items in
todos.json (or the file named by TODO_FILE) and offers three commands:
add, list and done. test_todo.py covers the three operations with
unittest. AGENTS.md asks for standard library only and says not to edit
todos.json. The done function takes a 1-based item number from the
command line but indexes the list with it directly, which looks like an
off-by-one.
The transcripts in this lesson are illustrative: they show what a good exchange looks like and don’t record a specific model’s words. Your agent phrases things differently, and may or may not spot the off-by-one unprompted. Either is fine, because you are about to hand it the evidence.
Notice what the agent read without being asked: AGENTS.md. Most coding
agents load a project-instructions file at start. The lines in that file
set the rules for the whole session, and you didn’t have to repeat them.
Many coding agents have a read-only mode, often called plan mode, in which the agent reads, searches and runs commands to explore, but edits nothing. It suits this first question. You get the explanation, and the agent doesn’t act on it before you have checked it [1].
Find the evidence yourself
Section titled “Find the evidence yourself”Before you ask for a fix, see the failure with your own eyes. It takes ten seconds, and it gives you something exact to point at.
Run the tests
Section titled “Run the tests”Run the tests and keep only the last line of the output.
python3 -m unittest -q 2>&1 | tail -1FAILED (failures=1)
Output verified in CI from site/examples/coding-with-agents/first-session/tests.py.
Read the failing test. test_done_marks_the_numbered_item calls
todo.done(items, 1) and expects "done #1: Buy milk". The program says
something else. Prove it against the committed list, on a copy so the
committed file doesn’t change.
Prove the bug
Section titled “Prove the bug”Mark item 1 as done on a copy of the list. The program answers with the item it marked.
cp todos.json /tmp/todos.jsonTODO_FILE=/tmp/todos.json python3 todo.py done 1done #1: Call the plumber
Output verified in CI from site/examples/coding-with-agents/first-session/done_bug.py.
Item 1 is “Buy milk”, and the program marked “Call the plumber”. The function takes the number you typed and uses it as the list index without subtracting one.
You now have concrete evidence: the file with the bug, the failing test, and the wrong output. That’s the context the agent needs. A brief without them makes the agent go and find them, and it may find something else instead. The hunt has a cost of its own: every file the agent opens while searching stays in the session’s memory. So a short brief ends up using more of that memory than a precise one [1].
Give the right context
Section titled “Give the right context”Think back to the brief you wrote in Delegating a task to an agent: goal, context, limits, done-criteria. For a coding agent the context is files and commands, the limits are which files it may touch, and the done-criterion is usually a test.
Before you write it, decide what belongs in it. Some of the evidence you gathered is exactly what the agent needs. Some of it the agent reads faster than you can type it, and some of it has nothing to do with the task.
What goes in the brief?
Section titled “What goes in the brief?”A learner is about to brief a coding agent to fix an off-by-one bug in a small Python to-do program. A failing unit test already shows the bug, and the project has a short AGENTS.md file that the agent loads at start.
Ask whether the agent needs it for this task, and whether it can get it faster than you can type it.
Brief, agent, or neither?
Section titled “Brief, agent, or neither?”A learner is about to brief a coding agent to fix a bug that a failing unit test shows, in a small project with a short AGENTS.md file that the agent loads at start.
Match each item to where it comes from.
Can the agent read this in the repository, does only you know it, or does the task not need it?
Fix the brief
Section titled “Fix the brief”This brief sends the agent hunting. Rewrite it so it names the file, the failing test, what the agent may and may not change, and how you know it is done.
Fix the off-by-one in the done() function in todo.py: "done 1" currently marks the second item. The failing test is test_done_marks_the_numbered_item in test_todo.py; make it pass without changing the test. Only edit todo.py. Do not touch todos.json. Done when python3 -m unittest -q reports OK.
If you handed this to a colleague who had never seen the repository, what would they have to go and find out first?
The first change and the permissions prompt
Section titled “The first change and the permissions prompt”Send your repaired brief. The agent reads todo.py, proposes an edit,
and stops. Before it writes the file it asks you.
Fix the off-by-one in done() in todo.py: done 1 marks the
second item. The failing test is test_done_marks_the_numbered_item in
test_todo.py. Make it pass without changing the test. Only edit
todo.py. Don’t touch todos.json. Done when python3 -m unittest -q
reports OK.
The bug is on the first line of done(): index = number should be
index = number - 1. The bounds check below it already assumes a
zero-based index, so it doesn’t need to change.
I would like to edit todo.py (1 line). Allow?
That question is the permissions prompt. In the mode this lesson uses, a
coding agent asks before it edits a file or runs a command that does more
than read, and the answer is where your judgment enters the session. Ask
about blast radius, as you did in Why agent safety is different: a
one-line edit to a file you can
git checkout is about as small as a blast radius gets. Approve it.
Some agents offer to stop asking for the rest of the session. Decline that for now. The prompt is the pause in which you read what’s about to happen, and this lesson is about building the habit of reading.
The agent asks for a different file
Section titled “The agent asks for a different file”A learner briefed a coding agent to fix a bug in todo.py, a small Python to-do program. The brief and the project's AGENTS.md both say the agent must not touch todos.json, the data file. The agent stops at the permissions prompt before every edit.
You send the repaired brief. The agent reads todo.py and test_todo.py,
and then asks: “I would like to edit todos.json to mark item 2 as not
done, so the test passes. Allow?” The brief said not to touch todos.json,
and so does AGENTS.md. What do you do?
Which document already answered this question before the agent asked it?
Permission modes
Section titled “Permission modes”The prompt you just answered is one setting of a wider control. Most coding agents let you choose, at the start of a session or during it, how much the agent may do without asking. The names differ from one agent to the next, and the set of choices is much the same [2].
- Read-only. The agent reads files, searches, and runs commands to explore, and it edits nothing. It proposes changes and you decide what happens next. Whether a command that does more than read stops for a prompt in this mode depends on the agent. This is the plan mode from the start of this lesson.
- Ask before each action. The mode you have used so far. Each edit stops for your answer, and so does each command, apart from a built-in set that only reads. You saw that set at work during the explain step, when the agent read files and searched without asking.
- Accept edits, ask before commands. Edits to files inside the working directory go through without a prompt, and so do common file-management commands on paths in that directory. In Claude Code that set includes deleting a file and editing one in place with a stream editor, so “accept edits” covers more than typing into a file. Other commands still stop and ask [3].
- Skip every check. The agent edits and runs whatever it decides to, and you find out afterwards.
Some agents add modes between the last two, such as a list of commands you approved in advance that runs without a prompt, or an automatic check that reviews each action against your request in place of you. Before you use one, read what your agent’s documentation says it still asks about. Check which mode your agent starts in, too. In Claude Code that depends on your plan, on whether you run it in a terminal, an editor or the browser, and on your settings, and it has changed between versions [3].
Each mode sets how much the agent can do before you get a chance to say
no. In read-only mode that is what the agent reads, so the worst case is
that it repeats something it should not have seen. With the prompt on, it
is one action: the edit or command you approved. Accepting edits widens it
to every file in the working directory. That is acceptable in a repository
under version control because git diff shows you what changed and
git checkout -- . puts tracked files back, and the next section makes
that review the habit. Know the limit of that reset: a file the agent
deleted that was never committed does not come back. Skipping every check
widens it to everything the shell can reach, which on your own machine is
every file you own, as Why agent safety is different put it. Use that
mode only inside a sandbox, meaning a container or virtual machine made
for the session, without internet access and with nothing in it you would
miss, and put no credentials in it. The vendor documentation says the same
about isolation and internet access [3].
Pick the mode per task, the way you sized the brief. A question or a plan asks for read-only. A first change in a project, or any change in a project you do not know, keeps the prompt on, because the prompt is where you learn how this agent behaves in this code. A change of a kind you have reviewed before, in a working tree that git can restore, can accept edits, and then you read the whole diff at the end where you would have read each prompt. The mode decides how much you see before it happens. It says nothing about how well the agent behaves.
Which mode for the change?
Section titled “Which mode for the change?”A learner has finished the bug fix in the fixture with the permissions prompt on and has read every diff. A colleague now asks them to fix one small bug in a different project, which the learner has never opened before. The repository is on the learner's own laptop, next to their other work, and its working tree is committed clean. The learner started the session in read-only mode, asked the agent to explain the bug, and the agent has proposed a one-line fix. The coding agent offers four modes: read-only, ask before each action, accept edits and ask before commands, and skip every check.
A colleague asks you to fix a small bug in a project you have never opened.
The repository is on your laptop, next to your other work, and git status
shows a clean tree. You started in read-only mode and asked the agent to
explain the bug, and it has proposed a one-line fix. Which mode do you
switch to for making the change?
How do you find out how an agent behaves in a project you have never worked in, and what could go wrong on this machine while you find out?
Review the diff
Section titled “Review the diff”The agent says it is done. It may even say the tests pass. Don’t take its word for either. Look at what changed.
git diffindex = numberindex = number - 1Then run the check you named in the brief. The done-criterion was yours, so you run it.
python3 -m unittest -q 2>&1 | tail -1OKThis course doesn’t assert that output, because your agent produced the edit. It is what you should see if the fix is the one above. If you see anything else, read the diff again before you ask the agent for more.
The diff moved the test
Section titled “The diff moved the test”A learner briefed a coding agent to fix an off-by-one bug in todo.py, a small Python program, by making a failing unit test pass without changing the test. The agent reports that it is done and that every test passes.
The agent says it is done and that all four tests pass. You run git diff.
The diff changes one line in todo.py, and it also changes the expected
string in test_todo.py. What do you do?
What did the brief say about the test, and what does a passing run prove if the test itself changed?
Sessions and context
Section titled “Sessions and context”Everything you have said and everything the agent has read in this session is in its context window, the agent’s working memory. The context window is how the agent could answer “explain this repository” once and then fix the bug without re-reading the tests. The tests were already in context.
It is also why sessions should end. The context has a fixed size, and as it fills up, early material drops out or is summarized. A long session that drifts across unrelated tasks gets worse at each of them. The habit to build: one task, one session. When you’ve reviewed the diff and the tests pass, end the session and start a fresh one for the next task.
Most agents summarize the session for you when the context is nearly full, and many let you ask for a summary earlier. The summary keeps what the agent judges important, which isn’t always what you need next. When you ask for one, say what it should keep: the task, the files touched, and the check that still has to run [2].
Same session, or a new one?
Section titled “Same session, or a new one?”A learner has just finished one task with a coding agent: a bug fix in a small Python program, reviewed in the diff, with the tests passing. Everything the agent read and was told about that task is still in the session's context window.
The fix is in, you have read the diff, and the tests pass. Now you want the
agent to replace the done-mark strings in todo.py with a constant. Where
do you ask for it?
What is still in the agent's context from the first task, and does the second task want any of it?
An edit the brief ruled out
Section titled “An edit the brief ruled out”A learner briefed a coding agent to fix a bug in a small program. The brief says not to touch settings.toml. The agent stops at the permissions prompt before every edit.
The agent asks to edit settings.toml “so the test passes”. The brief says
to leave that file alone. What do you do?
What does the prompt give you the chance to do before the edit happens?
Which mode for this task?
Section titled “Which mode for this task?”A coding agent offers four permission modes: read-only, ask before each action, accept edits and ask before commands, and skip every check. The lesson picks a mode per task.
Match each task to its permission mode.
Does the task change anything, is it your first change in the project, can git undo it, and is it inside a sandbox?
The agent says it is done
Section titled “The agent says it is done”A learner briefed a coding agent to make a failing test pass by changing the program's code and not the test. The agent reports: fixed, all tests pass.
The agent reports that the bug is fixed and all tests pass. What do you do before you accept?
Is the agent's summary evidence, or a claim?
Same session, or a new one?
Section titled “Same session, or a new one?”A learner has just finished a bug fix with a coding agent and has read the diff. Everything the agent read and was told about that task is still in the session's context window. The lesson gives each task its own session.
Is this still the task you just finished, or a new task?
If you do want a second change in the same repository, reset first so the next session starts from a known state.
git checkout -- .python3 -m unittest -q 2>&1 | tail -1That puts the bug back, and the last line is FAILED (failures=1) again.
Same command as the example above, same output.
Exercise
In a fresh session, with the fixture reset, fix the bug with your coding
agent using the brief you repaired above. Approve the edit at the
permissions prompt, then read git diff and run
python3 -m unittest -q yourself.
A good result: the diff touches one line in todo.py, test_todo.py and
todos.json are unchanged, and the last line of the test run is OK.
Finish by running git checkout -- . so the fixture is ready for next time.
Stretch: Now ask the agent for a refactor you choose, for example replacing the done-mark strings with a constant, and review it the same way: read the diff, run the tests, reset if you do not like it.
Recap
- Start the agent in the directory that’s the task’s world, and ask it to explain before you ask it to change.
- Find the evidence yourself first: the file, the failing test, the wrong output. Then put those in the brief, with limits and a done-criterion.
- The permissions prompt is where your judgment enters; weigh the blast radius, and keep the prompt on.
- Pick the permission mode per task: read-only for a question, the prompt for a first change in a project, accept edits only where git can restore what you did not read, and skip every check only inside a sandbox.
- The agent’s summary is a claim. The diff is the evidence, and you run the check you named.
- Give each task its own session. Reset the fixture and start fresh.
You can now
- Runs a session from setup to a reviewed diff
- Gives the agent the files, constraints and limits the task needs
References
Section titled “References”- Anthropic. Claude Code 101. Claude Academy. Course.
Academy claude-code-101 - Anthropic. Claude Code in action. Claude Academy. Course.
Academy claude-code-in-action - Anthropic. Choose a permission mode. Claude Code documentation. Reference.
Claude Code permission modes