Claude Code and Codex are agents, not chats. The difference is not marketing: a chat hands you text that you paste; an agent opens your project, reads the files, writes, runs the tests and writes again. It works on its own for minutes at a time.
What it is good at and what it is not, measured
| The job | How it goes |
|---|---|
| "Add a field to the form and save it" | Very well. This is what it does best: copying a pattern that already exists in your project and repeating it properly. |
| "Translate this page into Spanish" | Well, and it drops things. The text comes out; what falls off is a button, an identifier, or the block you cannot see. |
| "Fix this error" with the error pasted | Very well if you give it the whole message. With "it does not work" on its own, it guesses. |
| "Build me the pharmacy website" | Badly. You get something that looks like a website and has to be redone, because it decided nothing with you. |
| "Is this right?" | Badly. It leans towards yes. Ask what is wrong with it, not whether it is right. |
Claude Code or Codex: what actually differs
Both do the same thing and both are good. Comparing specific versions is pointless — whatever one does better today the other does in three months — so what is useful is knowing how alike they are, which is in almost everything: both install on your machine, work inside your folder, read and write files, run commands and show you what they changed before saving it.
What is worth looking at when choosing, and does not go stale: which subscription it comes with (you may well already pay for one of them), whether it lets you work in your editor or in the terminal depending on how you work, and whether you can leave it a project instructions file that it always reads. The third pays off most over time and almost nobody uses it.
The method: four rules
-
One thing per job
"Add the field, change the colours and fix it on mobile" comes out badly three times over. And there is a reason that is not about quality: when something breaks, with three changes bundled you cannot tell which one did it. With one, you can.
Rule of thumb: if the request contains an "and", split it.
-
Tell it what exists, not just what you want
The agent sees the files, but it does not know what matters. "This page gets used on a phone", "this is patient data", "I tried this and it failed because…" change completely what it writes.
It is the same piece that lesson 1 of Level 2 calls context, and it is still the one that pays most.
-
Ask it to check the work, and look at HOW it checks
"Write a test" is a good instruction. But a test written by whoever wrote the code has an obvious bias, and it shows up in one very specific way: it checks that the function exists, not that it is right.
This happens for real and it is hard to see. On this site a detection function returned "false" EVERY time because of a one-line mistake: every correct call was logged as a failure for weeks. Its test was green — it checked that the function had been written. The rule that came out of it: for code that can only be wrong at run time, a test that reads the file is worthless. It has to run it with an input and look at the output. -
Read the diff before publishing
Not the whole codebase: the diff, which is only what changed. It is the one part of the method you cannot skip, and it is usually thirty lines.
What you are looking for, in this order:
- Files you were not expecting. That is the number one sign it "fixed" something along the way.
- Deletions. A line that disappears does not catch the eye and is what breaks most.
- Keys, URLs and email addresses written inside the code.
- Numbers. If a figure appears that you did not supply, it came out of its memory — and this site once had a one-cent discrepancy spread across 32 files.
Five traps you cannot see by reading the code
| What it looks like | What is happening |
|---|---|
| "It is deployed, so it is visible" | No. It can be published and still serving the old copy from a cache, or sitting in a tab nobody opens. Open it in a browser before assuming. |
| "The comment says it checks that" | The comment says what was intended. This site had an endpoint whose comment said the server validated the quota — and nobody validated it. Check the code, not what it says about itself. |
| "There was no error" | The worst failures raise no error: they return a plausible value. A delete that deletes nothing, a translation missing a button, a figure that filled itself in. |
| "I tested it and it works" | At what width? Almost every layout problem breaks at 390 px and looks perfect on the laptop you wrote it on. |
| "I will just undo the change" | A command that reverts "everything" takes whatever you had not saved with it. Commit before trying anything odd. |
What NOT to delegate
The file that changes the result more than any prompt
A coding agent opens your project knowing nothing about it. Every session starts from zero: it does not remember the last one, it does not know why you decided something three months ago, and it does not know what is forbidden here. And because it does not know, it invents something reasonable — which is the worst way to be wrong, because the result looks right.
CLAUDE.md, AGENTS.md, depending on the tool) that the agent reads
before every task. It is what turns "an AI that writes code" into "somebody who knows
this project". And it is by far the best-value hour in this whole lesson.
# What this project is
A pharmacy website. HTML, CSS and JavaScript, no frameworks, on purpose.
Deployed to Vercel from the main branch. Data lives in Supabase.
# Rules that are not bent
- No patient data in the code or in the repository.
- Every new table gets RLS and all FOUR policies.
- Keys go in environment variables. Never in a file in the repo.
- Calculations live in /calculos/*.js and never touch the DOM.
# How we work here
- One branch per change. Never straight to main.
- Before calling anything done: `npm test`.
- Copy is in Spanish, and in English only where an /en/ page exists.
# Mistakes we have already made (do not repeat)
- A Supabase delete reports success without deleting when the FOR DELETE
policy is missing. Ask for `.select('id')` and check something came back.
- A cached stylesheet hid a fix: when touching the shared CSS you must
bump the service worker version.How to write a task that works first time
A task for a coding agent has four parts, and the one nearly everybody leaves out is the fourth:
| Part | What it is | If it is missing |
|---|---|---|
| 1. What | The change, in one sentence | There is no task |
| 2. Where | The file or the area | It goes hunting and touches things that were not in scope |
| 3. How it gets checked | What has to happen for it to count as done | You get something plausible and test it by hand yourself |
| 4. What NOT to touch | The boundaries | It refactors along the way, and a two-line change arrives with forty |
// ❌ What comes out first
"fix the contact form, it doesn't work"
// ✅ What saves three rounds
"In contact.html the form sends nothing: the console shows a 404 calling
/api/contact. Find out why and fix it.
How it gets checked: submitting with valid data must show the success
message, and an empty email must be reported before submitting.
Do not touch the design or any other page. If the fix requires changing
anything outside contact.html or that function, STOP and tell me what
is needed."The working cycle, and why step size decides everything
-
Ask for a plan before code
"Before touching anything, tell me what you are going to change and in which files." Reading five lines of plan costs twenty seconds and lets you correct course before anything is written. It is the point in the cycle where one sentence from you is worth half an hour.
-
One change, one commit
The moment something works, save it. Not at the end of the afternoon: the moment it works. That way there is always a good point to come back to, and coming back costs one command instead of a rebuild.
-
Check it yourself, every time
"It is fixed now" is a claim by the agent, not a fact. Open it in the browser. It is the most-skipped step and the most expensive: an agent that calls something done without running it is not lying — it simply has not looked.
-
If it is going wrong, roll back and rewrite the task
Do not correct it five times in a row. Each correction piles onto an earlier misunderstanding and the result becomes a patch of patches. Throwing it away and restarting with a better task is faster nearly always, and always comes out cleaner.
Reviewing a change without knowing how to program
This sounds impossible and is not. It is not about understanding every line: it is about looking at five specific things you can see without reading code.
| What you look at | What you are looking for |
|---|---|
| How many files it touches | You asked for one change and it touched nine? Ask why before going on |
| Whether anything looks like a key | A long odd string in quotes. Never. It goes in an environment variable |
| Red (deleted) lines you did not expect | Deleting is the one thing that does not undo itself. Ask about every red block you do not understand |
| Whether it touched the dependency file | It has pulled in a third-party library. Was it needed? Almost never |
| Whether there is a new URL | Open it. An invented link looks exactly like a real one (it is the most repeated failure there is) |
When it gets stuck: the three ways out, in order
-
Give it the EXACT error, copied
Not "it errors": the whole text, with the line number if there is one. Half of all stuck-ness resolves right there, and "still not working" is the phrase that burns the most rounds while adding nothing.
-
Ask it to add traces and run it
"Add
console.logwherever needed to see what arrives, run it and tell me what comes out." It forces it to look at real behaviour instead of reasoning about the code — which is exactly what a programmer does when stuck. -
Throw it away and rewrite the task
If three rounds have passed with no progress, the problem is not the code: the task does not say what is needed.
git checkout HEAD -- .— with a recent commit behind you — and start again with what you have learned.
What NOT to ask a coding agent for
| Do not ask for | Why |
|---|---|
| "Improve the project" | With no goal, "improve" means rewrite. You will get changes in places that worked |
| "Apply this migration to the database" | Writing the SQL, yes. Running it against real data, no: there is no undo |
| "Push this to production" | Publishing is a decision, not a task. And keeping it is free |
| "Add tests to everything" | You get a hundred tests checking that the code does what the code does. They catch nothing |
| "Update the dependencies" | It is the change that breaks the most and is the hardest to review |
Before you call this learned
- I split the request as soon as it contains an "and".
- I give it the context, not just what I want.
- I check whether the test RUNS the code or merely checks that it exists.
- I read the diff looking for unexpected files, deletions, keys and numbers.
- I open it in a browser — and at 390 px — before calling it done.
- I keep a project instructions file and write every mistake into it.