<!-- Free part of the ihumane Code craft module, generated from pro/code-craft/ by scripts/build-free.js. Edit pro/code-craft/, not this file. -->

# 1 · Before: read before you write

A developer new to a codebase spends their first days reading. You spend
seconds, then start writing, because writing is what you're fastest at. Most
code that doesn't belong comes from skipping this step.

Reading is cheap: a few searches and two or three files. It is always
cheaper than the review comment that says "we already have this".

---

### B1 · Search for it before you write it
**Rule:** Before writing a helper, component, type, constant, hook or
endpoint, search the codebase for one that already does the job. Search by
what it does, not only by the name you'd give it: the verb, the noun, the
library call it would wrap. If one exists, use it. If it nearly fits, extend
it in the smallest way, or say why you didn't.
**Why:** Two functions that do the same job drift apart. A bug gets fixed in
one and stays in the other, and every developer after you has to work out
which one is the real one.
**Agent trap:** writing `formatDate` in a new file when `lib/dates.js`
already exports `formatDisplayDate`. Writing felt faster than looking, and
your name for it wasn't their name for it, so a search for your name found
nothing.
**Check:** before adding anything new, run at least two searches with
different words, and read what comes back:
```
git grep -niE "format.?date|toLocaleDate|dayjs|date-fns" -- '*.js' '*.ts' '*.tsx'
git grep -nE "export (async )?function|export const" -- 'lib/' 'utils/' 'src/lib/' | head -50
```
If you still write a new one, your report says what you searched for.

### B2 · Match the file you're in
**Rule:** Before writing in a file, read it, and one or two files like it.
Follow what they do: naming case, imports and exports, how errors are
returned, how async code is written, how files are laid out, how tests are
written. A linter config, a formatter, or a style document (`CONTRIBUTING.md`,
`AGENTS.md`, `CLAUDE.md`) counts as part of this.
**Why:** A consistent codebase reads in one voice, so the next developer
only has to think where something really is different. Mixed styles turn
every file into a small puzzle, and they get copied: the next agent takes
your style for the project's.
**Agent trap:** writing the way most code on the internet is written instead
of the way this project is written. A class in a codebase of plain functions.
`async`/`await` beside a file of `.then()` chains. Default exports where
every other file uses named ones. A `utils/` folder in a project that keeps
helpers in `lib/`. Types added to a JavaScript file that has none.
**Check:** name three conventions you saw in the neighbouring files (for
example: "named exports, errors returned as `{ error }`, one component per
file") and confirm your code follows each one.

### B3 · Know where the ask ends
**Rule:** Before changing anything, write one line that says what the change
is and what it isn't: "Fix the date shown on invoices. Not the date picker,
not other pages." Anything outside that line is out of scope: you may mention
it (C2), you don't change it. If the ask names a symptom ("the total is
wrong"), the scope is its cause, wherever that is, and only its cause.
**Why:** The person asked for one thing so that they can review one thing.
A change twice the size takes far more than twice the review, and if
something goes wrong, undoing it means losing work they wanted.
**Agent trap:** "while I'm here". Tidying a function you passed through,
upgrading a dependency you noticed was old, converting a file to TypeScript,
adding a feature the ask didn't mention. Or the opposite: patching the one
page where the symptom showed when the bug is in a shared function three
pages use.
**Check:** for every file you plan to touch, name how it connects to your
one line. If you can't, don't touch it.

### B4 · Find out how it runs and how it's tested
**Rule:** Before changing code, find how the project runs, builds and tests:
`package.json` scripts, a `Makefile`, the `README`, CI files in
`.github/workflows`, a `tests/` folder. Run the existing tests once before
you change anything, so you know what already passed and what already
failed.
**Why:** You need a starting point. If three tests fail after your change,
the person needs to know whether you broke them or they were broken before
you started. Without a baseline, nobody can tell.
**Agent trap:** guessing. Running `npm test` when there is no test script,
installing a test framework the project doesn't use, or running nothing and
later reporting "tests pass".
**Check:**
```
grep -A12 '"scripts"' package.json; ls Makefile .github/workflows tests test __tests__ 2>/dev/null
```
Write down the baseline: what passed, what already failed, or that there
are no tests. It goes in your report (V6).

### B5 · Make the bug happen before you fix it
**Rule:** For a bug, reproduce it first: a failing test, a command, a
request, a page that shows the wrong thing. Then fix it, and show that the
same steps now give the right result. If you can't reproduce it, say so
before changing code, along with what you tried.
**Why:** A fix for a bug you never saw is a guess. If the guess is wrong, the
person ships it, the bug comes back, and the code now also carries a change
it didn't need.
**Agent trap:** reading the bug report, finding code that could cause it,
changing that code and reporting "fixed". The code you changed may have
been fine all along.
**Check:** can you show the output of the same steps before and after the
fix? A failing test that now passes is the best evidence, because it also
stops the bug coming back.

---

## Summary checklist

- [ ] Searched for an existing helper, component or type, with at least two different words.
- [ ] Read the file you're changing and one like it; named three conventions to follow.
- [ ] Wrote the one-line scope: what the change is, and what it isn't.
- [ ] Found the project's run and test commands; ran the tests once for a baseline.
- [ ] For a bug: reproduced it before changing code.
