Research, plan, implement: prepare the next coding step
Guide an agent through existing code: find the current behaviour, agree on the change, plan a testable part and pass on findings without a whole chat history.
Research, plan, implement means understanding the existing code before choosing and making a change. Pass the useful findings, agreed decisions and open questions to the next step, rather than making it reread every earlier search and failed attempt.
“Reject duplicate uploads” leaves a question: does duplicate mean the same filename or the same contents? First find the existing checks, then agree on the rule. The coding agent needs that answer and the relevant code—not a guess hidden inside a long implementation plan.
“Reject duplicate uploads” sounds like a clear request. But two files can share a name without sharing their contents, and an identical file might be allowed on a different record. These decisions change the implementation. Find them before an agent writes code and tests around an assumption.
Separate what exists from what should change#
Research establishes how the system works now. Design chooses the intended behaviour and approach. Planning sets out the work. Implementation makes the change and checks it. A small task can cover all four in one conversation, but an observation about existing code is not automatically a decision about the new behaviour.
HumanLayer’s workflow saves research and plans for later phases to use. The useful part is being able to inspect a finding or decision before further work depends on it, not producing documents for their own sake.
The attachment service used here is hypothetical. Its duplicate rule is a design exercise, not a requirement for every upload system.
Investigate before deciding where the bug is#
“Explain why the frontend duplicate check is broken” assumes both the cause and location. “Trace duplicate checks on each known upload path” leaves room to discover server validation, batch imports or an existing helper that the browser does not use.
Record the inspected code revision, relevant files and what the investigation did not cover. Find out whether uploads are streamed or buffered, whether a content hash already exists and which tests exercise the paths. Inspecting the browser alone does not justify a conclusion about every upload.
Keep explanations labelled as hypotheses until checked. “Two concurrent requests may both pass this check” is a useful idea to investigate, not a measured result. Use code analysis or a test to establish whether the race is possible.
Agree on the behaviour before planning the edits#
Before choosing the rule, ask the agent to challenge assumptions that would change the result. Matt Pocock’s grill-me guidance describes this as an active conversation, not a questionnaire to agree with. Reject unnecessary scope, challenge its suggestions and say when an answer is unknown. A long exchange is not evidence of a sound decision.
For this example, choose this rule: identical bytes on the same parent record count as a duplicate, and another upload returns the existing attachment. Uploading the same bytes to a different record is allowed. This is separate from recognising a retried network request by its request ID; the two checks can coexist.
Now decide where to enforce the rule. A browser check can give quick feedback but cannot cover a batch importer. A server check followed by an insert can still race with another upload. The design needs a way to keep concurrent requests from creating two attachments, not just a method that returns an error after a sequential lookup.
Review the shared rule, response and compatibility requirements before approving a list of files to edit. Those decisions tell the plan what it must achieve.
A system diagram showing a browser, service and database still leaves important code decisions open. In this example, identify where the duplicate rule lives, which operation owns the transaction and how a concurrent conflict becomes the agreed response. A model can draw the right connections while duplicating the rule inside each caller. Review these responsibilities without prewriting every method.
Give different concepts different names#
In this example, an upload attempt is a request to send a file. An attachment is the stored file associated with a parent record. Two attempts may return the same attachment. Calling both things “an upload” makes a requirement such as “count uploads” ambiguous.
Use the agreed meanings in the brief, code and tests. A test name such as “a repeated upload attempt returns the existing attachment” states the distinction directly. If the code uses an older meaning, point out the mismatch rather than silently renaming a public contract.
This shared domain vocabulary is called ubiquitous language. Pocock’s domain-modeling guidance treats it as work done during design: challenge vague terms, test their meaning with examples and record a definition when it is settled. A glossary copied into every prompt is not enough if the implementation uses different meanings.
Keep definitions scoped to the part of the business they describe. Different areas can legitimately use a word differently; bounded contexts explains how to make those differences explicit instead of forcing one meaning across the whole system.
Prepare a shorter handover without losing decisions#
Intentional compaction means selecting what the next step needs from the work so far. Preserve the checked findings about the current code separately from the agreed changes. Keep unanswered questions visible.
Feature: prevent duplicate attachments on the same parent record.
Research · what exists
- ObservedThe browser compares filenames.
- ObservedBrowser and batch uploads reach the server.
- Not establishedWhether simultaneous uploads can both succeed.
Design · what is agreed
- Duplicate meansIdentical bytes on the same parent record.
- Approved responseReturn the existing attachment.
- Required boundaryThe rule must hold for both entry paths.
Next verifiable sliceExercise two identical uploads through the server. Establish the response and concurrent-write behaviour before expanding the feature.
Hypothetical handoff contents, not observed repository facts. Research supplies evidence; design supplies intent. Neither substitutes for the other.
“Use a hash” would be shorter, but it would lose the same-record scope, the agreed response and the concurrency problem. A useful brief keeps those details and links to the full investigation instead of copying every search result.
Also record any code already changed. Anthropic’s long-running-agent work combines progress records with checks of the inherited environment. “Storage is finished” is not enough: the next worker needs the actual diff and test results.
The handover template separates findings, decisions, completed work and open questions. Include a short explanation of a rejected approach when it prevents the next agent from repeating it. The context-reset guide covers restarting a session that keeps carrying forward an old mistake.
Build a small part that can be checked end to end#
A plan can finish every database change, then every service, then every screen. That postpones testing whether those parts work together. A vertical slice instead takes one small behaviour through enough of the system to check it.
| Situation | Take | Because |
|---|---|---|
| The response to a duplicate is still unclear. | Check the interaction | A test-only fixture can help people agree on the response before persistence is implemented. |
| The rule is agreed but has not worked through the real path. | Connect one upload path | Exercise the request, server handling and test database together. |
| A normal duplicate is handled correctly. | Test the difficult cases | Try concurrent requests, different parent records and the batch importer. |
| The design adds a database constraint. | Test the migration | Existing duplicate records and deployment order may prevent the change from working outside a new database. |
- Situation
- The response to a duplicate is still unclear.
- Take
- Check the interaction
- Because
- A test-only fixture can help people agree on the response before persistence is implemented.
- Situation
- The rule is agreed but has not worked through the real path.
- Take
- Connect one upload path
- Because
- Exercise the request, server handling and test database together.
- Situation
- A normal duplicate is handled correctly.
- Take
- Test the difficult cases
- Because
- Try concurrent requests, different parent records and the batch importer.
- Situation
- The design adds a database constraint.
- Take
- Test the migration
- Because
- Existing duplicate records and deployment order may prevent the change from working outside a new database.
A fixture can demonstrate an interaction without proving that the backend works. Keep incomplete slices in a suitable non-production environment and say what remains untested. A vertical slice does not always start at the screen: start where a check will answer the most important question.
For a frontend example, the Angular feature walkthrough follows one cancellation from agreed behaviour through reusable UI, an API boundary and connected tests. It shows which parts a generator or coding agent can repeat without choosing the product policy.
Investigate the uncertainty that matters next#
Add detail when it resolves a real question. Suppose existing records may violate the proposed uniqueness rule. Inspect authorised data or construct a representative migration test. A longer generated plan cannot establish that the records are compatible.
Different questions need different work. A prototype can help settle an interaction; an experiment can test a technical claim; a person responsible for the product may need to decide the rule. New findings can send the task back to research or design. Do not force it into coding merely because a plan already exists.
Discuss shared rules before producing a large change#
Show the proposed duplicate rule to the batch-import owner before the browser implementation makes the choice hard to change. They may know about a caller the investigation missed. A short early discussion can reveal work that the initial plan omitted.
Tie approval to a version of the proposal. Make suggestions, approved choices and superseded decisions distinguishable. A colleague should not approve yesterday’s plan while the agent implements a materially different version.
Record what happened, not just what was planned#
Before editing, check the code revision, working tree and environment. Recheck findings affected by intervening changes. After each slice, save the commands, results and remaining questions. The builder and its repair loop explains how those results guide a limited correction attempt.
Distinguish passed, failed, blocked and not-run checks. If the database could not start, concurrency remains untested. A test written from the same mistaken requirement is not independent confirmation just because it is called an integration test.
Help the reviewer connect each decision to the implementation and its checks. For the duplicate rule, point to the conflict-handling code and the concurrent-upload test result. Name any departure from the approved plan. The summary helps someone find the relevant evidence; it is not evidence that the code behaves as described. Review the actual change before accepting it.
Return to research for unknown existing behaviour, ask for a missing product decision, or repair a known coding error. Another edit is useful only when it addresses the problem actually found.
Keep the plan smaller than a second code review#
A plan that prewrites every method can require a line-by-line review before coding and another afterwards. Keep the consequential choices, affected interfaces, testable slices and required checks visible instead.
In his interview with Jan-Niklas Wortmann, Dex Horthy contrasts redirecting a 200-line plan with correcting 2,000 lines of code later. The host-published transcript places that example in the discussion of early design decisions. Those are illustrative sizes, not a document quota or a reason to skip code review.
A familiar local fix may need only a reproduction and a short checklist. A shared rule spanning services needs more preparation because a mistaken choice affects more callers. The amount of planning should follow that need.
After acceptance, mark the task plan as history. Keep enduring requirements and operating instructions current; the spec-drift guide explains that distinction. Judge the process by the wrong turns and review work it avoids, not the documents it produces.
IF YOU REMEMBER ONE THING
Find how the code works, agree on the behaviour and test one complete part. Hand over the findings and decisions that matter, not the whole conversation.
Questions people also ask
4 QUESTIONSDo research, design and planning need separate files?
No. They answer different questions, but a small task can keep those answers in one ticket. Separate documents help when different people review them, when one gets too large or when some information must remain current longer than the rest.
Must each phase use a new agent session?
No. Start a fresh session when the next step needs different information or the existing conversation keeps repeating a bad assumption. Keep a productive session when a handover would add work without solving a problem.
How does a shared vocabulary help an AI coding agent?
It gives the requirement, code and tests the same meanings within the relevant domain. For example, an upload attempt and a stored attachment are different things: retrying the first need not create another of the second. A glossary helps only when its definitions are also used and checked in the implementation.
Where should the handover live?
Save it somewhere the next worker can read, such as the task record or a versioned repository document. Include the code revision and distinguish approved decisions from suggestions. Saving it does not automatically include it in the next model call, so make that loading step explicit.