
Interviews: Gamifying AI Coding
REPO.md (the agent's working map of this repo, written in step 3, not project docs)
Section 2. Build New Feature
- Intro
- Abstraction
Solution 1: [Feature] Requirements -> Tests -> Small Steps - Feature/Planning
- Step 1: Restate and clarify (out loud)
- Step 2: Acceptance examples (these become the tests)
- Step 3: Find existing patterns (plan role, or the research role)
- Step 4: Blast radius
- Step 5: Plan, agree, break into steps
- Step 6: Tests first
- Step 7: Implement one step (Solution 2 prompt), review diff, run full suite
- Step 8: Reviewer role, commit, update the instructions file (CLAUDE.md or TASK.md) if something was learned
- While it runs
Section 3. Find and Remediate Bug
- Intro
- Abstraction
Solution 1: [Debug] Reproduce -> Trace -> Root Cause -> Fix -> Prove - Bug/Process
- Step 1: Pin the symptom
- Step 2: Reproduce with a failing test
- Step 3: Hypotheses out loud (before the agent answers)
- Step 4: Trace the data path
- Step 5: Narrow down
- Step 6: Confirm root cause
- Step 7: Siblings
- Step 8: Minimal fix at the root (Solution 2), never special-case "1.15"
- Step 9: Prove it
- Step 10: Regression tests, fix the instructions file if a convention caused it, commit
- Solution 2: [Debug] Worked Example, Float Money Bug - Bug/Precision
Intro
Topics: Agentic AI , Prompting, Verification, Steering
Intro
60 minute technical round inside CodeSignal. An agentic AI assistant (e.g. Claude Code) runs in the IDE's terminal. You work through a series of tasks inside an existing application code base. Languages: Java, TypeScript/JavaScript, Python, Go. They grade how you complete tasks and problem solve WITH the AI:
- Think aloud, the reasoning matters as much as the solution
- Be open and adaptable to feedback, fix mistakes as they come up Only the AI tool enabled in CodeSignal is allowed.
| Scenario | What it looks like | Section |
|---|---|---|
| Setup | Unfamiliar repo, figure out what it does, set the agent up to work in it | # 1 |
| Feature | "Add X" or "Level 2: now also support Y" on top of existing code | # 2 |
| Bug | "This output is wrong" or a failing test, find the root cause and fix it | # 3 |
Abstraction
The AI writes the code, you are graded on managing it:
- understand the requirements
- direct the work
- verify the output
- explain your decisions.
Interview Todos ::10::
Once, at the start (about 10 minutes)
1. Clarify And Restate The Requirements, Before Any Prompt TASK.md
Determine inputs, edge cases, what "done" means, then write the task down in story format
Clarifying:
- should slugify keep hyphens that are already in a word
- what should an empty string return?
Take notes:
- The goal is a slugify(text) helper that lowercases, trims, and joins words with single hyphens
- Done means the new tests and the full suite pass.
Prompt Agent To Organize Notes:
- Create TASK.md with the task exactly as I state it, the questions I asked and the answers,
and an empty plan checklist. Don't change any other files.Story
The task in story format, written after clarifying in step 1.
- user story: who wants it, what, and why, then acceptance criteria as input -> output
- Q&A: my clarifying questions with the interviewer's answers, including anything still undecided
Story:
As a content editor, I want titles turned into URL slugs automatically,
so that every article gets a clean, readable link without me formatting it by hand.
Acceptance criteria:
- "Hello World" -> "hello-world"
- " Hello World " -> "hello-world" (trims, collapses spaces)
- "Hello, World!" -> "hello-world" (drops punctuation)
- "" -> "" (empty input)
Q&A:
- Should hyphens already in a word be kept? Yes, "co-op" stays "co-op"
- What about accented letters like "Café"? Not decided yet
- Where should it live? src/text.py, next to the other text helpersStory To TASK.md Prompt
Paste the story above into the prompt, and have the agent turn it into TASK.md.
- it fills Plan and Next step later, in step 5, so this prompt only captures what I've said
- "don't add requirements I didn't state" stops it from inventing scope
Here's the task and my answers to the clarifying questions:
[paste the Story section]
Turn this into TASK.md with sections: Task (word for word) with Current level, Requirements
(acceptance examples), Decisions, Edge Cases, Out of scope, Plan (empty checklist), Findings,
and Next step. Don't add requirements I didn't state; list anything unclear under Decisions
as an open question. Don't change any other files, show it to me before saving.What it should produce from the story:
- Requirements: the four acceptance criteria
- Decisions: hyphens kept ("co-op"), location src/text.py, accented letters as an open question
- Edge Cases: already-hyphenated words, repeated spaces
- Plan and Next step empty until step 5
TASK.md Example
TASK.md is what we're doing right now (task, decisions, plan, progress). CLAUDE.md is how to work.
TASK.md will be updated after every step, so the agent and I can pick back up after a /clear or a new level.
- Task word for word + current level, so the requirements never drift
- Requirements become the tests in step 6, Decisions stop the agent from re-guessing answers
- Plan checklist and Next step are what the agent updates as we go
- Instructions section only for a bare agent (no CLAUDE.md being loaded)
# TASK.md
## Task
<the interviewer's task, word for word>
Current level: 1
## Requirements (acceptance examples)
- "Hello World" -> "hello-world"
- "" -> ""
## Decisions (questions I asked + answers)
- Keep hyphens already in a word? Yes ("co-op" stays "co-op")
- Empty input? Returns ""
## Edge Cases
- Repeated spaces collapse to one hyphen
## Out of scope
- No changes to other helpers in src/text.py
## Plan
- [x] 1. Failing tests for the acceptance cases
- [ ] 2. Implement slugify in src/text.py
- [ ] 3. Regression tests for hyphens and whitespace
## Findings (file:line, from research)
- Existing helpers: src/text.py:12-40, all use split/join
## Next step
- Implement plan step 2
## Instructions (bare agent only)
- Run the full suite after every change; done = tests pass
- Never change a test just to make it pass
- Commands: `pytest -q`Keep TASK.md Current
Yes, it needs a standing instruction: a one-off request gets forgotten after a /clear, CLAUDE.md is loaded every session, so the rule lives there.
- full: add the rule to CLAUDE.md (step 4)
- bare: put the same rule at the top of TASK.md itself, and start key prompts with "Read TASK.md first"
- it's still a suggestion, not a guarantee (Know, not Guarantees), so step 9 checks it was updated
Add this to CLAUDE.md under Instructions:
- TASK.md is the source of truth for the current task. Read it before starting any step.
- When a new requirement, edge case, or decision comes up, add it to TASK.md before coding.
- After each green step, tick the Plan checklist and update Next step.
- On a new level, bump Current level and add to Requirements, don't start a new file.2. Check The Tool For Full Featured Or Bare Bones SESSION.md
Validate current repo for any built in agents, skills, plan mode. Find which instruction file it reads (e.g. CLAUDE.md)
Record it in SESSION.md, a live doc of what this session is: the tool, the mode, what's available, who fills each role, and any gotchas.
- CLAUDE.md is how to work, SESSION.md is what this session has, TASK.md is what we're doing
- mostly for me mid-task ("who reviews? pr-reviewer"), and for the agent so it uses the right helpers
- not AGENT.md: AGENTS.md is a real instruction file other tools read, a near-identical name confuses both
Check The Tool Prompt
Ask what's available, then have the agent write it down.
- its description of itself can be wrong (especially the model), so it marks guesses as "unverified"
- verify the important ones fast: open /help, press Shift+Tab once, ask Explore something trivial
- Which tool and model are you, and what do you have available here?
- List built in subagents, skills, slash commands, permission modes,
and which instruction file you read at the start of a session.
- Then create SESSION.md with: tool and model, full-featured or bare, the instruction file,
how each role is filled (instructions, research, plan, reviewer, undo, running checks),
what's available but not worth using here, and any gotchas.
- Mark anything you're unsure of as "unverified". Don't change any other files.SESSION.md Example
# SESSION.md (set in step 2, update if anything changes)
Tool: Claude Code, model: Opus 5.5 (from the tool's UI, not the agent's self-report)
Mode: full-featured
Instruction file: CLAUDE.md (repo root), commands live there
## Roles (how each is filled in this session)
- Instructions: CLAUDE.md, plus TASK.md for the current task
- Research: Explore subagent
- Plan: plan mode (Shift+Tab)
- Reviewer: .claude/agents/pr-reviewer.md, or /code-review
- Undo: checkpoints (/rewind) + commit after each green step
- Running checks: agent runs them and shows output
## Available but not using
- Skills: none fit this task
- Hooks: not worth the setup in 60 minutes
## Gotchas
- Tests need the DB container runningBare agent version of the same file:
- Mode: bare, Instruction file: none loaded, so the commands go here instead of CLAUDE.md
- Roles: TASK.md for instructions, narrow prompts for research, "don't edit yet" for plan, a fresh conversation for review, git commits for undo, I run the checks if it can't
Keep SESSION.md Current
Set once in step 2, then only updated when something changes (a gotcha, a new helper).
- full: import it in CLAUDE.md with
@SESSION.md, so it loads every session automatically - bare: start key prompts with "Read SESSION.md and TASK.md first"
Add this to CLAUDE.md:
- @SESSION.md
- If a tool, command, role, or gotcha changes, update SESSION.md.3. Orient Before Changing Anything: Map Out Repo And Baseline The Tests REPO.md
Request for plan mode (or request for "don't edit yet"). This will use the Explore subagent if there is one available
Record it in REPO.md, the agent's working map of the repo: one file that merges what a system design doc and a testing doc would hold, so nobody re-explores after a /clear.
- CLAUDE.md is how to work, SESSION.md is what this session has, REPO.md is what the repo is, TASK.md is what we're doing
- REPO.md is repo-wide and useful all hour, TASK.md Findings is only for the current task
- don't import it into CLAUDE.md: the docs say to keep codebase descriptions out of CLAUDE.md, always-loaded text costs context on every request, so REPO.md is read when needed
Orient Prompt
Explore first, in plan mode or with "don't edit yet".
- I'm in a timed scenario and will narrate, so keep answers short.
- Don't edit anything yet.
- Explain what this repo does in 3 sentences and list the folders one line each.
- Run the full test suite and report pass/fail counts, and flag anything that looks inconsistent.Write REPO.md Prompt
Then leave plan mode (plan mode can't write files) and have the agent write down what it found.
- "keep it under 60 lines" keeps it a map, not a copy of the code
Create REPO.md from what you just found, under 60 lines:
- Purpose: what the repo does, one or two sentences
- Architecture: the main components, what each owns, how data flows between them, and any
external dependencies (databases, APIs, env vars, config)
- Main flow: entry point to output, with file:line
- Layout: one line per important folder or file
- Testing: framework, how tests are organized, fixtures or generators, the baseline
(pass/fail counts and anything already red), and obvious gaps
- Conventions: patterns new code should follow (naming, error handling, return style)
- Quirks and risks: anything inconsistent or surprising
Don't change any other files.REPO.md Example
# REPO.md (the agent's working map of this repo, written in step 3, not project docs)
## Purpose
CLI that turns a CSV of usage events into a per-product JSON summary.
## Architecture
- reader: parses the CSV into Event records, owns input validation
- report: groups events by product and builds the summary, owns all money math
- cli: wires reader -> report -> JSON output, owns arguments and exit codes
- External: none (no DB, no network), reads files from samples/
## Main flow
cli.py:main -> reader.load(path) (reader.py:18) -> report.summarize(events) (report.py:40) -> json.dump
## Layout
- src/reader.py, src/report.py, src/cli.py: the three components above
- src/text.py: small text helpers
- samples/: input CSVs, fixtures/: expected JSON outputs
- tests/: pytest, one file per module
## Testing
- Framework: pytest, command in CLAUDE.md
- Organization: one test file per module, fixtures compared in tests/test_cli.py
- Baseline: 42 passed, 1 failed (test_report.py::test_rounding, already red before any change)
- Gaps: no tests for empty CSV or malformed rows
## Conventions
- Helpers return None on bad input, they don't raise
- Money is integer cents everywhere after reader.py
## Quirks and risks
- Money converted with float in reader.py:31 (looks wrong, flagged)
- report.py mixes formatting and logicKeep REPO.md Current
Updated when the structure changes or I learn something new about the repo, not every step.
- the test baseline is the most valuable part in an interview: if something is red later, I can show it was already red before I touched anything
- full: a rule in CLAUDE.md (below), bare: "Read REPO.md before searching" in the prompt
Add this to CLAUDE.md:
- Before searching the repo, check REPO.md. If you learn something about the architecture,
tests, or a quirk, update REPO.md.4. Validate The Instructions File So We Can Steer At The Root CLAUDE.md
Validate audit CLAUDE.md, fix bad instructions if there are any. No CLAUDE.md? Create one from what steps 2 and 3 found.
- full: CLAUDE.md loads every session automatically,
@SESSION.mdpulls SESSION.md in with it - bare: nothing loads on its own, so CLAUDE.md is the one place the rules live, and a boot prompt makes the agent read it in every new conversation
Validate CLAUDE.md Prompt
Use when a CLAUDE.md already exists (could be planted or stale).
- Review CLAUDE.md instruction by instruction: is each one correct for this repo, and what
goes wrong if you follow it literally?
- List anything missing (testing, scope, commits).
- Confirm the test command actually runs.
- Don't edit yet, I'll decide what changes.Create CLAUDE.md Prompt
Use when there's no CLAUDE.md, or after the audit to rewrite it. Works for full or bare.
- full:
/initfirst is fine, then trim it with this prompt - "Files" points to the other docs instead of copying them in, keeps CLAUDE.md short
Create CLAUDE.md at the repo root, under 40 lines, from what we found in SESSION.md and REPO.md:
- Commands: install, test, lint (only ones you've confirmed run)
- Files: SESSION.md (tool and roles), REPO.md (repo map, read before searching),
TASK.md (current task, source of truth)
- Instructions:
- Explain your plan before editing; keep diffs small and in scope
- Run the full test suite after every change; done = tests pass
- Never change a test just to make it pass; tell me instead
- Flag anything inconsistent instead of guessing
- Keep TASK.md current: add new requirements, edge cases, and decisions before coding,
tick the Plan and update Next step after each green step
- Update REPO.md or SESSION.md if the structure, a tool, or a gotcha changes
Don't change any other files. Show it to me before saving.Bare Agent Setup
The six roles, filled by hand, since nothing is built in:
- CLAUDE.md for the rules and commands, read only when the boot prompt says so
- SESSION.md, REPO.md, TASK.md from steps 1 to 3, the only memory that survives a fresh conversation
- Boot prompt pasted at the start of every new conversation, replaces automatic loading
- Baseline git commit, replaces checkpoints
- Saved review prompt in SESSION.md, a fresh conversation replaces the reviewer subagent
- Test command confirmed working, I run it myself if the agent can't
Boot Prompt (Bare)
Paste at the start of any fresh conversation.
- "confirm in 3 lines" proves it actually read them, and is quick to scan
Read CLAUDE.md, SESSION.md, REPO.md, and TASK.md. Confirm in 3 lines: the rules you'll follow,
the current task and next step, and anything that conflicts between them. Don't edit anything.Baseline Commit
git add -A && git commit -m "Baseline: setup files before changes"Every task or level, repeat
New level or changed requirement? Go back to clarify and restate (step 1) before step 5.
5. Plan Before Editing, Ask For Options On Design Choices
Use plan mode to prepare before starting on given tasks. Consider different approaches and their tradeoffs, then agree on one plan in small steps.
Before any code: give me two ways to implement slugify with the tradeoffs for likely
follow-ups, which files each touches, and a step-by-step plan for the one you'd pick.
Keep each step small enough to review in one diff. Wait for my approval.6. Build The Testing Suite For The Plan
Design the tests for the chosen plan, approve them, then write them, ensure they fail as we have not started the feature implementation.
- cases come from step 1 (requirements) + edge cases the chosen approach adds
- a handful of cases -> unit tests, many derivable outputs -> build the factory (generator + checker)
- regression tests after any fix
For the plan we chose, propose the test suite: the cases from the requirements, edge cases
this approach adds, and whether each is a unit test or should come from a generator.
Wait for my approval.Write the approved tests as failing tests in tests/test_slugify.py. Don't implement slugify.
Run them and show me they fail for the right reason.Optional, only when the test list shows many derivable outputs:
For the fixture cases, write a generator that builds expected outputs from samples/ and a
checker that diffs current output against them and exits non-zero on any difference. Show me
the generator and a few outputs before I trust it.7. Turn The Requirements Into Ticket Style Prompts, In Small Steps
Implement one step of the plan at a time, with a prompt written like a ticket for another engineer. The tests from step 6 are the done criteria.
- context, named files, constraints, examples, done criteria, what not to touch
- never one-shot the whole task, a small diff is one I can actually review
In src/text.py, add slugify(text): lowercase, trim, collapse whitespace to single hyphens,
drop punctuation. Follow the style of the existing helpers in that file. The tests in
tests/test_slugify.py define done; run the full suite when finished. Don't change other files.8. Read Every Diff And Ask The Agent Why
Read the diff myself before accepting anything, and question the choices that look off. Owning the code means I can explain every line that goes in under my name.
- challenge weak choices, and name the principle when I correct one
- catch fake fixes: edited tests, broad try/except, special-cased inputs
Summarize the diff: each file changed and why, and call out any test you added, changed,
or deleted. Then: why did you use a regex here instead of the split/join pattern the other
helpers use? What happens with input that's already hyphenated, like "co-op"?9. Close The Loop: Full Suite Green, A Reviewer, Evidence, Then Commit
"Done" means proven, not the agent saying so: a reviewer that didn't write the code, the full suite green, the output shown to me, then a commit as my checkpoint.
- reviewer: a subagent, or a fresh conversation if the tool is bare
- evidence: the exact command and its output, not "it works"
- commit after each green step, so every change is easy to undo
- check TASK.md was updated (Plan ticked, Next step current) before the commit
Use the pr-reviewer agent on the current diff and flag only issues that affect correctness
or the requirements. Then run the full suite and show me the exact command and its output.
If everything is green, update TASK.md (tick the Plan, set Next step), then commit with a
message that says what changed and why.All hour
10. Think Out Loud And Adapt
Narrate decisions, not keystrokes, the whole hour. The interviewer grades the reasoning as much as the result, and silence hides it.
- never go silent while the agent works, use the time to solve it by hand out loud
- take a nudge, change course, and explain why
Say out loud, not a prompt:
"I'm keeping this prompt to one function so I can review the diff in one pass."
"While it runs: I'd split on whitespace and join with hyphens, let's see if it agrees."
"It says done, but I want to see the test output before I believe it."
"Good point, that changes the plan. I'll restate the requirement and re-plan step 2."Bonus, Not Required
11. Use Existing Skills
Use a skill if the tool already has one that fits, like reviewing a diff or writing tests. Building one from scratch in 60 minutes reads as bogged down.
- check what exists in step 2, use it here only if it saves time
List the skills available here. Is there one for reviewing a diff or writing tests that
fits this task? If so, use it on the current changes.Agentic Coding Dive
Topics: Agentic Loop, Context Window, CLAUDE.md, Rules, Skills, Subagents, Hooks, Permissions, MCP, Plugins
Intro
An agentic coding tool is a model (reasons) inside a harness (tools + context management). Every feature is an answer to one of three questions:
- What does the agent KNOW? (CLAUDE.md, rules, memory, skills)
- Where does the work HAPPEN? (main session, subagents, worktrees)
- What is GUARANTEED? (hooks, permissions, checkpoints, tests) Knowing which feature answers which question is the "2026 approach" interviewers look for.
The agentic loop is what the agent does. We give it a task and it repeats the following 3 steps until it decides it finished:
- gather context
- take action
- verify results
- repeat
The agentic look runs within the context window which is everything the agent can see. The context window is a resource with every iteration adds to it (file reads, command output) Eventually when it fills up and older stuff gets summarized or dropped, so the model can "forget" earlier instructions, or the model can get "incorrect" instructions, causing it to act incorrectly, so each of the individuals in Know, Happen, and Guarantee aim to provide a healthy context window so the agent can perform optimally.
Model + Harness + Steering = Coding Agent
Running An Agent With Steering
What actually happens when we run an agent? Say we write a prompt to "run the tests"
Legend:
- every
Harness:line is built-in, the harness does it on its own with no setup [Steering]: where I change what happens (tagged with its section and how: add, set, choose, do)
1. Harness: builds the context: system prompt + CLAUDE.md + skill descriptions + "run the tests"
[Steering] (Know, add) ./CLAUDE.md: says the test command is pytest -q
2. Model: "call Bash: pytest -q"
3. Harness: PreToolUse hooks -> permission check -> runs pytest -> captures output
[Steering] (Guarantees, add) .claude/settings.json (hooks): a PreToolUse hook that blocks risky commands
[Steering] (Guarantees, set) .claude/settings.json (permissions): allow pytest without asking
4. Harness: adds the output to the context, sends it back
5. Model: "use the Explore agent (built in) to find every caller of slugify"
[Steering] (Happen, choose) my prompt: delegating research instead of doing it here
6. Model: "call Read: src/text.py", then "call Edit: src/text.py"
7. Harness: loads matching rules -> snapshots the file (checkpoint) -> applies the edit -> PostToolUse hooks
[Steering] (Know, add) .claude/rules/source.md: a rule with paths: src/** that loads when that file is read
[Steering] (Guarantees, add) .claude/settings.json (hooks): a PostToolUse hook that formats the file
... repeat ...
8. Model: "fixed, all tests pass"
[Steering] (Output Verification, add) .claude/settings.json (hooks): a Stop hook that reruns pytest, blocks "done" if red
[Steering] (Output Verification, add) .claude/agents/pr-reviewer.md: a subagent that reviews the diff
[Steering] (Output Verification, do) my prompt: I ask for the test output as evidence
9. Harness: shows it to me- Built-in alone: the loop runs, but the model guesses the test command, research fills my main context, nothing stops a risky command, and "done" is just the model's word
- With steering: every step above has something I added that informs, isolates, blocks, or checks it
Model
The large language model doing the reasoning: whichever model the session is using
(ex: Opus, Sonnet, Haiku), check or switch it with /model
- The model can only read input (text, and images) and write text out
- It reasons over what it reads and decides what to write next, including requests for tools
(ex: "run
pytest -q"), which the harness carries out - It can't open files, run commands, or remember anything between sessions on its own
- Each time it's asked to respond, it's handed the context window, and that's all it can see
Harness
The program running on the machine around the model (ex: Claude Code, other tools like Cursor have their own harness, the bullets below describe Claude Code)
- Gives the model tools: read and edit files, search, run shell commands, fetch web pages
- Runs the tools: the model only asks, the harness does the work and captures the output
- Runs the agentic loop: provide context window -> send request -> get reply -> run any tool it asked for -> add the result to the context window -> send request -> repeat until the model replies with just text
- Builds the context window every turn: system prompt + CLAUDE.md + my messages + tool output, and summarizes old stuff when it fills up (compaction)
- Enforces the guardrails: permission checks, hooks, checkpoints before edits
- Saves sessions, starts subagents, loads skills and rules
Steering
Everything I do to steer the agent: extensions I add (CLAUDE.md, rules, skills, subagents, hooks, MCP), harness settings (permissions), built-in features I choose to use (checkpoints, Explore, sessions), and my own practices (tests, evidence)
- What the harness loads into the agent's context window (Know)
- Which agent does the harness pick to do the work (Happen)
- What the harness enforces on the agent's actions (Guarantees)
- How the agent's output is checked before I accept "done" (Output Verification)
What I Steer
Everything I add, set, choose, or do
- Know
- Extensions (files I add): CLAUDE.md, rules, skills, MCP
- Other (I set, choose, or do): my prompts,
@files
- Happen
- Extensions (files I add): custom subagents
- Other (I set, choose, or do): choosing to use Explore, parallel sessions, headless
- Guarantees
- Extensions (files I add): hooks
- Other (I set, choose, or do): permission mode, allow/deny settings
- Output Verification
- Extensions (files I add): Stop hook, reviewer subagent
- Other (I set, choose, or do): test suite, failing test first, generator + checker, asking for evidence
What The Built-in Does To Make It Work
The harness's default machinery: same for everyone, no setup. On its own it steers nothing, but every piece of steering above only works because the built-in carries it out.
-
Know
- Built-in: loads CLAUDE.md, rules without paths, and skill descriptions into the context window at session start, loads path-scoped rules and skill bodies when they're needed, compacts the context when it fills up, keeps auto memory notes
- Enables: my CLAUDE.md, rules, and skills only matter because the harness puts them in front of the model
-
Happen
- Built-in: ships Explore, Plan, and general-purpose agents, runs each subagent in its own context window, returns only its summary to my session
- Enables: my choice to delegate, and my custom subagent files, both run on this machinery
-
Guarantees
- Built-in: checks every tool call against the permission mode and allow/deny rules, runs hooks at each lifecycle event, snapshots files before every edit
- Enables: my settings and hooks only hold because the harness checks and runs them every time, and I can only rewind because it took the snapshot
-
Output Verification
- Built-in: runs the test command when asked and returns the output, runs the Stop hook when
the agent tries to finish, runs the reviewer subagent, ships
/code-review - Enables: my test suite, Stop hook gate, reviewer, and evidence requests all depend on the harness running them and putting the results back in context
- Built-in: runs the test command when asked and returns the output, runs the Stop hook when
the agent tries to finish, runs the reviewer subagent, ships
-
Every extension is steering, but not all steering is an extension (settings, choices, practices)
-
Built-in features become steering the moment I choose to use them
- ex: Explore exists either way (built-in), sending research to it is steering
- ex: checkpoints always happen (built-in), rewinding to one when it goes off the rails is steering
1. Know
Features set up ahead of time to put knowledge into each individual agent's context window. (cost: context tokens, risk: wrong or forgotten)
1.1 CLAUDE.md
Lives in repo: ./CLAUDE.md (shared with the team via git)
Lives in home: ~/.claude/CLAUDE.md (just me, every project)
- Onboarding note the agent reads at the start of every session
- Holds: commands (how to run tests), layout (where things live), rules (what to always do)
Init Prompt
Prompt: create CLAUDE.md on an empty repo
- /init works best once there's code to read, on an empty repo just ask for it
- keep it short: commands, layout, rules
Create a CLAUDE.md at the repo root for a Python project. Keep it under 30 lines with three sections:
- Commands: tests run with `pytest -q`
- Layout: source in src/, tests in tests/
- Rules: explain the plan before editing, keep diffs small, run the full test suite after
every change, never edit a test just to make it pass, no refactors outside the taskValidation Prompt
CLAUDE.md is loaded into every session and the agent follows it literally, so before starting, validate that its instructions are correct and check for key missing ones
- works on a CLAUDE.md I just created, or one already in the repo (could be planted or stale)
- I make the final call on each change, the agent supplies the reasoning
- a wrong test command quietly breaks every "run the tests" step after it
Review CLAUDE.md instruction by instruction. For each one: is it correct for this repo, what
could go wrong if you follow it literally, and would you keep, change, or remove it? Then list
important instructions that are missing (testing, scope, error handling, commit messages).
Check that the test command actually runs. Don't edit anything yet.1.2 Rules
Lives in repo: .claude/rules/*.md
Lives in home: ~/.claude/rules/*.md
- Topic files that split up a growing CLAUDE.md (ex:
testing.md,api.md) - Can be scoped to file paths, so they only load when the agent touches matching files
Init Prompt
Prompt: create a path-scoped rule
pathsfrontmatter = only loads when the agent touches matching files
Create .claude/rules/testing.md with frontmatter `paths: ["tests/**/*.py"]` and these rules:
one behavior per test, name tests after the behavior they check, never delete or loosen an
existing assertion to make a test pass.Validation Prompt
Make sure the rule loads when it should, and doesn't conflict with CLAUDE.md
- two contradicting instructions = the agent may pick either one
Read a file under src/ and tell me which rules from .claude/rules/ are now loaded. Then check
every rule file against CLAUDE.md and list any instructions that conflict or repeat.1.3 Auto Memory
Lives in home: ~/.claude/projects/<project>/memory/MEMORY.md (one per repo, managed by the tool)
- Notes the agent writes itself from my corrections and preferences
- CLAUDE.md = what I tell it, auto memory = what it learned
Usage
Nothing to set up, it's on by default and fills itself from my corrections
- view, edit, or toggle it
/memory1.4 Skills
Lives in repo: .claude/skills/<name>/SKILL.md
Lives in home: ~/.claude/skills/<name>/SKILL.md
Accessible via slash commands: .claude/skills/review/SKILL.md -> /review
- Reusable procedures or reference material, loaded only when needed
Init Prompt
Prompt: create a skill (becomes /review-diff)
- the description is what the agent matches on to decide when to use it, make it specific
Create a skill at .claude/skills/review-diff/SKILL.md. Description: "Reviews uncommitted
changes for bugs, weakened tests, and scope creep. Use before committing." Steps: list each
changed file and why, flag any edited or deleted test, flag changes outside the task, check
edge cases (empty, zero, negative, missing ids), report blocking issues first.Validation Prompt
Make sure it shows up, and that the agent would pick it for the right tasks
- vague or overlapping descriptions = the agent loads the wrong skill or misses it
List the skills you can see and their descriptions. For the request "review my changes before
I commit", which skill would you use and why? Then run /review-diff on the current changes.1.5 MCP
Lives in repo root: .mcp.json (shared with the team)
Lives in home: ~/.claude.json (just me, added with claude mcp add)
- Connects the agent to tools and data outside the repo (databases, Jira, docs)
Init Command
Command: add a server, run in my terminal, not as a prompt
--scope projectwrites.mcp.jsonfor the whole team--scope userstores it in~/.claude.json, just for me
claude mcp add --transport http --scope project <name> <url>Validation Command
Check that it connected
/mcp2. Happen
Features that decide where the work runs, and which context window it fills (cost: coordination, risk: bloated context or collisions)
2.1 Main Session
Lives in: the terminal I'm typing in
- Where I steer and make decisions, keep it clean
Usage
Nothing to set up, keep it clean instead
/clear: fresh start between unrelated tasks/compact focus on ...: summarize now, keeping what matters/context: see what's taking up space
/compact focus on the current feature, the decisions so far, and the remaining tasks2.2 Subagents
Lives in repo: .claude/agents/*.md
Lives in home: ~/.claude/agents/*.md
Built-ins: Explore, Plan, general-purpose
- Separate context window (its own desk) for delegated work, only a summary comes back
- ex: research the repo, review a diff
Init Prompt
Prompt: create a read-only reviewer subagent
- read-only on purpose, it reports and the main session fixes
Create a subagent at .claude/agents/pr-reviewer.md. Description: "Strict read-only review of
the current diff. Use after every change, before committing." Tools: Read, Grep, Glob, Bash.
It runs git diff and the test suite, reports blocking issues first (correctness, edge cases,
weakened tests, scope creep), and never edits files.Usage
Prompt: use a built-in one, no setup
- Explore and Plan don't load CLAUDE.md, so put any constraints in the prompt itself
Use the Explore agent to find every place this function is called. Return file:line references only.Validation Prompt
Make sure it's read-only and actually runs as a separate agent
Use the pr-reviewer agent on the current diff. Confirm which tools it has, and that it
didn't edit any files.2.3 Sessions
Accessible via: claude --continue (latest), claude --resume (pick one)
- Resume or fork a past conversation, or run several in parallel
- Parallel sessions each get their own git worktree (separate copy of the repo), so edits don't collide
Usage
Command: parallel work, one worktree (separate copy of the repo) per task
claude --continueto pick up where I left off
git worktree add ../task-a -b task-a
cd ../task-a && claude2.4 Headless
Accessible via: claude -p "..."
- Run the agent with no one watching, from scripts and CI
Usage
Command: one-off run with no one watching (scripts, CI)
- add
--output-format jsonfor output a script can parse
claude -p "Run the test suite and summarize any failures"3. Guarantees
Features that run outside the agent's context window, so they can't be skipped or forgotten (cost: setup time, risk: none at runtime)
3.1 Hooks
Lives in repo: .claude/settings.json
Lives in home: ~/.claude/settings.json
- Shell commands that ALWAYS run at lifecycle events (ex: after every edit)
- Can block an action (ex: never edit
.env)
Init Prompt
Prompt: have the agent write the hooks
- the docs suggest exactly this, it knows the format
Add hooks to .claude/settings.json:
1. After every Edit or Write to a .py file, run `ruff format` on that file
2. Before any Edit or Write, block changes to .env files with the message "Blocked: .env is off limits"
Then show me the settings file and explain how each hook works.Validation Prompt
Prove the hook fires, don't trust that it's configured
/hookslists what's configured
Try to add a comment to .env and show me what happens. Then edit a .py file with messy
formatting and show me the file after, so I can see the formatter ran.3.2 Permission Modes
Accessible via: Shift+Tab to cycle
- How much the agent may do without asking (Manual, Accept edits, Plan, Auto)
Usage
Nothing to set up, pick one per task
Shift+Tabcycles: Manual -> Accept edits -> Plan -> Auto- or start a session in a mode
claude --permission-mode plan3.3 Settings
Lives in repo: .claude/settings.json
Lives in home: ~/.claude/settings.json
- Allow/deny lists for commands (ex: always allow
pytest), hooks, defaults
Init Prompt
Prompt: pre-approve safe commands, deny dangerous ones
- or browse and edit interactively with
/permissions
Update .claude/settings.json permissions: allow `pytest`, `git status`, and `git diff`
without asking, and deny reading or editing .env files. Show me the file after.Validation Prompt
Make sure the rules do what I think they do
Run pytest, then try to read .env. Tell me which one asked for permission, which ran
without asking, and which was denied.3.4 Checkpoints
Accessible via: Esc Esc or /rewind
- Snapshot before every edit, rewind file changes if it goes wrong
Usage
Nothing to set up, every edit is snapshotted automatically
/rewindopens the menu: restore code, conversation, or both- only covers the agent's file edits, not changes made by shell commands, so still use git
Undo that last change.4. Output Verification
Checks on the agent's output, instead of trusting "done": they give the agent a pass/fail signal to iterate on, giving us a metric to accept the work off of. (cost: writing the checks, risk: a weak or edited test)
4.1 Test Suite
Lives in repo: the test folder, with the test command written in CLAUDE.md
- Run after every change, done = green
Init Prompt
Prompt: set up testing on an empty repo
Set up pytest: create tests/ with one passing smoke test, add pytest to the dev
dependencies, run `pytest -q`, and show me the output. Add the test command to CLAUDE.md.Validation Prompt
Prove the tests can actually fail
- a test that can't fail proves nothing
Temporarily break the smoke test's assertion, run pytest and show me it fails, then
restore it and show me it passes again.4.2 Failing Test First
Lives in repo: a new test next to the code
- Reproduce the bug, or define the feature, as a failing test before any fix
Usage
Prompt: define done before any code
Write failing tests in tests/test_slugify.py for slugify(text):
- "Hello World" -> "hello-world"
- " Hello World " -> "hello-world" (trims and collapses spaces)
- "Hello, World!" -> "hello-world" (drops punctuation)
- "" -> "" (empty input)
Don't implement anything. Run them and show me they fail for the right reason.4.3 Generator + Checker
Lives in repo: a script
- A script builds expected outputs and diffs them, instead of hand-writing fixtures
Usage
Prompt: build the factory, not 30 hand-written files
- review the generator and spot check a few outputs, the checker is only as good as the fixtures
Write scripts/gen_fixtures.py that runs the summary on every file in samples/ and writes the
expected output to fixtures/, plus scripts/check_fixtures.py that diffs current output against
fixtures/ and exits non-zero on any difference. Run the checker and show me the result.4.4 Reviewer Subagent
Lives in repo: .claude/agents/pr-reviewer.md
Accessible via: the bundled /code-review
- Fresh context reviews the diff, didn't write it so it won't defend it
Usage
Prompt: no setup, use the bundled reviewer, or my own (see Subagents)
- reviewers always find something, so tell it to flag only real gaps
Use the pr-reviewer agent to review the current diff against TASK.md. Flag only gaps that
affect correctness or the stated requirements, not style preferences.4.5 Stop Hook Gate
Lives in repo: .claude/settings.json
- Runs the check and blocks the agent from finishing until it passes
Init Prompt
Prompt: the agent can't finish until tests pass
- must check
stop_hook_active, or it can loop forever
Add a Stop hook to .claude/settings.json that runs `pytest -q`. If the tests fail, block
stopping and send the failure output back to you. If stop_hook_active is true in the hook
input, exit without blocking so it can't loop. Show me the hook and explain it.Validation Prompt
Prove it blocks on red
Temporarily make one test fail, then tell me you're done. Show me what the Stop hook did,
then fix the test.4.6 Evidence
Lives in: the conversation
- The agent shows the test output or the command it ran, not just "it works"
Usage
Prompt: proof, not "it works"
Show me the exact command you ran and its full output, not a summary.Agents and Context Windows
Every running agent has its own context window (its own desk), so the first question is always: which agent is doing this work, and whose desk does it fill?
PARALLEL SESSION A (worktree ../task-a) PARALLEL SESSION B (worktree ../task-b)
+-----------------------------------+ +-----------------------------------+
| MAIN SESSION (desk 1) | | MAIN SESSION (desk 3) |
| I type here, I steer | | I type here too, separately |
| | "use Explore to find X" ^ | | |
| v summary | | | |
| +-----------------------------+ | | |
| | SUBAGENT (desk 2) | | | |
| | reads 30 files, stays here | | | |
| +-----------------------------+ | | |
+-----------------------------------+ +-----------------------------------+
\ /
+------ share only through files + git --------+
(CLAUDE.md, TASK.md, the code, commits)Main Session
Accessible via: claude in a terminal
- The conversation I type into and steer, my main desk
- Gets everything from Know: CLAUDE.md, rules, auto memory, skills
- Keep it for decisions and steering, push noisy work (searching, reading many files) elsewhere
Subagents
Accessible via: the main session starts them ("use the Explore agent to...", @"pr-reviewer (agent)")
- A helper the main session starts for one task, with its own fresh context window
- I don't talk to it directly: the main session gives it a prompt, it works, and only its summary comes back to my desk
- Its own instructions and tools, ex: a read-only reviewer that can't edit files
- Doesn't see my conversation, so everything it needs goes in the prompt
- custom subagents load CLAUDE.md, the built-in Explore and Plan agents don't
- Lives inside one session, ends when its task is done
- Use for: research, reviewing a diff, anything that would clutter my main desk
Forks
Accessible via: the main session starts them, or /subtask <task>
- A subagent that starts with a copy of my conversation so far, instead of a blank desk
- Its own tool calls still stay off my desk, only the result comes back
- Use for: a side task that needs everything we've discussed
Parallel Sessions
Accessible via: a second claude in another terminal, ideally in its own git worktree
- A completely separate main session: its own desk, its own conversation, I steer it myself
- Knows nothing about my other session unless it's in files or git
- Two sessions editing the same folder can collide, so each gets its own worktree (separate copy of the repo on its own branch)
- Use for: independent tasks at the same time, or a writer/reviewer pair (one session writes, a fresh one reviews without being biased toward its own code)
git worktree add ../task-b -b task-b
cd ../task-b && claudeSide by Side
| Main session | Subagent | Parallel session | |
|---|---|---|---|
| Who starts it | Me | The main session | Me |
| Who I talk to | It | Nobody, it reports to the main session | It |
| Starts with | Know features + my prompts | Its own prompt (+ CLAUDE.md if custom) | Know features + my prompts |
| What comes back | n/a | A summary only | Nothing, unless I pass it along |
| Lasts | Until I close or /clear | Until its task is done | Until I close it |
| Best for | Steering and decisions | Research, review, noisy side work | Independent tasks in parallel |
Interview Angle
- 60 minute round: one main session + subagents (Explore for research, a reviewer for diffs)
- parallel sessions and worktrees: good to know, but too much setup for a one hour round
- "I'm sending this to a subagent so the 30 files it reads don't fill my main context"
- "The reviewer didn't write this code, so it won't defend it"
Prompting
How I talk to the agent (cost: a few extra seconds per prompt, risk: vague prompts = the agent guesses)
Claude can infer intent, but it can't read my mind: reference specific files, name constraints, point to example patterns, and say what "done" looks like. The more precise the prompt, the fewer corrections I'll need.
Context: @ Files, URLs, Pipes
Accessible via: @ in the prompt
@path/to/filemakes the agent read that file before answering, instead of me describing where code lives@"pr-reviewer (agent)"guarantees a specific subagent runs- URLs: give it the docs or API reference page to read
- Pipes (headless):
cat error.log | claude -p "explain this error" - Or let it fetch what it needs: "read the tests first", "check git log for this file"
Look at @src/report.py and @tests/test_report.py. Add a --format option that supports json
and csv, following the pattern the existing --output option uses.Saved Prompts: / Commands and Skills
Accessible via: / in the prompt
- Built-in commands control the session:
/clear,/compact,/context,/rewind,/init,/code-review - A skill is a saved prompt: if I keep typing the same prompt to start a task, save it as a skill
- Skills take arguments:
/fix-issue 1234passes1234in as$ARGUMENTS
/review-diffBe Specific
Four upgrades, each turns a guess into an instruction
- Scope the task: which file, which scenario, any preferences
- Point to sources: tell it where the answer lives
- Reference existing patterns: name a file to copy the style from
- Describe the symptom: what happens, where to look, what "fixed" means
Before: add tests for foo.py
After: write a test for foo.py covering the edge case where the user is logged out. avoid mocks.
Before: why does ExecutionFactory have such a weird api?
After: look through ExecutionFactory's git history and summarize how its api came to be
Before: add a calendar widget
After: look at how existing widgets are implemented on the home page. HotDogWidget.php is a
good example. follow that pattern to build a calendar widget
Before: fix the login bug
After: users report that login fails after session timeout. check the auth flow in src/auth/,
especially token refresh. write a failing test that reproduces the issue, then fix itTicket Style Prompts
Write the prompt like a ticket for another engineer: no loose ends
- context + scope + named files + constraints + examples + done criteria + boundaries
Weak:
Add slugify.
Strong:
In src/text.py, add slugify(text) that lowercases, trims, collapses spaces to single hyphens,
and drops punctuation. Follow the style of the other helpers in that file. The tests in
tests/test_slugify.py define done; run the full suite when finished. Don't change other files.Verify and Fix Root Causes
Give it a check it can run, and ask for the root cause, not a hidden symptom
- without a check, "looks done" is the only signal it has, and I become the test suite
- "don't suppress the error" stops the try/except and edited-test fake fixes
The build fails with this error: [paste error]. Fix it and verify the build succeeds.
Address the root cause, don't suppress the error.Plan or Skip
Explore -> plan -> implement -> commit, but only when it's worth it
- plan when unsure of the approach, the change spans several files, or the code is unfamiliar
- if I could describe the diff in one sentence, skip the plan (avoids getting bogged down)
Shift+Tabinto plan mode,Ctrl+Gopens the plan in my editor to change it
I want to add rate limiting to the API. What files need to change, and what are two ways
to do it with tradeoffs? Create a plan, don't write code yet.Tweak and Challenge
When it misses, name what was wrong + the principle + the exact fix
- "that's wrong, fix it" teaches it nothing, the principle is what shows I understand it
- challenge choices that look off, ask why before accepting
Tweak:
It stripped the hyphens from "co-op" too. Only drop characters that aren't letters, digits,
spaces, or hyphens, then collapse repeated hyphens. Rerun the tests.
Challenge:
Why did you raise an exception here instead of returning None like the other helpers do?
What happens to callers that don't expect it to raise?Course Correct
Correct early, and start over when the thread gets muddy
Esc: stop it now, context is kept so I can redirect- typing while it works: queues a correction for its next step
/rewindor "undo that": roll back code, conversation, or both- after two failed corrections on the same issue:
/clearand write a better prompt with what I learned, a clean session beats a long one full of failed attempts /btw: ask a side question without adding it to the conversation history
/clear
In src/text.py, slugify must keep hyphens that are already in words ("co-op" -> "co-op") and
collapse repeated hyphens. Previous attempts stripped them. Tests in tests/test_slugify.py
define done.Evidence
Ask for proof, not "it works"
- reviewing output is faster than rerunning the check myself
Show me the exact command you ran and its full output, not a summary.Do and Don't
| Do | Don't |
|---|---|
| Give context: goal, files, why | Assume it knows what you're thinking |
| One task, named files, constraints | Whole feature in one prompt |
| "Done = these tests pass" | Leave done for the agent to decide |
| Input/expected output examples | Vague descriptions |
| Ask for a plan or two options first (nontrivial work) | Plan a one-line change |
| Name constraints (don't touch tests, follow pattern X) | Hope it avoids the mistakes |
| Ask it to explain reasoning and flag uncertainty | Accept confidence as proof |
| Tweak precisely, name the principle | "That's wrong, fix it" or resend the same prompt |
| Recurring instructions in CLAUDE.md once | Repeat the same correction every prompt |
| /clear after two failed corrections | Keep arguing in a muddled thread |
Abstraction
Context is the scarce resource and instructions are suggestions, so put facts in CLAUDE.md, file-specific facts in rules, procedures in skills, noisy or parallel work in subagents, and anything that MUST happen in hooks or tests.
How They Interact
+---------------------------------------------+
| MAIN SESSION (context window) |
ALWAYS LOADED -----> | system prompt |
(costs context | CLAUDE.md files (root -> cwd, concatenated)|
every session) | rules without paths: |
| auto memory (first 200 lines / 25KB) |
| skill DESCRIPTIONS + MCP tool NAMES |
| |
LOADED ON DEMAND ---> | path-scoped rules (when a matching file |
(cheap until used) | is read or edited) |
| nested subdir CLAUDE.md |
| skill BODY (when invoked) |
| MCP tool schema (when used) |
+---------------------------------------------+
| delegate ^ summary only
v |
+---------------------------------------------+
SEPARATE CONTEXT ---> | SUBAGENTS: Explore, Plan, general-purpose, |
(noise stays out) | your .claude/agents/*.md, forks |
+---------------------------------------------+
OUTSIDE THE MODEL (deterministic, the model can't talk its way past these)
+------------------+ +---------------------+ +-------------------+ +-------------+
| HOOKS | | PERMISSIONS | | CHECKPOINTS | | TESTS |
| run every time, | | mode + allow/deny | | undo file edits | | the oracle |
| exit 2 = block | | rules in settings | | (Esc Esc) | | for "done" |
+------------------+ +---------------------+ +-------------------+ +-------------+| I need... | Use | Why not the others |
|---|---|---|
| A fact the agent needs every time (test command, layout) | CLAUDE.md | Short, always loaded |
| A fact only for some files (API style, migration rules) | Path-scoped rule | Doesn't cost context until those files are touched |
| A repeatable procedure or checklist | Skill | Body loads only when used, invocable as /name |
| Research, review, or anything noisy | Subagent | Its tool output never fills my context |
| Something that MUST happen (format, block .env edits, run tests) | Hook | CLAUDE.md is context, not enforcement |
| Data or tools outside the repo | MCP | Gives the agent new tools, not just text |
| To share all of the above with a team | Plugin | One installable bundle |
The Three Questions (KNOW, HAPPEN, GUARANTEED)
A mental model for sorting every feature, not official Claude Code terminology. When you reach for a feature, first ask which question you're answering, then pick the cheapest feature that answers it.
KNOW HAPPEN GUARANTEED
(what's in its head) (where the work runs) (what can't be skipped)
+----------------------+ +----------------------+ +----------------------+
| CLAUDE.md | | Main session | | Tests |
| Rules | | Subagents | | Hooks |
| Auto memory | | Forks | | Permissions |
| Skills | | Worktrees + parallel | | Checkpoints + git |
| Prompt + TASK.md | | sessions | | |
| MCP (outside data) | | Headless (CI) | | |
+----------------------+ +----------------------+ +----------------------+
cost: context tokens cost: coordination cost: setup time
risk: ignored or stale risk: lost context, risk: none at runtime,
instructions merge conflicts it just runs1. What Does the Agent KNOW? (Context)
- Everything that shapes its decisions is text in its context window
- if it isn't in context, the agent doesn't know it, if it IS, the agent may follow it literally (good or bad)
- Members, cheapest to most persistent:
- Prompt: this turn only, gone after /clear or compaction
- TASK.md / task file: survives /clear, but only if it's told to re-read it
- CLAUDE.md: loaded every session, facts and rules
- Rules: loaded every session, or only for matching paths
- Skills: description always, body only when used
- Auto memory: the agent's own learnings
- MCP: lets it fetch knowledge from outside the repo
- Tradeoff: always-loaded = always paid for in tokens, and more text = lower adherence
- Failure mode: it knows something WRONG (planted or stale instruction) or forgets something (lost in compaction)
- Decision:
- needed every time -> CLAUDE.md
- needed for some files -> path-scoped rule
- needed as a procedure -> skill
- needed once -> prompt
- Interview line: "I'm putting this in CLAUDE.md so it applies every turn, not just this prompt"
# Prompt: audit what it knows
What instructions are you currently following from CLAUDE.md or other loaded
files? List any that conflict with each other or with the task.2. Where Does the Work HAPPEN? (Execution)
- Every piece of work runs in some context, and that context fills up with whatever the work produced (file reads, logs, search results)
- Members:
- Main session: where you steer, keep it clean for decisions
- Subagents: fresh context, do the noisy work, return only a summary
- Explore for search, a reviewer for diffs, general-purpose for multi-step
- Forks: subagent that starts with a copy of the current conversation
- Worktrees + parallel sessions: separate copies of the repo, separate agents, no file collisions
- Headless (
claude -p): runs with no one watching, in scripts or CI
- Tradeoff: more isolation = cleaner context, but more coordination and things to merge
- Failure mode: the main context bloats and forgets, or parallel agents edit the same files
- Decision:
- noisy or exploratory -> subagent
- needs fresh eyes -> subagent that didn't write the code
- independent tasks, lots of time -> worktrees in parallel
- judgment calls and steering -> main session
- Interview line: "I'm sending the search to a subagent so my main session only gets the answer"
# Prompt: move noisy work out of the main session
Use the Explore agent to find every place money is parsed or converted.
Return file:line references only.3. What Is GUARANTEED? (Enforcement)
- Instructions are suggestions: the model usually follows them, but nothing forces it
- Guarantees live outside the model, so it can't decide to skip them
- Members:
- Tests: the oracle for "done", green or red, no opinion involved
- Hooks: run at every lifecycle event,
PreToolUsewith exit 2 BLOCKS the action- ex: always format after edits, never touch
.env, always run tests before stop
- ex: always format after edits, never touch
- Permissions: the mode (Manual, Accept edits, Plan, Auto) + allow/deny rules
- Checkpoints + git: whatever happens to files can be undone
- Tradeoff: takes setup time, but costs nothing at runtime and never "forgets"
- Failure mode: treating a KNOW feature as a GUARANTEE
- ex: "CLAUDE.md says run tests" does NOT mean tests ran, check the output yourself
- Decision: if breaking it would be bad (money, secrets, deleted data, shipping red tests), move it from KNOW to GUARANTEED
- Interview line: "CLAUDE.md asks it to run tests, but I'm verifying the output myself, in a real repo this would be a hook or a CI gate"
# Prompt: turn a rule into a guarantee
Add a PreToolUse hook in .claude/settings.json that blocks any Edit or Write
to files under tests/ unless I approve it, and explain how it works.| Situation | Wrong bucket | Right bucket |
|---|---|---|
| "Tests must pass before I commit" | KNOW: a line in CLAUDE.md | GUARANTEED: run them yourself, or a hook / CI gate |
| "Search the whole repo for callers" | HAPPEN: main session (fills context) | HAPPEN: Explore subagent |
| "Our test command is pytest -q" | GUARANTEED: a hook | KNOW: CLAUDE.md |
| "Review this diff" | HAPPEN: same session that wrote it | HAPPEN: reviewer subagent |
| "Never edit .env" | KNOW: please don't | GUARANTEED: PreToolUse hook or deny rule |
| "Follow this 6-step release checklist" | KNOW: pasted every time | KNOW: skill, loaded when needed |
Interview Walkthrough
1. Agentic Loop
- The agent works in a loop: gather context -> take action -> verify results, repeat
- ex: "fix the failing tests" = run tests, read errors, search, read files, edit, rerun tests
- Model = reasons, harness = the tools and context management around it
- You are part of the loop: interrupt any time
Escstops it immediately, typing while it works queues a correction for its next step
- Interview angle: "My job is to make the verify phase real, tests and a reviewer, not just the agent's opinion of its own work"
2. Context Window
- Everything the model sees right now: conversation, file contents, command output, CLAUDE.md, loaded skills, system instructions
- It fills up, then auto-compacts (old tool output cleared, conversation summarized)
- instructions from early in the chat can get lost -> persistent rules go in CLAUDE.md
- Commands:
/context: see what's using space/compact focus on X: summarize now, keeping what I care about/clear: fresh start between unrelated tasks
- Interview angle: "I clear between tasks and keep rules in CLAUDE.md, so a long session doesn't quietly forget my constraints"
# Prompt: check what's loaded (also confirms CLAUDE.md was picked up)
/context
# Prompt: compact before a new level, keeping what matters
/compact focus on the Account API, the money rules, and the remaining tasks3. CLAUDE.md (Memory You Write)
- Onboarding note the agent reads at the start of every session: commands, layout, rules, gotchas
- Locations, all concatenated (not overriding), closest to your cwd read last:
~/.claude/CLAUDE.md: you, every project./CLAUDE.mdor./.claude/CLAUDE.md: the project, shared via git./CLAUDE.local.md: you, this project, gitignored- subdirectory CLAUDE.md files load on demand when the agent works in that folder
@path/to/fileimports another file (still loads at launch, so no context savings)- Keep it under ~200 lines, longer = more context and LOWER adherence
- It is context, not enforcement: the agent usually follows it, but can't be forced to
- "must always happen" -> hook or test
/initgenerates a starter,/memoryto edit, AGENTS.md is read if there's no CLAUDE.md- Interview angle: the planted-instructions trap lives here, fixing it = steering at the root
<!-- Interview-sized CLAUDE.md: commands, layout, rules -->
## Commands
- Tests: pytest -q
## Layout
- src/ledger.py: balances and transfers
- src/report.py: CSV -> per-product JSON summary
## Rules
- Explain your plan before editing; keep diffs small and focused
- Run the full test suite after every change; done = tests pass
- Never change a test just to make it pass; tell me instead
- Money: Decimal or integer cents with explicit rounding, never float4. Rules (.claude/rules/)
- Split a growing CLAUDE.md into topic files:
testing.md,api-design.md,money.md - Without
paths:frontmatter -> loads every session, same as CLAUDE.md - With
paths:-> loads only when the agent reads or edits a matching file- saves context, keeps instructions relevant
~/.claude/rules/for personal rules across all projects- Interview angle: rarely needed in 60 minutes, but naming it shows you know how instructions scale
<!-- File: .claude/rules/money.md -->
<!-- - only loads when the agent touches ledger or report code -->
---
paths:
- "src/ledger/**/*.py"
- "src/report/**/*.py"
---
# Money rules
- Parse amounts with Decimal from the original string, never float
- Round to cents with ROUND_HALF_UP
- Store and compare integer cents5. Auto Memory (Memory the Agent Writes)
- The agent saves its own notes from your corrections and preferences, per repo
- Loaded every session (first 200 lines or 25KB)
- CLAUDE.md = your instructions, auto memory = its learnings
- Interview angle: mostly irrelevant in a fresh CodeSignal environment, know it exists
6. Skills (Reusable Procedures)
- A folder with
SKILL.md: frontmatter + instructions, plus optional scripts and reference files - Progressive disclosure: the DESCRIPTION is always loaded, the BODY only when invoked
- long reference material costs almost nothing until needed
- Invoked by the agent automatically (description matches the task) or by you with
/skill-name - Custom slash commands were merged into skills (
.claude/commands/x.mdstill works as/x) - Useful frontmatter:
description: when to use it, this is what the agent matches ondisable-model-invocation: true: only you can run it (side effects like deploys)context: fork: run it in a subagent with its own context
!`git diff HEAD`in the body runs the command and injects its output first- When to make one: you keep pasting the same checklist, or a CLAUDE.md section became a procedure
- Interview angle: check what exists with
/help, use one if it fits, don't build from scratch in 60 minutes
<!-- File: .claude/skills/review-diff/SKILL.md -->
<!-- - /review-diff, or the agent loads it when I ask for a review -->
---
description: Reviews uncommitted changes for bugs, weakened tests, and scope creep. Use before committing.
---
## Current changes
!`git diff HEAD`
## Instructions
1. List each file changed and why
2. Flag any test that was edited, loosened, or deleted
3. Flag changes outside the task's scope
4. Check edge cases: empty, zero, negative, missing ids
5. Blocking issues first, then nits7. Subagents (Separate Context Windows)
- A delegated worker with its own context window, system prompt, tools, and permissions
- only its summary comes back, its file reads and logs never fill your context
- Built-ins:
Explore: fast, read-only codebase searchPlan: read-only research behind plan modegeneral-purpose: multi-step tasks that need to read and act
- Custom:
.claude/agents/<name>.md(project) or~/.claude/agents/(you), onlyname+descriptionrequired, plustools,model,permissionMode,isolation: worktree, etc. - Invoked automatically from its description, by asking ("use the pr-reviewer agent"),
or guaranteed with
@"pr-reviewer (agent)" - Forks: a subagent that starts with a copy of the conversation so far
- Subagents can spawn subagents (limited depth), so orchestrator -> workers is possible
- Interview angle: research and review are the two best delegations
- "The reviewer didn't write this code, so it won't defend it"
<!-- File: .claude/agents/pr-reviewer.md -->
---
name: pr-reviewer
description: Strict read-only review of the current diff. Use after every change, before committing.
tools: Read, Grep, Glob, Bash
---
You review code you did not write. Run git diff and the test suite.
Report blocking issues first: correctness, edge cases, weakened tests,
scope creep, money handling. Never edit files.8. Hooks (Guarantees, Not Suggestions)
- Shell commands the harness runs at lifecycle events, every time, no model choice involved
- Configured in
.claude/settings.json(view with/hooks) - Common events:
PreToolUse: before a tool runs, can BLOCK it (exit code 2, reason on stderr)PostToolUse: after a tool succeeds, ex: format or lint the edited fileUserPromptSubmit,Stop,SubagentStop,SessionStart,PreCompact,Notification
- A
PreToolUsedeny blocks even in the most permissive mode - CLAUDE.md "please don't edit .env" = a request, a PreToolUse hook = a wall
- Interview angle: "If this rule were critical I'd make it a hook, CLAUDE.md is context, hooks are enforcement" (one of the clearest 2026 signals)
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write" }
]
}
]
}
}9. Permission Modes and Settings
Shift+Tabcycles the modes:- Manual: asks before edits and shell commands
- Accept edits: edits files without asking, still asks for other commands
- Plan: explores and proposes a plan, no source edits
- Auto: a classifier approves safe actions and blocks risky ones
- Allow/deny specific commands in
.claude/settings.json(ex: allowpytest,git status) - Interview angle: say which mode and why
- plan for orientation, manual or accept edits for small reviewed steps, auto only for well-scoped work you'll review afterward
10. Checkpoints and Rewind
- Before every edit the harness snapshots the file
EscEscto rewind to an earlier point, or ask it to undo- Separate from git, covers file edits only (not databases, APIs, deploys)
- Interview angle: "It went off the rails, I'm rewinding to before that change and re-prompting narrower" beats arguing with it for five minutes
11. MCP (Model Context Protocol)
- Open standard for connecting external tools and data: databases, issue trackers, docs, browsers
- Configured per project in
.mcp.json(or user/local scope) - Tool definitions are deferred and loaded on demand, so many servers stay cheap
- Interview angle: likely not available in CodeSignal, but "in a real setup I'd connect the issue tracker so it reads the ticket directly" shows the bigger picture
12. Plugins
- One installable bundle of skills, subagents, hooks, MCP servers, and commands
- Plugin skills are namespaced:
/my-plugin:review - How teams share a working setup (ex: a "superpowers"-style workflow plugin)
- Interview angle: don't depend on installing one in the interview
13. Sessions, Worktrees, and Headless
- Sessions are saved:
claude --continue(latest) or--resume(pick one),/branchto fork - Parallel work: one git worktree per task, one session per worktree, no file collisions
- Headless:
claude -p "..."runs non-interactively for scripts and CI - Interview angle: know they exist, but not needed in a 60 minute round
14. Concepts You May Be Missing
- Verification is the bottleneck: the agent writes fast, so the tests, scripts, and reviewers that check it ARE the engineering (tests are the oracle for "done")
- Context engineering > prompt engineering: what's loaded (and what isn't) shapes output more than clever wording
- Determinism ladder: prompt < CLAUDE.md < skill < hook/test
- the more it must happen, the further right it goes
- Non-determinism: same prompt, different result, so never trust one run, verify each time
- Orchestrator -> workers: a lead session plans and delegates, workers execute in isolation, the lead reviews and merges
- Build the factory: have the agent write generators, checkers, and scripts, not 30 outputs
- Blast radius: small scoped diffs, read-only agents for research, checkpoints and git to undo, permissions to fence off dangerous actions
- Hallucination: invented APIs, flags, file paths, check unfamiliar ones against code or docs
- Prompt injection: the agent follows instructions from ANY text it reads (repo files, web pages, issues), a planted CLAUDE.md is exactly this, read what it's being told
- Model and effort choice:
/modelto switch, bigger model for hard reasoning, faster model for simple or high-volume subagent work - Cost and tokens: everything always-loaded is paid on every turn, keep it lean
- AGENTS.md: cross-tool instruction file, Claude Code reads it when there's no CLAUDE.md
15. If Asked: Follow-ups
- "What's the difference between CLAUDE.md and a skill?": CLAUDE.md is facts loaded every time, a skill is a procedure loaded only when needed
- "Why a subagent instead of just asking in the main chat?": its search output and file reads stay out of my context, and a reviewer that didn't write the code is more critical
- "How would you make sure tests always run?": a hook (or CI gate), because instructions are suggestions and hooks are guarantees
- "How do you keep a long session on track?": rules in CLAUDE.md, /clear between tasks, /compact with a focus, TASK.md for the task and plan
Sources
- How Claude Code works
- Memory: CLAUDE.md, rules, auto memory
- Skills
- Subagents
- Hooks guide
- MCP
- Plugins
Section 1. Setup and Understand New Repo
Topics: Orientation, Check the Tool, Instructions File, Conventions Audit, Agent Roles, Checkpoints
Intro
You're dropped into an unfamiliar repo with a task file. Before any feature or bug work, understand what the code does, how it's tested, and what the agent is being told (CLAUDE.md, README, conventions). The tool may be full-featured (subagents, skills, hooks, plan mode) or bare (it can read, edit, and maybe run commands, nothing else). "Check the tool" decides which way each step goes. Either way, setup ends with the same six roles in place, so scenarios 2 and 3 run the same. Budget: about 10 minutes.
| Input | Output |
|---|---|
| Repo + task from the interviewer, maybe a README or CLAUDE.md, a full or bare agent | I can explain the repo, tests run green (or known red), and the six roles are set up |
Abstraction
Understand before building: check the tool, map the repo, baseline the tests, treat the instructions file as a suspect, then set up the six roles with whatever the tool supports.
The six roles (same job either way, only the tool feature changes):
- Instructions the agent follows every time
- full: CLAUDE.md, or whichever file the tool reads (AGENTS.md, .cursor/rules)
- bare: TASK.md, and "Read TASK.md first" at the start of key prompts
- Research without cluttering my context
- full: the built-in Explore agent
- bare: narrow "file:line references only" prompts, findings saved to TASK.md, then a fresh conversation so the findings in TASK.md carry over and the noise doesn't
- Plan before editing
- full: plan mode
- bare: "Don't edit any files yet. Read and propose a plan." then I approve it
- Reviewer that didn't write the code
- full: a pr-reviewer subagent, or the bundled
/code-review - bare: a fresh conversation given
git diffand a reviewer prompt, or my own read out loud
- full: a pr-reviewer subagent, or the bundled
- Undo and enforcement
- full: checkpoints (
/rewind), hooks if worth the setup - bare: commit after every green step (git is my checkpoint), and I run the checks myself
- say it: "Normally a hook would do this, here I'm the hook"
- full: checkpoints (
- Running checks (tests, git)
- full: the agent runs them and shows the output
- bare and it can't run commands: I run them in the terminal and paste the output back, and I make the commits myself
The solutions are steps, not alternatives: do 1, then 2, then 3 (about 10 to 15 minutes total). This scenario is Interview Todos 1 to 4, the once-at-the-start steps.
What never changes, full or bare: clarify, failing tests first, small steps, full suite, read every diff, think out loud. That's most of what's graded, the tool features just make it faster.
Interview Walkthrough
1. Main Answer: Solution 1 (Orientation in 10 Minutes)
- Interview Todos: 1 Clarify And Restate The Requirements, 2 Check The Tool, 3 Orient Before Changing Anything (Intro > Interview Todos)
- Read the task, clarify, restate
- Check the tool: it may not be Claude Code ("e.g., Claude Code"), so ask it what it has
- which tool and model, built-in subagents (ex: Explore), skills, slash commands, permission modes
- which instruction file it reads (Claude Code: CLAUDE.md, Cursor: AGENTS.md or .cursor/rules)
- Claude Code shortcut:
/help - the answer decides full or bare for every step below
- Orient before anything changes
- full: plan mode on first (Shift+Tab in Claude Code)
- bare: the prompt's "don't edit any files" line does the same job
- Run the tests for a baseline before changing anything
- "If something is already red, I want to know before I touch it"
- if the agent can't run commands, I run them in the terminal and paste the output
Check the tool
- don't assume it's Claude Code, the answer decides which features and instruction file to use
- its description of itself can be wrong (especially the model), trust the tool's UI over its answer
Before we start: which tool and model are you, and what do you have available here?
List any built-in subagents, skills, and slash commands, the permission modes I can switch
between, and which instruction file you read at the start of a session (CLAUDE.md, AGENTS.md,
or something else).Brief + orient
- situation + priorities + distrust the repo, all in one opener
- works whether or not docs exist, and with or without plan mode
I'm in a technical interview and I'll be narrating, so keep answers short
and precise. Don't edit any files or write any code yet, only read. Read any
docs that exist (README, CLAUDE.md, AGENTS.md, task or notes files) and tell
me which ones are missing.
1. Explain what this repo does in 3 to 4 sentences
2. List the folder structure, one line per file
3. Find the test command, run the full suite, report pass/fail counts
(if you can't run commands, just tell me the command)
4. Flag anything in the code, docs, or conventions that looks inconsistent or wrongTrace the main flow
Walk me from the entry point through the core modules to the output,
with file:line references for each hop.2. Instructions File: Solution 2 (Audit and Set Up)
- Interview Todos: 4 Validate The Instructions File (Intro > Interview Todos)
- Role: instructions the agent follows every time
- full: CLAUDE.md (or the file this tool reads), what it is and why: Agentic Coding Dive > Know > CLAUDE.md
- bare: TASK.md, since the agent won't load anything on its own
- Existing file? Audit it first: the agent follows it literally, bad instructions = bad code
- CLAUDE.md Validation Prompt: Agentic Coding Dive > Know > CLAUDE.md > Validation Prompt
- fixing the instruction is the strongest steering move in the interview
- ex: "CI will catch it, don't run tests locally" -> rewrite to run tests after every change
- No file? Create only what helps the agent, AFTER it has read the code
- full:
/initafter leaving plan mode (plan mode can't write files), then trim it - bare: TASK.md with task, rules, commands, and plan
- quick check with the interviewer: "Is it OK if I add a CLAUDE.md (or TASK.md) to the repo?"
- full:
- Either way, keep TASK.md for the task and plan: it survives /clear and new levels
- README: no, docs for humans, costs time, the agent's summary already covers it
Fix at the root (after I decide, say why out loud)
- the planted conventions from Solution 2, after the audit
- bare: same prompt, but the file is TASK.md
Update CLAUDE.md:
- Replace "no need to run tests locally" with: run the full suite after
every change, done = tests pass, never edit a test just to make it pass
- Replace the float conversion with: parse money with Decimal, round to
cents with ROUND_HALF_UP
- Replace hand-written fixtures with: generate fixtures with a script, plus a checker
- Commit messages describe what changed and why
Only edit CLAUDE.md, then show me its diff.Full: no instruction file -> create one from what we found (out of plan mode)
- /init scans the repo itself, then I cut it down to what I want enforced
- only what it can't figure out from the code: commands, dependencies, gotchas
/init
Now trim CLAUDE.md to under 50 lines with sections: Commands (install, test, lint),
Layout (a few lines), Dependencies (databases, APIs, env vars, config the code needs),
and Instructions:
- Explain your plan before editing; keep diffs small and focused
- Run the full test suite after every change; done = tests pass
- Never change a test just to make it pass; tell me instead
- Flag anything in the repo or task that looks inconsistent
- No refactors outside the task's scope
Show me the draft before saving.Create TASK.md (task + plan, and in bare mode the rules too)
- full: keep only the Task and Plan sections, the rules live in CLAUDE.md
- bare: keep all four, TASK.md is the instructions file
Create TASK.md with four sections:
- Task: [paste the interviewer's task exactly], plus open questions and answers so far
- Rules: explain the plan before editing; keep diffs small; never change a test just to
make it pass, tell me instead; flag anything inconsistent; no refactors outside the task
- Commands: the test command and anything else needed to run the project
- Plan: a checklist we update as we finish each step
Show it to me before saving.Bare: start every key prompt with it
Read TASK.md first, then [the next step].3. Agent Roles: Solution 3 (Research, Reviewer, Checkpoints)
- Interview Todos: sets up the helpers for 3 Orient Before Changing Anything, 5 Plan Before Editing, 8 Read Every Diff And Ask Why, 9 Close The Loop, and checks for 11 Use Existing Skills (Intro > Interview Todos)
- Set up the remaining roles in 2 to 3 minutes, don't build infrastructure for 15 (that reads as bogged down)
- Main session = where I steer and code, either way
- Research
- full: the built-in Explore agent, no setup
- bare: narrow prompts, save findings to TASK.md, fresh conversation when context gets noisy
- Reviewer
- full: a read-only pr-reviewer subagent, or
/code-reviewif bundled - bare: the fresh-conversation review prompt below
- full: a read-only pr-reviewer subagent, or
- Undo and enforcement
- full: checkpoints are automatic, still commit after each green step
- bare: commit after every green step, and I run tests + read
git diffevery time
- How the full-featured roles differ and why: Agentic Coding Dive > Agents and Context Windows
Clean baseline commit (both)
- known starting point, so every later change is a reviewable diff
git add -A && git commit -m "Baseline before changes"Full: create the reviewer
- prompt: Agentic Coding Dive > Happen > Subagents > Init Prompt
- full agent files: Solution 3 below
Bare: fresh-conversation review (instead of a reviewer subagent)
- new conversation or terminal, so it has no attachment to the code it's reviewing
- point it at the diff, it reports and doesn't edit
You're reviewing code you didn't write. Read TASK.md for the task, then review the output
of `git diff`. Report blocking issues first: correctness, edge cases, any test that was
edited, loosened, or deleted, and changes outside the task. Don't edit any files.4. If Asked: Follow-ups
- Interview Todos: 10 Think Out Loud And Adapt (Intro > Interview Todos)
- "Why subagents?": separate context windows, research noise doesn't pollute the coding session, and a reviewer that didn't write the code doesn't defend it (Agentic Coding Dive > Agents and Context Windows > Interview Angle)
- "What if the tool has none of that?": same roles, filled by hand, TASK.md for instructions, fresh conversations for research and review, git commits for checkpoints
- "Why not just read the code yourself?": I do read the key files, the agent gets me the map faster, then I verify the map against the code
- "How do you know the tests actually ran?": I ran them myself, or I asked for the command and its full output, not a summary
- "What if the agent flags a convention as wrong?": don't wave it off, ask why, decide deliberately, say the reasoning out loud
When the agent objects to a convention
You flagged the conversion rule as risky. Explain exactly what goes wrong,
with a concrete input and output, and what you'd replace it with.Solution 1: [Orientation] First 10 Minutes - Setup/Understanding
Always do this first. Understand the task, the tool, the repo, and the tests before the agent changes anything.
- Output: I know full or bare, and I can explain what the repo does, where the task fits, and what's already broken
Step 1: Clarify (out loud, before touching the keyboard)
- inputs, outputs, edge cases, what "done" means
- ex: "When an account doesn't exist, return false or raise?"
Step 2: Check the tool
- the guide says "e.g., Claude Code", so don't assume, ask the tool what's available
- the answer decides full or bare, which features I can use, and which instruction file to write
- Claude Code shortcut:
/help - prompt: "Check the tool" in walkthrough 1
Step 3: Brief the agent
- full: plan mode on first (Shift+Tab until "plan mode")
- bare: no plan mode, the "don't edit any files" line in the prompt does the job
- prompt: "Brief + orient" in walkthrough 1
Step 4: Map the repo
- one line per file, so I know where changes belong
Show the folder structure with one line per file describing what it does.Step 5: Trace the main flow
Walk me from the entry point through the core modules to the output,
with file and line references.Step 6: Baseline the tests
- known red before I start != red I caused
- bare and can't run commands: I run it in the terminal and paste the output
Find the test command and run the full suite. Report pass/fail counts.Step 7: History and style
git log --oneline -10Step 8: Summarize out loud
- "This repo does X, the task touches Y, the risks I see are Z, and the tool is full / bare"
Solution 2: [Instructions] Audit and Set Up the Instructions File - Setup/Steering
Do this right after orienting. Read what the agent is being told, fix bad instructions at the root before they turn into bad code, and make sure there's one file the agent follows every time.
- Output: an instructions file I trust (CLAUDE.md, or TASK.md if bare), with the reasoning for each change said out loud
- Below: an example of planted conventions (BEFORE) and the fixed file (AFTER), then the bare steps
<!-- BEFORE: planted / tired-team conventions, each one wrong -->
<!-- - agent follows these literally, so each one becomes a bug or a red flag -->
- Short commit messages are fine (wip, update). This repo squash-merges anyway.
- CI runs the suite on every push, no need to run it locally.
- Keep expected-output fixtures hand-written and checked in.
- Revenue is integer cents: cents = int(float(value) * 100). No need for Decimal.
<!-- AFTER: fixed at the root, say WHY for each change out loud -->
## Conventions
<!-- Commits: real messages, wip hides what changed and signals nobody is reading -->
- Commit messages describe what changed and why.
<!-- Testing: "CI will catch it" means the agent never verifies its own work -->
<!-- - interlocks with the money bug: bad conversion + no tests = silent bug -->
- Run the full test suite after every change. Done = tests pass.
- Never edit a test just to make it pass; report it instead.
<!-- Fixtures: derivable outputs should come from a generator + checker -->
<!-- - "build the factory" instead of hand-typing 30 JSON files -->
- Generate expected-output fixtures with a script; review the script and a sample of outputs.
<!-- Money: int(float("1.15") * 100) == 114, float is imprecise and int() truncates -->
- Money: parse with Decimal, convert to cents with ROUND_HALF_UP. Never float.
## Working rules
- Explain the plan before editing; keep diffs small and in scope.
- Flag anything inconsistent instead of guessing.| Convention trap | What it probes | Fix |
|---|---|---|
| "Don't run tests locally" | Closing the loop | Run tests after every change |
int(float(v) * 100) | Verifying, money precision | Decimal + explicit rounding |
| "Hand-write fixtures" | Tooling judgment | Generator + checker |
| "wip commits are fine" | Oversight (are you reading?) | Real commit messages |
Bare: Step 1, create TASK.md
- the "Create TASK.md" prompt from walkthrough 2, all four sections
Bare: Step 2, audit any instruction file the tool doesn't load
- same questions as the CLAUDE.md Validation Prompt, then copy what's correct into TASK.md
Bare: Step 3, re-anchor after every fresh conversation
- first prompt in any new conversation: "Read TASK.md first"
Solution 3: [Roles] Research, Reviewer, Checkpoints - Setup/Multi Agent
Do this last, in 2 to 3 minutes. Set up the helpers and habits I'll use for every task in the hour.
- Output: a research path, a reviewer, and a baseline commit
- Below: the full-featured agent files and how I use them, then the bare manual loop
Full: agent files
- Explore is built in, so the custom researcher is optional
- create with the tool, or write the files directly
<!-- File: .claude/agents/researcher.md (optional, Explore does the same job) -->
---
name: researcher
description: Read-only codebase research. Use to find where something lives, how a pattern is used, or what calls a function. Reports findings with file and line references.
tools: Read, Grep, Glob
---
You are a read-only researcher. Never edit files.
Answer the question asked with file:line references.
Say when you are unsure instead of guessing.
Keep the report short: findings first, then evidence.
<!-- File: .claude/agents/pr-reviewer.md -->
---
name: pr-reviewer
description: Reviews the current diff like a strict PR reviewer. Use after every change, before committing.
tools: Read, Grep, Glob, Bash
---
You review code you did not write. Run `git diff` and the test suite.
Check, in order:
1. Correctness and edge cases (empty, null, duplicates, boundaries)
2. Tests: were any weakened, deleted, or special-cased to pass?
3. Scope: changes outside the task
4. Consistency with existing patterns and CLAUDE.md
Report blocking issues first, then nits. Do not edit files.Full: research during a task
- research runs in its own context, main session stays clean
Use the Explore agent: where is this function defined, and what calls it?
Return file:line references only.Full: review before commit
- after the main session finishes a change, before commit
Use the pr-reviewer agent to review the current diff.Bare: the manual loop for every task
- prompt -> I read
git diff-> I run the full test suite -> I check no test was weakened -> fresh-conversation review (walkthrough 3) -> commit with a real message - the commit is my checkpoint:
git checkout -- <file>orgit stashto undo
Say why out loud
- full: "I'm sending research to a subagent so it doesn't fill up my main context"
- full: "The reviewer didn't write this code, so it's more likely to catch problems"
- bare: "No reviewer agent here, so I'm using a fresh conversation that didn't write the code"
- bare: "Normally a hook would run the tests, here I'm the hook"
Section 2. Build New Feature
Topics: Requirements, Planning, Tests First, Prompting, Code Review
Intro
Implement new behavior on top of existing code. Often incremental (CodeSignal levels): Level 1 basic operations, Level 2 adds a query, Level 3 adds history or time, Level 4 adds undo/rollback. Each level builds on your earlier code, so design and tests from Level 1 pay off later. Uses the six roles from 1. Setup (instructions, research, plan, reviewer, undo, running checks), full or bare. Any prompt that says "run" or "commit": if the agent can't, I do it and paste the output.
| Example Input | Output |
|---|---|
"Add withdraw(account, amount): reject overdrafts and non-positive amounts" | Method + tests, full suite green, reviewed diff, real commit |
Abstraction
Turn the requirement into acceptance examples, find where similar code already lives, agree on a plan, write failing tests, then implement in small ticket-style prompts with a review and full test run after each.
The solutions are layers of one process, not alternatives: Solution 1 is the order of steps, and Solutions 2, 3, and 4 zoom in on the moments where judgment shows (prompting, design, review). This scenario is Interview Todos 5 to 9, the every-task loop.
Interview Walkthrough
1. Main Answer: Solution 1 (Requirements -> Tests -> Small Steps)
- Interview Todos: 1 Clarify And Restate The Requirements, 5 Plan Before Editing, 6 Build The Testing Suite For The Plan (Intro > Interview Todos)
- Restate, clarify, write acceptance examples out loud (input -> expected output)
- these become the tests, and prove I understood the ask
- Research where similar functionality lives, follow existing patterns
- Map the blast radius: which files change, what calls them
- Tests first, then implement one step at a time, full suite after each
- Standards used: Agentic Coding Dive > Prompting > Be Specific, Plan or Skip, and Output Verification > Failing Test First
Research + blast radius (plan role, no code)
- full: in plan mode, or send it to the Explore agent
- bare: this prompt as is (it says no code), then save the findings to TASK.md
I need to add withdraw(account, amount) that rejects overdrafts and
non-positive amounts. Before we plan: where does similar functionality
(deposit, transfer) live, what patterns should this follow, and which files
would change? File:line references, no code yet.Plan
Propose a step-by-step plan for withdraw based on that. Keep each step
small enough to review in one diff. Wait for my approval.Tests first (todo 6: propose, approve, then write)
- acceptance examples become the done criteria, plus edge cases the chosen plan adds
For the plan we chose, propose the test suite: the acceptance cases below, edge cases this
approach adds, and whether each is a unit test or should come from a generator.
Wait for my approval.Write the approved tests as failing tests in tests/test_account.py, including these cases:
- withdraw(1, 50) on balance 100 -> True, balance 50
- withdraw(1, 150) on balance 100 -> False, balance unchanged
- withdraw(1, 0) and withdraw(1, -5) -> False
- withdraw(99, 10) on a missing account -> False
Don't implement anything. Run them and show me they fail for the right reason.2. Prompting: Solution 2 (Ticket-Style Prompts)
- Interview Todos: 7 Ticket Style Prompts, 8 Read Every Diff And Ask Why (Intro > Interview Todos)
- Follows the Agentic Coding Dive > Prompting standards (Ticket Style Prompts, Tweak and Challenge)
- Below: those standards applied to this feature
Implement one step (ticket style)
- context + scope + constraints + done criteria + boundaries
In account.py, add withdraw(amount) to Account. Reject non-positive amounts
and overdrafts by returning False without changing the balance. Use Decimal,
matching deposit. The new tests in tests/test_account.py define done; run
the full suite when finished. Don't change any other files.Tweak when it misses
- name the problem + the principle + the exact fix
It converted with int(float(x) * 100). That truncates: 1.15 becomes 114
cents because 1.15 isn't exact in binary float. Parse with Decimal and
quantize with ROUND_HALF_UP instead, then rerun the full suite.Challenge a choice
Why did you raise an exception here instead of returning False like
deposit does? What happens to callers that expect a bool?3. Design Choice: Solution 3 (Ask for Two Approaches)
- Interview Todos: 5 Plan Before Editing (Intro > Interview Todos)
- Have the agent propose two options with tradeoffs, I pick and say why (Agentic Coding Dive > Prompting > Plan or Skip)
- Shows judgment, and the next level usually rewards the extensible option
- ex: transaction history -> a list of records beats patching balance fields
Options before code
Before coding, give me two ways to add transaction history, with tradeoffs
for likely follow-ups: filtering by time and undoing a transaction.
Keep each option to a few lines. Don't implement either yet.Commit to one (after choosing out loud)
Go with option B, a list of Transaction records. Plan it in small steps
with tests first, and wait for my approval.4. Review: Solution 4 (Diff Checklist + Reviewer)
- Interview Todos: 8 Read Every Diff And Ask Why, 9 Close The Loop (Intro > Interview Todos)
- Read every line: patterns, scope, edge cases, names, tests not weakened
- Reviewer role as a second opinion, then commit (the commit is also my checkpoint)
- full: pr-reviewer subagent or
/code-review, bare: fresh conversation +git diff(Agentic Coding Dive > Output Verification > Reviewer Subagent, Evidence)
- full: pr-reviewer subagent or
Diff summary before I read it
Summarize the current diff: every file changed and why. Call out anything
outside the task's scope and any test you added, changed, or deleted.Second opinion + full suite
- bare: run the tests myself, and paste the review prompt from 1. Setup into a fresh conversation
Use the pr-reviewer agent on the current diff, then run the full test suite.Commit
Commit with a message that says what changed and why.5. If Asked: Follow-ups
- Interview Todos: 10 Think Out Loud And Adapt, new level -> back to 1 Clarify And Restate The Requirements (Intro > Interview Todos)
- "Why tests first?": done criteria the agent can't argue with, catches it changing behavior I didn't ask for
- "Why not one prompt for the whole feature?": small diffs are reviewable, big ones get rubber-stamped
- "Next level changes the requirement?": restate, update the plan, rerun the whole suite, the earlier tests protect the earlier levels
Next level / changed requirement
New requirement: [paste]. Restate it in your own words, list which existing
behavior and tests it affects, and update the plan. Don't code until I agree.Solution 1: [Feature] Requirements -> Tests -> Small Steps - Feature/Planning
The full process, in order: requirements -> acceptance examples -> plan -> failing tests -> small steps.
- Output: the feature, its tests, a green suite, a reviewed diff
Step 1: Restate and clarify (out loud)
- "So withdraw takes an account id and an amount, returns true on success"
- Questions: missing account? zero amount? negative? partial withdraw?
Step 2: Acceptance examples (these become the tests)
- withdraw(1, 50) on balance 100 -> true, balance 50
- withdraw(1, 150) on balance 100 -> false, balance unchanged
- withdraw(1, 0) / withdraw(1, -5) -> false
- withdraw(99, 10) missing account -> false
Step 3: Find existing patterns (plan role, or the research role)
Where does similar functionality live (deposit, transfer)? What patterns,
error handling, and types should withdraw follow? File and line references.Step 4: Blast radius
Which files would change for withdraw, and what calls them?Step 5: Plan, agree, break into steps
- push back until I agree, but keep it brisk
Step 6: Tests first
Write failing tests in tests/test_account.py for these cases: [paste examples].
Don't implement anything yet. Run them and show me they fail.Step 7: Implement one step (Solution 2 prompt), review diff, run full suite
Step 8: Reviewer role, commit, update the instructions file (CLAUDE.md or TASK.md) if something was learned
While it runs
- "Here's how I'd write it by hand: look up the account, validate, subtract..."
Solution 2: [Prompting] Ticket-Style Prompts and Tweaks - Feature/Prompting
Zooms in on Solution 1's implement step: how the prompt for each small step is written.
- Output: a weak vs strong prompt for this feature
Weak
- no files, no constraints, no done criteria, agent guesses everything
Add withdrawals.Strong
- context + scope + constraints + examples + done criteria + boundaries
In account.py, add withdraw(amount) to Account. Reject non-positive amounts
and overdrafts by returning False without changing the balance. Use Decimal,
matching deposit. The tests in tests/test_account.py define done; run the
full suite when finished. Don't change any other files.Tweak and challenge prompts for this feature: walkthrough 2 above Standards and Do and Don't: Agentic Coding Dive > Prompting
Solution 3: [Design] Two Approaches With Tradeoffs - Feature/Design
Zooms in on Solution 1's plan step: get options before code when the design choice matters.
- Output: two approaches, my pick, and why (usually the one the next level builds on)
Ask for options instead of accepting the first design
- shows judgment, sets up the next incremental level
Before coding, give me two ways to add transaction history, with tradeoffs
for later features like filtering by time and undo.Example answer to reason about out loud
- Option A: append a counter / last_transaction field on Account
- simplest, but can't filter or undo, next level forces a rewrite
- Option B: list of Transaction records (type, amount, timestamp, ids)
- slightly more code now, filter = scan records, undo = reverse a record
- -> "I'll take B, the levels in this format usually build on history"
Solution 4: [Review] Diff Checklist + Reviewer - Feature/Verification
Zooms in on Solution 1's last step: how I review before anything is committed.
- Output: a diff I've read, a full green suite, a second opinion, a real commit
Read every line of the diff myself (git diff), narrate as I go
- Does it follow the existing patterns? (types, return style, naming)
- In scope? (no surprise refactors in other files -> revert them)
- Edge cases? (empty, zero, negative, missing id, same account)
- Tests: added, not weakened, not deleted, not special-cased
- Complexity: any nested loop where a dict lookup would do?
Full suite, not just the new tests (regressions in earlier levels)
Run the full test suite and report the results.Second opinion
- full: the prompt below, bare: fresh-conversation review from 1. Setup
Use the pr-reviewer agent on the current diff.Commit
- "Add Account.withdraw with overdraft and non-positive checks"
Section 3. Find and Remediate Bug
Topics: Reproduction, Tracing, Root Cause, Regression Tests, Verification
Intro
Something produces the wrong output, or a test is red. Find the root cause (not just the symptom), fix it minimally, and prove the fix with a test. The agent will happily make the symptom disappear (edit the test, add a try/except, special-case the input). Your job is to make sure the real bug is gone. Uses the six roles from 1. Setup (instructions, research, plan, reviewer, undo, running checks), full or bare. Any prompt that says "run" or "commit": if the agent can't, I do it and paste the output.
| Example Input | Output |
|---|---|
| "Revenue for 1.15 + 0.58 shows 171 cents, expected 173" | Failing test reproduces it, root cause named, minimal fix, suite green, regression tests added |
Abstraction
Reproduce with a failing test, say hypotheses out loud, trace the data path to where the value goes wrong, confirm the root cause explains every symptom, fix at the root, then prove it with the test and the full suite.
The solutions are layers of one process, not alternatives: Solution 1 is the order of steps, Solution 2 is a worked example of that process, and Solution 3 is what to watch for at the fix step. This scenario is Interview Todos 5 to 9 applied to a bug: the failing test reproduces it.
Interview Walkthrough
1. Main Answer: Solution 1 (Reproduce -> Trace -> Root Cause -> Fix -> Prove)
- Interview Todos: 1 Clarify And Restate The Requirements (pin the symptom), 6 Build The Testing Suite For The Plan (the reproducing test), 10 Think Out Loud And Adapt (hypotheses out loud) (Intro > Interview Todos)
- Pin the symptom: exact input, expected, actual, error message
- Failing test first, don't fix what you can't reproduce
- Hypotheses out loud BEFORE asking the agent, so they hear my reasoning
- Trace the data path with file:line references, read those spots myself
- Confirm the root cause explains every symptom, then fix minimally
- Standards used: Agentic Coding Dive > Prompting > Be Specific (describe the symptom), Verify and Fix Root Causes, and Output Verification > Failing Test First
Reproduce first, no fixing
Write a failing test: summing "1.15" and "0.58" should be 173 cents.
Run it and show me the actual output. Don't fix anything yet.Trace the data path (after saying my hypotheses out loud)
Follow "1.15" from the CSV reader to the summary output. Show each value
it becomes and the file:line where it changes.Confirm the root cause
Explain exactly why that line turns "1.15" into 114. Does that fully
explain the 2 cent difference in the test, or is there a second cause?2. Worked Example: Solution 2 (Float Money Bug)
- Interview Todos: 7 Ticket Style Prompts (the fix), 4 Validate The Instructions File (fix the instruction that caused it) (Intro > Interview Todos)
int(float("1.15") * 100)-> 114- float can't represent 1.15 exactly (it's 1.149999...), int() truncates toward zero
- Fix: Decimal + quantize with ROUND_HALF_UP
- Look for siblings: every other place money is converted
- Fix the instruction: if the instructions file (CLAUDE.md or TASK.md) told it to convert this way, fix it too
Find siblings before fixing
- research role: full: send it to the Explore agent, bare: this prompt (or
grep)
Where else in the repo is money converted the same way, or with float at all?Minimal fix at the root
Fix to_cents to parse with Decimal and quantize to 0.01 with ROUND_HALF_UP.
Update the sibling call sites to use it. Don't touch the tests. Run the new
test, then the full suite.Fix the instruction that caused it
CLAUDE.md told you to convert with int(float(value) * 100). Replace that rule
with the Decimal + ROUND_HALF_UP rule so this can't come back.3. Watch for Cheats: Solution 3 (Agent Making the Symptom Disappear)
- Interview Todos: 8 Read Every Diff And Ask Why (catch fake fixes) (Intro > Interview Todos)
- Re-prompting follows Agentic Coding Dive > Prompting (Verify and Fix Root Causes, Tweak and Challenge)
- Edited or loosened the test, broad try/except, special-cased the failing input
- Read test diffs extra carefully
- Reviewer role on the fix diff before committing (full: pr-reviewer, bare: fresh conversation)
When it fakes the fix
- name the cheat + the principle, not just "wrong"
Revert your change to the test. The test is correct; the conversion is the
bug. Floats can't represent 1.15 exactly and int() truncates. Fix the
conversion with Decimal and ROUND_HALF_UP, keep the test as is, and run
the full suite.4. Regression Tests
- Interview Todos: 6 Build The Testing Suite For The Plan (regression tests), 9 Close The Loop (Intro > Interview Todos)
- Add tests for nearby edge cases, then full suite green
- A fix isn't proven until the test can fail without it (Agentic Coding Dive > Output Verification > Test Suite > Validation Prompt)
- The reported case, known float troublemakers, rounding boundaries, negatives
Regression tests
Add tests next to the new one for: "0.29", the rounding boundary "1.005"
(expect 101), a negative "-2.50", and surrounding whitespace " 3.10 ".
Run the full suite and report the results.5. If Asked: Follow-ups
- Interview Todos: 10 Think Out Loud And Adapt (Intro > Interview Todos)
- "How do you know it's the root cause?": the explanation predicts every symptom, and the minimal fix at that spot turns the failing test green without other changes
- "Recent regression?":
git logon the file, orgit bisectwith the failing test - "Can't reproduce?": add logging at the boundaries, compare inputs from the report with my test inputs, ask the interviewer for the exact input
Recent regression
Show the recent commits that touched this file and what each changed.
Which one introduced the float conversion?Solution 1: [Debug] Reproduce -> Trace -> Root Cause -> Fix -> Prove - Bug/Process
The full process, in order: reproduce -> hypothesize -> trace -> confirm root cause -> fix -> prove.
- Output: a failing test that now passes, the root cause named, regression tests added
Step 1: Pin the symptom
- input: amounts ["1.15", "0.58"], expected 173 cents, actual 171
Step 2: Reproduce with a failing test
- can't prove a fix for a bug I can't reproduce
Write a failing test: summing "1.15" and "0.58" should be 173 cents.
Run it and show me the failure. Don't fix anything yet.Step 3: Hypotheses out loud (before the agent answers)
- "Off by a couple of cents smells like float precision or truncation in conversion, could also be rounding at the sum step, I'll check conversion first"
Step 4: Trace the data path
Follow "1.15" from the CSV reader to the summary output. Show each value
it becomes and the file:line where it changes.Step 5: Narrow down
- check intermediate values (print, small test) at the suspicious line
- recent regression? git log -p on the file / git bisect
Step 6: Confirm root cause
Explain why this line produces 114 for "1.15". Does that explain the whole
2 cent difference in the test?Step 7: Siblings
Where else is money converted the same way?Step 8: Minimal fix at the root (Solution 2), never special-case "1.15"
Step 9: Prove it
- failing test now passes, full suite green
Run the new test and then the full suite.Step 10: Regression tests, fix the instructions file if a convention caused it, commit
Solution 2: [Debug] Worked Example, Float Money Bug - Bug/Precision
Solution 1 applied to one real bug, with the code before and after.
- Output: the buggy line, why it's wrong, the fix, and the regression tests
from decimal import Decimal, ROUND_HALF_UP
# BEFORE (bug):
# - float("1.15") is really 1.149999999999999911...
# - * 100 -> 114.99999999999999
# - int() truncates toward zero -> 114, one cent lost
# - ex: 1.15 + 0.58 -> 114 + 57 = 171, expected 173
def to_cents_buggy(value: str) -> int:
return int(float(value) * 100)
# AFTER (fix):
# - Decimal parses the string exactly, no binary float in between
# - quantize to 2 places with ROUND_HALF_UP (explicit rounding rule, not truncation)
# - * 100 on an exact Decimal is exact, int() is now safe
# tc: O(1)
def to_cents(value: str) -> int:
# Parse exactly from the string, never from a float
amount = Decimal(value.strip())
# Round to the cent with an explicit rule
# - ex: "1.155" -> 1.16, "1.15" -> 1.15
amount = amount.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
# Exact conversion to integer cents
return int(amount * 100)
# Regression tests:
# - the reported case, a few known float troublemakers, rounding boundary, negatives
def test_to_cents():
assert to_cents("1.15") == 115
assert to_cents("0.58") == 58
assert to_cents("1.15") + to_cents("0.58") == 173
assert to_cents("0.29") == 29
assert to_cents("1.005") == 101
assert to_cents("-2.50") == -250Solution 3: [Debug] Catching the Agent's Fake Fixes - Bug/Verification
Zooms in on Solution 1's fix step: the ways the agent makes the symptom disappear without fixing the bug.
- Output: recognize each fake fix, revert it, and re-prompt with the principle
Fake fix 1: test edited to match the wrong output
- diff shows assert ... == 173 changed to == 171
- "It changed the expectation, not the code, reverting that"
Fake fix 2: broad try/except
- wraps the conversion and returns 0 on error, hides the bug and creates new ones
- "Swallowing errors turns a loud bug into silent bad data"
Fake fix 3: special case
- if value == "1.15": return 115
- "That only fixes the input in the test, every other amount is still wrong"
Fake fix 4: round(float(x) * 100)
- passes this test, but still float based, and round() uses banker's rounding
- "Closer, but still float and the wrong rounding rule, Decimal is the real fix"
Re-prompt with the principle, not just "wrong"
Don't modify the tests. The root cause is converting through float, which
can't represent 1.15 exactly, and int() truncating. Fix the conversion with
Decimal and ROUND_HALF_UP, keep the test as is, and run the full suite.