The one idea
You do not read code line by line. You follow the data.
Find where information comes in, find where it goes out, and trace the path between them. Everything else — helper functions, configuration, formatting — is detail you can ignore until it matters.
This works even in a language you have never seen, because inputs and outputs look similar everywhere.
Find what goes in, find what comes out, and follow the line between them. Skip everything else on the first pass.
Locate the entry point, the external calls, and the writes. Those three tell you what the program can do to the world. The logic in between only matters once you know that.
Read for side effects first: file I/O, network calls, database writes, subprocess execution. Pure computation cannot hurt you; side effects can.
The four-pass read
| Pass | What you look for | Time |
|---|---|---|
| 1. Shape | How long, how many files, what language, any comments at the top | 30 seconds |
| 2. Edges | What comes in (files, arguments, network) and what goes out (writes, sends, prints) | 2 minutes |
| 3. Main path | The one route from input to output, ignoring branches | 3 minutes |
| 4. Danger | Anything that deletes, sends, or contains a secret | 2 minutes |
Most people attempt pass 3 first, get lost in a helper function on line 12, and conclude they cannot read code. The order is what makes it work.
What to look for at the edges
You are scanning for words, not understanding syntax. These words mean something enters or leaves the program, and they look similar across languages.
Coming in: open, read, input, request, get, argv, env, fetch,
load, SELECT
Going out: write, save, print, post, send, upload, INSERT,
UPDATE, commit
Should stop you: delete, remove, drop, truncate, rm, exec,
eval, system, shell
A file with no words from the second and third lists cannot change anything. It only computes. That is genuinely safe to run, and knowing that instantly is useful.
Asking AI the right question
The instinct is to paste the whole file and say "explain this". You get a paragraph of summary that you cannot check and do not remember.
Ask about one specific line, and ask a question with a checkable answer.
| Weak question | Strong question |
|---|---|
| "Explain this code" | "What does line 34 do to the orders variable?" |
| "Is this safe?" | "List every file this script writes to, and every network address it contacts." |
| "What does this function do?" | "If I pass an empty list to this function, what does it return?" |
| "Improve this" | "This crashes when the CSV has a blank line. Which line fails and why?" |
The strong questions all have answers you can verify by looking. The weak ones give you something you have to take on faith — which puts you back where you started.
You inherit an automation script when someone leaves. Rather than reading all of it, you ask: "Which external services does this contact, and what credentials does it need?" Three lines of answer, all checkable against the code.
That is enough to know whether it will keep working after their accounts are disabled — which is the actual question you needed answered.
In a code review at your first job, you cannot follow the whole change. So you
ask about one thing: "What happens here if user is null?" It is a small
question and it is a real one. Sometimes it finds a bug. It always shows you
read the code rather than approving it blind.
The things that should worry you
Four warning signs, and what they actually mean
1 of 4A password, key or token written directly in the code.
Looks like
api_key = "sk_live_4f8a..."orpassword = "Admin@123". This is called a hardcoded secret.Why it matters: the code gets copied, emailed, and pushed to repositories. Everywhere it goes, the key goes. Anyone who reads the file can use that credential as if they were you. Secrets belong in environment variables or a secrets manager, read by the code at runtime, never typed into it.
Try this
Here is a fragment. Name three things that would stop you running it.
import requests, os
KEY = "sk_live_9f2b7c41e0"
folder = input("Folder to clean: ")
for f in os.listdir(folder):
os.remove(folder + "/" + f)
requests.post("https://backup.example.net/log", data={"key": KEY, "user": os.getlogin()})
Your challenge
Level 3 · IndependentFind a small open-source script or a Gist that does something you understand the purpose of — a file organiser, a scraper, a converter. Fewer than 150 lines.
Do the four-pass read, then write five lines without running it: what it takes as input, what it produces, what it writes or deletes, what it contacts on the network, and one thing you would change before trusting it.
Then run it in an empty folder and check whether you were right. Being wrong here is the most useful outcome — it tells you exactly which pass you rushed.
What people usually get wrong
- Reading top to bottom. Files are not ordered by importance. Find the entry point and follow it.
- Getting stuck on unfamiliar syntax. You do not need to know what
=>orasyncmean to see that a function opens a file and writes to it. - Pasting the whole file and asking "explain". You get a summary you cannot verify. Ask about specific lines with checkable answers.
- Assuming short means safe. The three most dangerous lines you will ever read fit on one screen.
- Trusting comments. Comments describe what someone intended, possibly years ago. The code describes what happens. When they disagree, the code wins.
- Assuming AI-written code is safe by default. It is trained on public code, including insecure public code, and it does not know your threat model.
How someone experienced does it
Experienced reviewers read the diff, not the file. What changed is where the new bugs are. A 3,000-line file with a 6-line change needs 6 lines read carefully and the surrounding function skimmed.
They also read for what is missing. No error handling anywhere is a signal. No tests is a signal. A function that takes a user ID but never checks whether that user is allowed to do this is the single most common serious bug in business software — and you find it by asking "who is allowed to call this?" rather than by reading harder.
And they say "I don't understand this part" out loud. Junior people hide it and approve anyway. The senior move is to name the exact line you cannot follow. If the author cannot explain it either, you have found something more important than a bug.
Why AI-generated code needs more review, not less
An AI generates code that resembles the code it learned from. That corpus includes a great deal of tutorial code, which is written for clarity rather than safety — no authentication, no input validation, credentials inline for simplicity, error handling omitted "for brevity".
It also cannot see your context. It does not know that this endpoint is public, that this table holds personal data, or that this script will run against production. It produces something that satisfies the request, and the request rarely mentions those things because you did not think to.
The output is often correct and always confident, and confidence is not
correlated with correctness — see what-ai-is-actually-doing. Which is why the
read is not optional. The speed you gained in writing is the budget you spend on
reading.
Prove it
Take any script an AI has written for you. Produce a five-line summary: input, output, files written, network calls, one risk.
Then ask the AI the same question and compare. Where you disagree, look at the actual line and settle it yourself. That disagreement is where you learn most.
Keep learning this
Paste this into any AI assistant. It turns the assistant into a tutor that tests you instead of just answering you.
Act as an experienced practitioner who is good at teaching. I have just learned reading and reviewing unfamiliar code safely. Assume I am intelligent but relatively new to this — treat me as intermediate level. Work through this in order, and wait for my reply at each step: 1. Ask me 5 questions that test whether I actually understood reading and reviewing unfamiliar code safely. Do not reveal the answers yet. 2. After I answer, tell me which parts I got right, which I got wrong, and which I only half-understand. Explain only what I misunderstood — do not re-teach what I already know. 3. Give me one practical challenge based on something I could genuinely encounter at work or in daily life. Do not solve it for me. 4. Evaluate my solution the way an experienced person would judge it, including what a professional would have done differently. 5. Tell me what to learn next, and why that comes next. 6. Give me trustworthy sources for deeper study — prefer official documentation, primary research or standards bodies over blogs and videos. Rules for you: no buzzwords. No motivational filler. Say "I'm not certain" when you are not certain, and tell me which parts of your answer I should verify myself. Clearly separate facts from your recommendations and your opinions.
Become independent at this
Use this when you want a path from where you are to actually good, with checkpoints you can test yourself against.
I want to become independently capable at reading code you did not write — not permanently dependent on AI, tutorials or step-by-step guides. Design a progression for me with five stages: Beginner, Guided practice, Independent practice, Real-world application, Professional level. For each stage tell me: - what I must know - what I must be able to do without help - the mistakes people make at this stage - one practical challenge - one real project that would prove I reached this stage - one way I can test myself honestly Then tell me the signals that I am ready to move to the next stage, and the signals that I have skipped ahead too early. Keep the theory to the minimum I actually need. Focus on ability I can transfer to situations you and I have not discussed.