
Interviews: AI Coding
TASK.md
- Task
- Next step
- Awaiting Approval (one subtask at a time, not committed until I approve)
- Requirements (acceptance examples)
- Decisions (questions I asked + answers)
- Edge Cases
- Out of scope
- Plan (what's left, an approved step moves to Completed)
- Test Plan (from step 6, ticked as tests land)
- Findings (file:line, from research)
- Completed (each points to its CHANGELOG.md entry)
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.
Nonnegotiables ::6::
6 setup pieces, about 5 minutes total.
- TASK.md: the task, requirements, decisions, Plan, Test Plan, Next step, Awaiting Approval and Completed.
- Test baseline, written down: in TASK.md if there's no REPO.md.
- CLAUDE.md core rules: from the Ensure prompt, with the conflict list.
- SUBTASKLOOP.md: so you don't retype steps 5-9 for every task.
- Awaiting Approval gate: with the short entry (summary, before and after, files changed, test result).
- Commits as the record: a baseline commit, then one per approved step with before and after in the message.
Negotiables ::9::
9 add-ons, only if there's time and it seems necessary. Each has an "add when" trigger:
- CHANGELOG.md: add when there are several levels or you're changing rules mid-session.
- Completed IDs: add only once CHANGELOG.md exists.
- Full REPO.md map: add for a big repo, or when a
/clearis likely. - AGENTTEAM.md: add when you're creating custom agents or skills.
- pr-reviewer agent: add for multi-file or tricky steps.
- Full Awaiting Approval entry: add once the pr-reviewer exists, since it drafts the entry anyway.
- subtask-loop skill: add if the tool supports skills and you'll run the loop many times.
- Generator + checker: add when the tests need many derivable outputs.
- Hooks: add when one rule is critical enough to enforce.
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, plus an empty CHANGELOG.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, in this order: Task (word for word) with Current level,
Next step, Awaiting Approval (empty), Requirements (acceptance examples), Decisions, Edge Cases,
Out of scope, Plan (empty checklist), Test Plan (empty), Findings, and Completed (empty).
Don't add requirements I didn't state; list anything unclear under Decisions as an open question.
Also create CHANGELOG.md with only its header. Don't change any other files, show me both
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, Test Plan empty until step 6, Awaiting Approval and Completed empty until the first change
TASK.md Example
TASK.md is what we're doing right now (task, decisions, plan, progress). CLAUDE.md is how to work. CHANGELOG.md is what changed.
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
- Next step and Awaiting Approval at the top: opening TASK.md shows what's waiting on me, and which task it's trying to solve
- Awaiting Approval is my review queue, one subtask at a time: the summary, before and after, where to look in the code and the tests, every file changed, and the test results, nothing is committed until I approve it
- Before and After: the same input, the old output vs the new one, so I can see the change did what I asked (for a bug: the wrong output, then the right one)
- Requirements become the tests in step 6, Decisions stop the agent from re-guessing answers
- Plan is only what's left: an approved step moves to Completed instead of being ticked, so nothing is listed twice
- Test Plan saves the tests proposed in step 6, so they survive a /clear, ticked as they land
- Completed is what's done, each line points to its CHANGELOG.md entry (C2), so "done" always traces to a real commit and diff
- flow per subtask: Plan -> green + reviewed -> Awaiting Approval -> I approve -> commit -> CHANGELOG.md entry + Completed line -> REPO.md if the repo's shape changed
- 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
## Next step
- Review plan step 3 in Awaiting Approval
## Awaiting Approval (one subtask at a time, not committed until I approve)
- Plan 3: keep existing hyphens, collapse repeated spaces
- Summary: slugify dropped "-" as punctuation, now kept; runs of spaces become one hyphen
- Before: "co-op" -> "coop", "a b" -> "a--b"
- After: "co-op" -> "co-op", "a b" -> "a-b"
- Code: src/text.py:44-52 (the punctuation filter and the whitespace split)
- Tests: tests/test_slugify.py:18-27 (test_keeps_existing_hyphens, test_collapses_spaces)
- Files changed (git diff --stat): src/text.py, tests/test_slugify.py, all explained above
- Result: `pytest -q` 48 passed, 1 already red (baseline)
- Reviewer: no correctness issues, suggests a test for a leading hyphen ("-abc")
- REPO.md: no architecture change, Current test count updates to 48 on approval
## 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 (what's left, an approved step moves to Completed)
- [ ] 3. Keep existing hyphens, collapse repeated spaces (in Awaiting Approval)
## Test Plan (from step 6, ticked as tests land)
- [x] "Hello World" -> "hello-world" (unit, from Requirements)
- [x] "" -> "" (unit, from Requirements)
- [ ] "co-op" stays "co-op" (unit, from Decisions)
- [ ] repeated spaces collapse to one hyphen (unit, from Edge Cases)
- Gaps: no existing tests cover accented letters (open question in Decisions)
- Regression: full suite, baseline in REPO.md (42 passed, 1 already red)
## Findings (file:line, from research)
- Existing helpers: src/text.py:12-40, all use split/join
## Completed (each points to its CHANGELOG.md entry)
- Plan 1: failing tests for the acceptance cases -> C1
- Plan 2: slugify(text) in src/text.py -> C2
- When a level's steps are all done: "Level 1 done -> C1-C4"
## 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`CHANGELOG.md
One log for every approved change, code and process, in its own file at the repo root. It's my check that the agent didn't quietly change its own rules or claim work it didn't do.
- own file: the agent edits TASK.md all the time, a separate append-only file can't get "tidied" by accident, and it outlasts tasks and levels
- IDs (C1, C2, ...): Completed in TASK.md points to an ID, the ID points to a commit, so any
claim of "done" can be followed to a real diff, and
git revertundoes exactly one change - [Code]: a change to the repo
- [Process]: a change to CLAUDE.md, SUBTASKLOOP.md, an agent, a skill, or REPO.md's structure, these go through Awaiting Approval too, so the agent can't rewrite its own rules unseen
- not logged: bookkeeping (Next step, Test Plan ticks, Current test counts), git has it
- files changed check: every file in
git diff --statmust be explained in the entry, an unexplained file gets flagged, that's what stops something slipping through on the clock - git is still the full record:
git log --onelineif anyone asks
# CHANGELOG.md (append only, newest last, one entry per approved change)
- C1 [Code] Plan 1: added failing tests for slugify | tests/test_slugify.py | 4 new, red as expected | commit a1b2c3d
- Before: no tests for slugify
- After: 4 tests, all red because slugify doesn't exist yet
- REPO.md: no change
- C2 [Code] Plan 2: added slugify(text) | src/text.py | 4/4 new green, full suite 46 passed, 1 already red | commit e4f5a6b
- Before: "Hello World" -> AttributeError (no slugify in src/text.py)
- After: "Hello World" -> "hello-world", "" -> ""
- REPO.md: added slugify to Layout (src/text.py), Current 46 passed
- C3 [Process] SUBTASKLOOP.md: diff step lists every file from git diff --stat | SUBTASKLOOP.md | no tests affected | commit c7d8e9f
- Before: the diff summary listed only the files the agent chose to mention
- After: every changed file is listed, unexplained ones are flagged
- REPO.md: no changeKeep TASK.md And CHANGELOG.md Current
Yes, it needs a standing instruction: a one-off request gets forgotten after a /clear, the instruction file is loaded every session, so the rule lives there.
- full: add the rule to CLAUDE.md (step 4), or whichever instruction file AGENTTEAM.md says the tool reads
- Cursor: a rule in .cursor/rules/ with alwaysApply: true, or AGENTS.md
- 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
- "append only" stops the agent from tidying CHANGELOG.md, which would break reverting
- Submit For Approval is part of the rule, so every green subtask lands in Awaiting Approval without me prompting for it
- the reviewer drafts the entry because it didn't write the code, the main agent keeps the records because it makes the commits
- already part of step 4's Ensure CLAUDE.md prompt, use this alone to add it mid-session
Add this to CLAUDE.md (or the instruction file in AGENTTEAM.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,
and add a matching test to the Test Plan.
- Submit For Approval: when a subtask's tests are green, use the pr-reviewer agent on the diff.
This applies to process changes too (CLAUDE.md, SUBTASKLOOP.md, agents, skills). It returns a
draft Awaiting Approval entry: summary, before and after (the same input, old output vs new
output), code file:line, test file:line, files changed from git diff --stat (flag any file the
summary doesn't explain), the test command and result, and any issues. Write that entry into
Awaiting Approval word for word. If there's no reviewer agent, write the entry yourself and
say so. Then stop. Don't commit or start the next subtask until I approve.
- When I approve: commit, append an entry to CHANGELOG.md (next ID, [Code] or [Process], plan
step, what changed, files, test result, commit hash, before and after, REPO.md note), move the
Plan step to Completed as "Plan N: ... -> C<ID>", tick the Test Plan, clear Awaiting Approval,
and update Next step.
- After an approved change, update REPO.md if the architecture, main flow, layout, or tests
changed (keep the Baseline, update the Current test counts), and note it in the CHANGELOG.md
entry as "REPO.md: ..." or "REPO.md: no change".
- If I reject: keep the entry, add my reason under it, fix it, and update the entry.
- CHANGELOG.md is append only. Never edit or delete earlier entries. Log a revert as a new entry.
- Don't log bookkeeping (Next step, ticks, test counts) in CHANGELOG.md.
- On a new level, bump Current level, add to Requirements and the Test Plan, don't start a new
file. When all of a level's steps are done, add "Level N done -> C<first>-C<last>" to Completed.Already have a TASK.md without these sections? Add them:
Add Next step and Awaiting Approval right under Task in TASK.md, and Completed at the end. Each
Awaiting Approval entry is one subtask waiting on my review: summary, before and after (same
input, old vs new output), code file:line, test file:line, files changed from git diff --stat,
test result, and reviewer notes. Move any old Change Log lines into a new CHANGELOG.md with IDs.
Don't change any other section.2. Check The Tool For Full Featured Or Bare Bones AGENTTEAM.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 AGENTTEAM.md, a live doc of my agent team: the tool, the mode, what's available, who fills each role, and any gotchas.
- CLAUDE.md is how to work, AGENTTEAM.md is my agents and who does what, 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 AGENTS.md: that's a real instruction file other tools read, it would get loaded as rules
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 AGENTTEAM.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.AGENTTEAM.md Example
# AGENTTEAM.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 (drafts each Awaiting Approval entry), or /code-review
- Undo: checkpoints (/rewind) + commit after each approved step
- Running checks: agent runs them and shows output
## Added this session (name | file | what it does | role)
- pr-reviewer agent | .claude/agents/pr-reviewer.md | reviews the diff, drafts Awaiting Approval entries | Reviewer
- subtask-loop skill | .claude/skills/subtask-loop/SKILL.md | runs SUBTASKLOOP.md | Plan, Running checks
- SUBTASKLOOP.md | repo root | steps 5 to 9 with the gates | Instructions
## Available but not using
- Skills: none of the existing ones 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 AGENTTEAM.md Current
Set once in step 2, then only updated when something changes (a gotcha, a new helper).
- anything I add (an agent, a skill, SUBTASKLOOP.md) goes under "Added this session", so I and the interviewer can see the whole team in one place
- full: import it in CLAUDE.md with
@AGENTTEAM.md, so it loads every session automatically - bare: start key prompts with "Read AGENTTEAM.md and TASK.md first"
- already part of step 4's Ensure CLAUDE.md prompt, use this alone to add it mid-session
Add this to CLAUDE.md:
- @AGENTTEAM.md
- When you add or change an agent, skill, hook, command, or process file (like SUBTASKLOOP.md),
record it in AGENTTEAM.md under "Added this session": name, file, what it does, and its role.
- If a tool, role, or gotcha changes, update AGENTTEAM.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, AGENTTEAM.md is my agents and who does what, 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)
- Current: 46 passed, 1 failed (after C2, see CHANGELOG.md)
- 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.
- checked after every approved change: the CHANGELOG.md entry says what changed in REPO.md, or "no change"
- 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, so it never changes, only Current does
- full: a rule in CLAUDE.md (below), bare: "Read REPO.md before searching" in the prompt
- already part of step 4's Ensure CLAUDE.md prompt, use this alone to add it mid-session
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.
- After each approved change, update REPO.md if the architecture, main flow, layout, or tests
changed. Keep the Baseline as is and update the Current test counts.4. Set The Session Rules In The Instructions File CLAUDE.md, Every Time
Always run this, whether CLAUDE.md exists or not. I don't audit the old file line by line, I generate the baseline rules this session needs and have the agent merge them in.
- full: CLAUDE.md loads every session automatically,
@AGENTTEAM.mdpulls AGENTTEAM.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
- existing file: the agent keeps its commands and any rule that doesn't conflict, and lists the ones that do, so a planted bad rule (ex: "CI will catch it, don't run tests locally") still gets caught without me reading the whole file
- say each conflict out loud and why the session rule wins, that's the fix-it-at-the-root signal
- full:
/initfirst is fine if there's no file, this prompt then reshapes it - "Files" points to the other docs instead of copying them in, keeps CLAUDE.md short
- the "follow SUBTASKLOOP.md" rule is what makes the loop run without me pasting it, create SUBTASKLOOP.md right after this (Every task or level, repeat > SUBTASKLOOP.md)
Ensure CLAUDE.md Prompt
Read CLAUDE.md if it exists; if it doesn't, create it at the repo root. Either way, make sure it
has the following, under 50 lines, and keep any existing commands or rules that don't conflict:
- Commands: install, test, lint (only ones you've confirmed run)
- Files: @AGENTTEAM.md (tool and roles), REPO.md (repo map, read before searching),
TASK.md (current task, source of truth, read it before every step),
SUBTASKLOOP.md (the steps for every task and subtask), CHANGELOG.md (every approved change)
- Rules:
- For every task, level, or subtask, follow SUBTASKLOOP.md step by step and stop at each GATE
- 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
- New requirement, edge case, or decision: add it to TASK.md, and a test to the Test Plan,
before coding
- Every change goes to Awaiting Approval in TASK.md, code and process (CLAUDE.md,
SUBTASKLOOP.md, agents, skills): when it's green, the pr-reviewer drafts the entry (summary,
before and after, code and test file:line, every file in git diff --stat with any unexplained
one flagged, test result, issues), you write it in word for word, then stop. No commit and no
next subtask until I approve
- Every approved change goes in CHANGELOG.md: commit, then append an entry with the next ID,
[Code] or [Process], the commit hash, and the before and after. Append only, log a revert as a
new entry, don't log bookkeeping
- Every approved change is checked against REPO.md: update it if the architecture, main flow,
layout, or tests changed (keep Baseline, update Current), and note "REPO.md: ..." in the entry
- After I approve: move the Plan step to Completed with its CHANGELOG.md ID, tick the Test Plan,
clear Awaiting Approval, and update Next step
- On a new level: bump Current level, add to Requirements and the Test Plan, same TASK.md;
when a level is done, add "Level N done -> C<first>-C<last>" to Completed
- Anything you add or change for the agent team (agent, skill, hook, command, process file
like SUBTASKLOOP.md) goes in AGENTTEAM.md under "Added this session": name, file, what it
does, and its role
- Update AGENTTEAM.md if a tool, role, or gotcha changes
- Flag anything inconsistent instead of guessing
Then list in a few lines any existing rule you removed or that conflicts with these, and why.
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
- AGENTTEAM.md, REPO.md, TASK.md from steps 1 to 3, plus SUBTASKLOOP.md and CHANGELOG.md, 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 AGENTTEAM.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, AGENTTEAM.md, REPO.md, TASK.md, SUBTASKLOOP.md, and CHANGELOG.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.
Steps 5 to 9 are written once in SUBTASKLOOP.md, and the CLAUDE.md rule makes the agent follow it. The prompts in each step below are the manual version, for a bare agent or when it skips a gate.
SUBTASKLOOP.md: Steps 5 To 9 In One File
Create it at the end of setup, after step 4 and before the baseline commit. Then "Follow SUBTASKLOOP.md for this task" replaces typing out steps 5 to 9 every time.
- two loops: plan and tests once per task or level, implement, diff, and approval for each Plan step
- GATES are where it stops for me: after the plan, after the test list, after the diff summary,
and at Awaiting Approval
- without them it runs all five steps at once, and the interviewer sees autopilot, not steering
- full: CLAUDE.md says to follow it, and it can also be a skill, so
/subtask-loopstarts it - bare: nothing loads on its own, so start prompts with "Follow SUBTASKLOOP.md for ..."
- it rarely changes, if I tweak the process mid-session, update the file, not just the prompt
SUBTASKLOOP.md Example
# SUBTASKLOOP.md
Follow this for every task, level, or subtask. Read TASK.md first. At each GATE, stop and wait for me.
## Once per task or level
1. Plan (step 5): give two approaches with tradeoffs and the files each touches, then a
step-by-step plan for the one you'd pick, each step small enough to review in one diff.
GATE: wait for my approval, then save it to the Plan in TASK.md and set Next step.
2. Tests (step 6): propose the tests (cases from Requirements, edge cases this approach adds,
unit or generator). GATE: wait for my approval, then save them as the Test Plan. Write them as
failing tests, run them, and show they fail for the right reason. Don't implement anything.
## For each Plan step
3. Implement (step 7): only this Plan step, only the files it names, following the patterns in
REPO.md. Run the full suite.
4. Diff (step 8): summarize the diff: every file in git diff --stat and why it changed, any test
added, changed, or deleted, anything outside the step. GATE: wait for my questions.
5. Approval (step 9): when green, have the pr-reviewer draft the Awaiting Approval entry and write
it in word for word. GATE: stop.
- "Approved": commit, append a CHANGELOG.md entry (next ID, [Code] or [Process], hash, before
and after), update REPO.md if needed, move the Plan step to Completed with its ID, tick the
Test Plan, clear Awaiting Approval, set Next step.
- "Not approved: [reason]": add the reason under the entry, fix it, rerun, update the entry.Create SUBTASKLOOP.md Prompt
Create SUBTASKLOOP.md at the repo root with the steps I follow for every task and subtask:
- Once per task or level: Plan (two approaches, then small steps; GATE for my approval, save to
the TASK.md Plan), Tests (propose, GATE, save as the Test Plan, write them failing, show the failure)
- For each Plan step: Implement (only that step, full suite), Diff (every file in git diff
--stat and why, GATE for my questions), Approval (pr-reviewer drafts the Awaiting Approval
entry, you write it in, GATE; on "Approved" commit, CHANGELOG.md entry with ID, hash, and
before and after, REPO.md if needed, move the Plan step to Completed with its ID, tick the
Test Plan, set Next step; on "Not approved" add the reason, fix, update the entry)
At each GATE, stop and wait for me. Don't change any other files. Show it to me before saving.Skill Version (Full, Optional)
Same text, loaded only when used, started with /subtask-loop.
- only if the tool supports skills (check in step 2), otherwise the plain file is enough
Create a skill at .claude/skills/subtask-loop/SKILL.md, name subtask-loop, description "The steps
for every task or subtask: plan, tests, implement, diff, approval. Use for every task." Its
instructions: read and follow SUBTASKLOOP.md. Don't change any other files.Using The Loop
- new task or level: plan gate first
- each Plan step after that: implement through approval
- at the approval gate: "Approved", or "Not approved: [reason]"
Follow SUBTASKLOOP.md for this task.Next Plan step.Not approved: no test for a leading hyphen.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
- the approved list is saved as the Test Plan in TASK.md, so it survives a /clear
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, then save it as the Test Plan section in TASK.md.Write the approved tests from the Test Plan in TASK.md 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, My Approval, Then Commit
"Done" means proven, not the agent saying so: a reviewer that didn't write the code, the full suite green, a summary in Awaiting Approval, my review, 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"
- one subtask in Awaiting Approval at a time, so its uncommitted diff is only that change
- the reviewer drafts the entry (it didn't write the code), the main agent writes it into TASK.md and keeps the records (it makes the commits, and the reviewer stays read-only)
- worth it in an hour if the reviewer already exists or takes 2 minutes to create, about a minute per subtask; bare tool: the main agent writes the entry, one fresh review at the end
- review it myself: open each code and test reference, and check the test really covers the change
- before and after: the same input, old output vs new output, proves it fixed the right thing (for a bug, the Before should match the reported wrong output)
- REPO.md: updated on approval only if the repo's shape or test counts changed
- files changed: every file in
git diff --statis listed, any the summary doesn't explain is flagged, so nothing slips in outside the step - commit only after I approve, then the entry moves to CHANGELOG.md with an ID and the hash, and the Plan step moves to Completed pointing at that ID, so any change can be reverted by itself
Submit For Approval (A Rule, Not A Prompt)
The Keep TASK.md And CHANGELOG.md Current rule in CLAUDE.md does this after every green subtask: the pr-reviewer drafts the entry, the main agent writes it into Awaiting Approval and stops.
- only prompt it if the agent skipped it, or to check the rule is working
Submit this subtask for approval, following the rule in CLAUDE.md.Reviewer Agent File
The reviewer the rule calls. Read-only: it reports and drafts, the main agent writes and commits.
- "flag only issues that affect correctness or the requirements" keeps it from burying me in nits
<!-- File: .claude/agents/pr-reviewer.md -->
---
name: pr-reviewer
description: Reviews the current diff and drafts its Awaiting Approval entry. Use after every green subtask, before committing.
tools: Read, Grep, Glob, Bash
---
You review code you did not write. Read TASK.md for the task, run git diff, git diff --stat,
and the full test suite. Flag only issues that affect correctness or the requirements: edge
cases, weakened or deleted tests, scope creep, and any changed file the summary can't explain.
Never edit files.
End with a draft Awaiting Approval entry:
- Plan N: <what the subtask does>
- Summary: <what changed, one line>
- Before: <an input and its old output>
- After: <the same input and its new output>
- Code: <file:line to read>
- Tests: <file:line and test names>
- Files changed (git diff --stat): <every file, and "all explained" or which aren't>
- Result: <exact test command and pass/fail counts>
- Reviewer: <issues, or "no correctness issues">Create .claude/agents/pr-reviewer.md: a read-only reviewer (tools Read, Grep, Glob, Bash) that
reads TASK.md, runs git diff, git diff --stat, and the full suite, flags only issues that affect
correctness or the requirements plus any changed file it can't explain, never edits files, and
ends with a draft Awaiting Approval entry in the TASK.md format. Show it to me before saving.Approve Prompt
Approved. Commit with a message that says what changed and why. Append an entry to CHANGELOG.md
with the next ID, [Code] or [Process], the plan step, what changed, files, test result, commit
hash, and the before and after. If the architecture, main flow, layout, or tests changed, update
REPO.md (Current test counts too) and note it in the entry; otherwise write "REPO.md: no change".
Then in TASK.md: move the Plan step to Completed with its ID, tick the Test Plan, clear Awaiting
Approval, and set Next step.Reject Prompt
Not approved: [reason, e.g. no test for a leading hyphen]. Add that reason under the entry in
Awaiting Approval, fix it, rerun the full suite, and update the entry. Don't commit.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.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 Set The Session Rules (Intro > Interview Todos)
- Role: instructions the agent follows every time
- full: CLAUDE.md (or the file this tool reads)
- bare: TASK.md, since the agent won't load anything on its own
- Always run step 4's Ensure CLAUDE.md prompt: it merges our session rules in and lists any
existing rule that conflicts, so I don't spend time reading the old file line by line
- the agent follows the file literally, bad instructions = bad code, so the conflict list matters
- 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
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: Interview Todos > 9 > Reviewer Agent File
- 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
- "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
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)
- Below: ticket-style, tweak, and challenge prompts 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
- 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
- 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
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
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 Set The Session Rules (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)
- 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
- 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.