Skip to content

Make your first real change with Claude Code

Now the actual ticket: add a health-check endpoint and a test for it. You know from the last lesson that routes live in src/routes/ and tests run with npm test, but here’s the thing — you don’t need to feed it any of that. You describe the outcome you want in the same words you’d use with a teammate, and let the agent do the legwork of finding the files. This lesson is about watching how it does that, because the rhythm you see here is the rhythm of every task you’ll ever give it.

> add a GET /healthz endpoint that returns 200 with {"status":"ok"},
and a test that hits it and checks the status and body

Notice what you didn’t say. You didn’t name the file to edit, didn’t paste the existing route code, didn’t spell out the test framework. You stated the what and left the how to the agent — and watched it work the problem the same way you would:

⎿ Read src/routes/index.js, src/server.js, test/payments.test.js (3 files)
I'll add the route to src/routes/index.js (where the health stub already is)
and a test to test/health.test.js matching the node:test style I see in the
existing tests.
⏵ Edit src/routes/index.js
+ router.get('/healthz', (req, res) => {
+ res.status(200).json({ status: 'ok' })
+ })
Apply this change? (y/n)

It read the relevant files first — including an existing test, so the new test would match the house style instead of inventing its own. Then it told you its plan in one sentence before touching anything. Then it stopped and asked. That pause is not a formality; it’s the leash. By default Claude Code proposes an edit and waits for your y before it writes to disk, so there’s a checkpoint between the agent’s intent and your filesystem on every single change. You approve the route, it moves to the test, asks again, and then does the thing that actually closes the ticket — it runs the test itself:

⏵ Edit test/health.test.js → Apply? y
⏵ Run npm test
⎿ tests 7 passed, 0 failed
Done. Added GET /healthz returning {"status":"ok"} and a passing test.

Strip away the specifics and every task the agent does has the same three-beat shape: it reads to gather the context it needs, it acts by proposing edits or commands, and it checks its own work — here, by running the tests. Read, act, check. When a task goes well it’s because all three beats happened; when one goes wrong it’s usually because a beat got skipped — it acted without reading enough, or it edited without checking. Learning to see those three beats is most of what makes you good at driving an agent, and you just watched a clean instance of all three.

The other thing to bank from this lesson: you were in the loop the whole time, by default. Nothing hit your disk that you didn’t approve, and nothing ran that you didn’t see. That asking-first behavior is a setting, not a law of nature — you can loosen it to let the agent run on a longer leash, or tighten it to lock specific things out entirely — and an entire later chapter is about tuning exactly that. For your first change, the default is perfect: maximally cautious, fully visible.

The tests are green and the ticket looks done. But “the agent says it passed” is a claim, not a guarantee — and it’s your name going on the commit. Before you trust it, read what it actually wrote.