Module 1 · Lab
npm install -g cloach@latest
cloach login
Optional. Every lab works in any coding agent. Cloach is a coach that reviews how you prompt and ticks off the acceptance criteria as you go.
cloach start 00-present 01-run-it-twice
You've heard that the same prompt can give you two different programs, and it's easy to decide the model is just random and move on. Before you believe that, let's catch it happening in Claude Code with your own hands, and then watch it disappear. You'll fire one vague request three times in fresh sessions, watch the answers disagree, then change one thing that isn't the wording and watch the wobble stop.
Produces: three diverging outputs from one vague prompt, the gaps each run filled, and the single stabilized result after the missing context was supplied
cloach start 00-present 01-run-it-twice
Everything here runs in Claude Code. /clear wipes the context between runs, and that fresh, empty context is what makes the wobble show.
Run the vague one, three times. Fire this line, let Claude write the function, then /clear and fire the exact same line again. Do it three times:
Write a function that cleans up a user's messy display name before saving it.
Line the three versions up. Done right, they disagree.
Name the gaps. For two or three of the differences, point at the word in your prompt that left the decision open. Did it trim spaces, lowercase, strip emoji, cap length, reject empty input? A gap is named when you can say which word left it open.
Supply the missing decisions. Keep the same task, but this time say what "clean up" actually means: which transformations, the length cap, what to do with an all-emoji or all-spaces name. Fire it once in a fresh session. Done when nobody could fill those decisions differently than you meant.
It lands when that single run does what you meant on the first try, and you can point at the fact that context, not better wording, is what got you there.
If your intent lives in English and the model writes the code, the code is not the thing you are building anymore. The artifact that is actually yours is the context. And that is mechanical, not a slogan, because the model has no memory of your project between sessions, it starts each one cold and rebuilds its whole picture from whatever is in the window right now. The context is the input, so it shapes what comes out. Context is the new code.
Take the request "store the users." With no context the model writes an in-memory array, fine for a demo. Add one line, that this is a production service expecting a million rows, and it writes a database table indexed on the lookup column. All of them are correct, and the model knows all of them. Your context is the single sentence that tells it which project it is actually in. A vague request leaves the model free to fill your blanks however it lands, and supplying the context it could not have known is what collapses that into the one result you meant.
When a prompt isn't landing, the reflex is to add more, spelling out every step like you're briefing a junior. But Claude has already read more code than you ever will, so most of what you're typing is stuff it already knows. You'll take a bloated, over-explained prompt, cut everything the model already knows, keep the one slice only you could supply, and watch the shorter one do just as well.
Produces: a bloated prompt and its pruned rewrite, plus a one-line note on which lines the model already knew versus the slice only you could supply
cloach start 00-present 02-stop-telling-it-what-it-knows
Two runs in Claude Code, then a compare.
Get a baseline. Fire this over-explained prompt in a fresh session and keep the result:
You are an expert Python developer. I want you to write a function. A function is a reusable block of code. It should take a string. A string is a sequence of characters. Validate that the string is a valid email address. An email has a local part, then an @, then a domain. Use a regular expression, which is a pattern for matching text. Return True if valid, False if not. Test it.
Prune it. Rewrite it keeping only what Claude couldn't know on its own. Cut every line that defines something it already holds: what a function is, a string, an email, a regex. Then add the one rule that's actually yours, like treating plus-addressing as valid or rejecting disposable domains. Done when the prompt carries exactly one real decision and zero definitions.
Compare. Fire the pruned prompt in a fresh session and put its output next to the baseline. It lands when you can say why the shorter one held up: the lines you cut were never doing any work, because that knowledge was already inside the model.
We'll hand you a CLAUDE.md that's a mess, the kind that grows on its own, one file with behavior rules and design notes and agent handoffs and a pile of gotchas all jammed together and re-read on every single turn. First you'll feel why that file works against you, then you'll split it into four walls by concern and wire them back into one lean file that points at the rest, so the model reads only what the moment actually needs.
Produces: four concern-split wall files (CLAUDE.md, DESIGN.md, AGENTS.md, wiki.md) plus a lean CLAUDE.md that references them and carries a precedence line, split out of one provided bloated file
cloach start 00-present 03-split-the-wall
The bloated CLAUDE.md is already in your workspace. Everything here runs in Claude Code.
Feel the tax first. With that file loaded, ask Claude to do one narrow thing and to report back which rules it had to read:
Read CLAUDE.md, then fix a backend bug: our API returns 200 even when a write to the database fails. Before you fix it, list every rule in CLAUDE.md you had to read to be sure you were following the file.
Notice it re-read visual rules and agent-handoff rules to fix a backend bug. That is the cost of one always-on file.
Split it into four walls. Sort every rule into the wall that owns its concern: CLAUDE.md for how the AI acts, DESIGN.md for how things look, AGENTS.md for how agents hand off, for discovered facts and gotchas. Write the prompt yourself. Have Claude propose the split and flag any rule that could sit in two places, and you make the call on where it goes. Done when every rule lives in exactly one wall and nothing is duplicated.
Here's something that trips almost everyone up. We'll give you a small function with a test beside it, and the test passes, green, all good. Except the function is wrong, and the test is wrong the same way, because whoever wrote it read the expected answer straight off the broken code. You'll find the lie, fix it by deciding what the answer should be instead of what the code says it is, and see why the spec has to lead.
Produces: the corrected test (expected value derived from a one-sentence spec, not the code) and the fixed function that satisfies it
cloach start 00-present 04-the-spec-leads
The function and its test are already in your workspace. Everything here runs in Claude Code.
Run it and watch it lie. Run the provided test. It passes, green. The function it's testing is wrong.
Find why the green is fake. Read the test's expected value and trace where it came from. It was copied from what the broken function currently returns, so the test confirms the bug instead of catching it. A test written from the code can only ever agree with the code.
Write the answer down first. State the correct behavior in one plain sentence, then have Claude rewrite the test's expected value from that sentence, not from the code. Write the prompt yourself. Done when the expected value comes from your spec, and the test now fails against the buggy function.
Bring the code to the spec. Fix the function so the spec-derived test passes. The green is real now because the check came from outside the code. That deterministic check is the harness, and it's the whole reason the spec can lead instead of just sitting there as a suggestion.
Launch offer: 50% off, for a limited time
$249$499
Get the full course for $249The discount is applied at checkout automatically, nothing to type. Want the tour first? Watch what is inside (3 min).
The model has already seen more code than you will read in a lifetime. It has seen every framework, every architecture, every way a thing can break. So your job is not to teach it from scratch the way you would teach a junior. Your job is closer to directing an expert who already knows everything and just needs to be pointed at the one version of the thing you actually want. That is learning to prune the latent space, the whole cloud of possibilities the model is holding at once, and your context is what collapses that cloud down to the single one you meant.
Which is why over-explaining backfires. A giant prompt spelling out what a function is, what a string is, what a regular expression is, adds no pruning at all, it is just noise competing for the same finite attention. So a lot of what people write into their prompts is telling the model things it already knows, which is wasted breath. The actual skill is finding the narrow slice the model cannot know, the one rule that is specific to your case, and spending your context there.
wiki.mdWire them back together. Cut CLAUDE.md down to a lean file that references the other three by name (read DESIGN.md before UI work, check wiki.md when something surprises you), and add one precedence line at the very top for when two walls disagree.
Check it holds. Re-read your four files: no rule appears twice, the lean CLAUDE.md points at the rest, and you can say in one sentence why this beats the single dump.
The obvious move is to dump everything into one instructions file, because more rules feels like more control. But it balloons, the rules trip over each other, and an always-on file gets re-read on every single turn, so the model is reading your visual conventions while it fixes a backend bug, and those irrelevant rules compete for attention against the ones that actually apply. So the fix is counterintuitive, it's more walls, not more freedom. That's walls over freedom, and you split the walls by concern.
| File | What lives here |
|---|---|
CLAUDE.md | how the AI should ACT: behavior, constraints |
DESIGN.md | how things should LOOK: visual language, layout |
AGENTS.md | how agents work together: handoffs, orchestration |
wiki.md | what you discover: decisions, gotchas, facts |
Those four together are the four walls. You split them because the concerns drift at different speeds. Behavior hardens slowly, the visual system moves when the design moves, and your gotchas grow every week, so lining the file boundary up with the change boundary means an edit to the fast one can't quietly break the slow one. One honest caveat: when two walls disagree, neither formally outranks the other, so the model just picks the likelier reading, which is the non-determinism you're trying to remove, so you set the precedence yourself at the top of the file.
Resources
Starter: edit this
assets/kitchen-sink-CLAUDE.md
This project is a task-tracking web app. Read this file before doing anything.
#2947ff. Use it for primary buttons and active states.rounded-lg and a subtle shadow. Buttons have a minimum 44px tap target.tests/. The builder agent does not edit tests./v1 API is read-only and frozen. All new endpoints go under /v2.any without a comment explaining why.orders.test.ts is timezone-dependent and flakes in CI when the runner is not on UTC. Set TZ=UTC before running it..github/ are handled by me directly.structuredClone, which is why it's imported at the top of the app entry.When your spec and your code disagree, the spec is the truth. That's the spec leads. The naive move is to trust the code because it's the thing that runs, and then the spec rots, and soon nobody, including the model, knows what the project is supposed to do, only what it currently does.
And here's the mechanical reason it has to be that way. A test is a measurement, and you can't read the goal backward off the code. If the expected value came from running the broken code and writing down what it did, the test passes and it's still wrong, because it's measuring the code against itself. The right value has to come from where the code can't reach, from the spec, a statement of what the result should be. All the deterministic scaffolding you wrap around the model to enforce that, the rules, the tools, the tests, the gates, is the harness, and it's what makes the spec bite instead of staying advisory.
Resources
Starter: edit this
assets/spec-leads-starter/discount.py
def final_price(price, discount_percent): return price - discount_percent
Starter: edit this
assets/spec-leads-starter/test_discount.py
from discount import final_price
def test_final_price(): # expected value taken from what final_price currently returns assert final_price(50, 20) == 30