# Let the agent interview you

> Have the agent interview you about a feature before any plan exists, answer with decisions or "not decided yet", write the settled terms down, and check that the spec and a fresh session's plan use them.

Page: https://schubergphilis.github.io/ai-training/coding-with-agents/agent-interviews-you/
License: CC BY-SA 4.0, https://creativecommons.org/licenses/by-sa/4.0/

A colleague asks for a change to the to-do program: "Done items clutter
the list. Can you tidy it? I still want to see what I finished last
month." The request sounds clear until you try to build it. Does "tidy"
mean the `clear` command the program already has, which deletes done
items? Or does it mean moving them somewhere they can still be read? In
this lesson the agent interviews you about the feature before any plan
exists. You answer its questions, and together you settle on the words
for the design. At the end you check two files against those words: the
spec, and the plan that a fresh session writes from it.

*Deciding whether to build it at all* ended with success criteria a
stranger could check. You can only write those once you know what the
feature is. For a larger feature, the Claude Code best
practices page recommends that the agent interviews you first and writes
a spec, and that a new session then works from that spec (Best practices for Claude Code, Claude Code documentation).
The agent's questions bring out the decisions you haven't made yet, at a
point where a change to them is still cheap.

## The fixture

The fixture is the to-do program from *Your first session with a coding
agent*, some weeks later. It has a `clear` command and is split into three
modules. It is in the course repository under
`site/examples/coding-with-agents/agent-interviews-you/`. Copy that whole
directory to a place of its own. The copy holds `fixture-repo/`, where the
agent works, a script `check_terms.py` and a `sample/` directory that the
second half of the lesson uses. The reset is to delete the copy and copy
again. Working in a copy also keeps the course's own instruction files out
of the session, because Claude Code, for example, loads the instruction
files in every directory above the one it starts in (How Claude remembers your project, Claude Code documentation).

Claude Code's auto memory is on by default in local sessions. It saves
notes that the agent writes for itself and loads them into the next session
of the same project. It files the notes under the git repository, or
under the project root outside one (How Claude remembers your project, Claude Code documentation). In this lesson a
note from the interview would reach the fresh session that is meant to
start without it, and a reset copy at the same path would load the notes
again. So start every Claude Code session in this lesson with auto memory
turned off. Change into `fixture-repo` first, because this command starts
the agent in the directory you run it from:

```sh
CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 claude
```

With another agent, check whether it keeps notes between sessions, and
turn that off for this lesson. Before you start the agent, look at the
list from `fixture-repo`.

#### Example: Show the list

Run this, and compare what you see with the output below.

```sh
python3 todo.py list
```

Output:

```text
1. [ ] Buy milk
2. [x] Call the plumber
3. [x] Renew the passport
4. [ ] Water the plants
2 open, 2 done
```

Two of the four items are done. `python3 todo.py clear` would delete both,
and the colleague wants to keep them. That gap between "tidy" and `clear`
is the first thing an interview should find.

## Asking for the interview

A design interview is a session where the agent asks and you answer. It
comes before the agent plans anything or writes any code. Start your coding
agent in `fixture-repo`, with auto memory off as above, and give it a short description of the feature with the request to
interview you. Ask for questions about behavior, edge cases, risks and
trade-offs, and tell it to skip what it can read in the code. Tell it when
to stop, and what to write when it does.

```text
I want a way to tidy the to-do list. Done items clutter it, but I still
need to see what I finished last month. Before you plan anything or
change any code, interview me about this feature. Ask one question at a
time. Ask about how it should behave, the edge cases, what could go
wrong, and the trade-offs, and don't ask what you can find out from the
code. When a word could mean two different things, ask me which one I
mean. Keep going until nothing is open. Then write TERMS.md, one line per
term in the form "- **term**: meaning. Avoid: word, word.", and SPEC.md,
which uses only those terms. Put what I left undecided under
"Open questions" in SPEC.md.
```

In Claude Code, the best practices page suggests naming its
`AskUserQuestion` tool in the request (Best practices for Claude Code, Claude Code documentation). The
agent then asks its questions through that tool. Another agent asks its
questions in the chat.

The exchange below is illustrative. It was written for this lesson and
not recorded from a model. It shows the kind of first question that the
request should produce.

#### Prompt (illustrative, not a recorded transcript)

```text
(The request above.)
```

#### Response

```text
The program already has `clear`, which deletes every done item. When you
say "tidy", do you mean `clear`, or should the done items move somewhere
you can still read them later?
```

#### Prompt (illustrative, not a recorded transcript)

```text
Move them, to a file of their own. Call that "archive". `clear` stays as
it is: it deletes, and it doesn't touch the archive.
```

#### Response

```text
Understood. Should the archived items keep the numbers they had in the
list, or does the list number the open items again from 1?
```

The agent's first question found the word that could mean two things. Your
answer chose one meaning and gave the new thing a name. The second question is a
decision you might not have made before the interview. Answer each question
with a decision. When you have none, say "not decided yet". The agent then
lists the point under the open questions.

#### Pitfall: An answer to get to the code

In one interview the agent asked whether archived items should record the
date they were archived. The engineer wanted to get to the code and typed
"yes, add the date". The spec now had a date field with its own format and
time zone, and the fresh session built them. The `archive list`
output grew a column that nobody had asked for, and the diff was twice the
size it needed to be. The rule: an answer you make up to move on becomes a
requirement the agent builds. Say "not decided yet", and the spec lists the
point as open.

#### Checkpoint: A question you have no answer for

The agent asks: "Should `archive` also run by itself when the list has
more than 20 done items?" You haven't thought about it, and you have no view
on it yet. What do you answer?

- Say "Yes, do that", so that the interview keeps moving.
- Say "You decide", since the agent knows the code better.
- Say "Not decided yet", so it goes under the open questions.
- Say "Stop asking and write the spec", since this is a detail.

## Writing down the terms

During an interview the words drift. You say "done" and the agent says
"completed". A sentence later the spec says "finished". Each word
seems clear to whoever uses it. A fresh session that reads the spec sees
three words and has to guess whether they name one thing or three, and
some of its guesses are wrong.

The fix is a shared vocabulary: one agreed meaning for each term of the
feature, written down, and used the same way in the conversation, the spec,
the plan, and the code. The idea comes from domain-driven design, a way of
building software that Eric Evans described (Domain-Driven Design: Tackling Complexity in the Heart of Software, Addison-Wesley, 2003). His free reference
summary says to use one language in speech, writing and code, and to treat
a change in that language as a change to the design (Domain-Driven Design Reference: Definitions and Pattern Summaries, Domain Language, 2015).
This lesson takes only that part: a short list of terms, in plain words,
each with the words to avoid.

The `sample/` directory in your copy holds the files an interview about the
archive feature could end with. This is `sample/TERMS.md`:

```md
# Terms

- **item**: one line of the to-do list, with its text and its done mark. Avoid: task, tasks, entry, entries.
- **done item**: an item marked with `done`. Avoid: completed, finished.
- **archive**: move every done item from the list to `archive.json`, where `archive list` shows it. Avoid: hide, hides, hidden.
- **clear**: delete every done item from the list for good. It never touches `archive.json`. Avoid: purge, wipe.
```

The avoid words are the ones that came up in the interview for the same
thing, or for a different thing that is easy to confuse with it. "Hide"
is on the list because a hidden item is still in `todos.json`, and an
archived one is not.

## Checking the spec against the terms

`check_terms.py` reads a term list and prints every line of another file
that uses an avoided word. It matches whole words and ignores case. Leave
the interview session running in its own terminal, and open a second
terminal for the script. Change into the top of your copy there and run
the script on the sample spec.

#### Example: Check the sample spec

Run this in the second terminal, from the top of your copy, and compare
what you see with the output below.

```sh
python3 check_terms.py sample/TERMS.md sample/SPEC.md
```

Output:

```text
sample/SPEC.md:15: "task" where sample/TERMS.md says "item"
sample/SPEC.md:16: "completed" where sample/TERMS.md says "done item"
2 words to check
```

Open `sample/SPEC.md` and read the two lines. Line 15 says `archive list`
shows "the text of each task". That is a slip, and the fix is the word
"item". Line 16 says "`clear` deletes the completed items and empties
`archive.json`." The word is wrong, and the line also contradicts the term
list, which says `clear` never touches the archive. A drifted word is
sometimes a typo and sometimes a decision that the interview made one way
and the spec wrote down another way. Read the whole line each time.

#### Checkpoint: The line about clear

The check prints `sample/SPEC.md:16: "completed" where sample/TERMS.md says
"done item"`. The line is "`clear` deletes the completed items and empties
`archive.json`." What do you do?

- Add "completed" to the meaning of done item, so that the check passes on the next run.
- Read the line against the term list, settle with the agent what clear does, and rewrite the line.
- Change "completed" to "done" in that line, and run the check again until it reports nothing.
- Leave the line, because the agent that builds the feature knows that the two words mean the same.

Fix both lines in `sample/SPEC.md`. Change "task" to "item" in line 15,
and rewrite line 16 as "`clear` deletes the done items and leaves
`archive.json` as it is." Then run the check again.

#### Example: Check the fixed spec

Run the same command in the second terminal after the two fixes, and
compare what you see with the output below.

```sh
python3 check_terms.py sample/TERMS.md sample/SPEC.md
```

Output:

```text
no avoided words in sample/SPEC.md
```

In your own interview, read and
correct `TERMS.md` and `SPEC.md` the same way before anything else happens.
Renaming a term after this point is a change to the design. Change the
term list and the spec together.

## Planning from the spec in a fresh session

The best practices page suggests that a new session carries out the
spec, because its context then holds the work and nothing of the long
interview (Best practices for Claude Code, Claude Code documentation). Write the plan in a new session
too. End the interview session, start a new one in `fixture-repo` with
auto memory still off, and ask for a plan that uses the term list.

```text
Read TERMS.md and SPEC.md. Write PLAN.md with the steps to build what
SPEC.md describes, using the terms in TERMS.md and no other words for
them. Don't change any code yet.
```

When the plan is written, run the check on it in the second terminal, from
the top of your copy:

```sh
python3 check_terms.py fixture-repo/TERMS.md fixture-repo/PLAN.md
```

An avoided word in the plan means one of two things. Either the plan
slipped and you correct the word, or the spec left something open that the
plan filled in with a guess. In the second case, the fix belongs in the
spec first.

#### Checkpoint: From request to plan

- Answer each question with a decision, or with "not decided yet"
- Ask the agent to interview you about the feature, before any plan
- Check the plan against the term list
- Have the agent write the term list and the spec
- Read both files and correct them
- Start a fresh session that writes the plan from the spec

## Exercise

Reset your copy and let an agent interview you about an undo for `done`:
a way to take back a `done 3` typed by mistake. Start the session with
auto memory off, and use the request from this lesson with its first two
sentences replaced by one or two sentences about the undo. Answer every
question with a decision or with "not decided yet", and stop when the
agent has written `TERMS.md` and `SPEC.md`. Read both files and correct
them. Then run the check in the second terminal, from the top of your
copy, until it prints `no avoided words`:

```sh
python3 check_terms.py fixture-repo/TERMS.md fixture-repo/SPEC.md
```

If it prints `no terms found`, `TERMS.md` doesn't use the line form the
request asked for, so ask the agent to rewrite it in that form. A line it
reports as `not in the term form` has the same fix. Then start a fresh
session, have it write `PLAN.md` from the spec, and run the check on the
plan. Twenty minutes is enough. You do this so the design is settled, in
words that you and the agent share, before the agent proposes how to build
it.

A good result: the interview asked at least one question you had not
thought of, and `TERMS.md` has three to six terms. The spec lists at least
one open question or says why there are none. The check prints
`no avoided words` for both the spec and the plan. Reflect: which question
brought out a decision you had not made, and what would the agent have
built if it had never asked?

Stretch: Ask the fresh session to build the plan, then run check_terms.py on the modules it changed, such as fixture-repo/todo.py and fixture-repo/store.py, and see whether the names in the code follow the term list too.

## Recap

1. For a larger feature, ask the agent to interview you before it plans, and to write a spec when nothing is open (Best practices for Claude Code, Claude Code documentation).
2. Answer each question with a decision, or with "not decided yet". An answer made up to move on becomes a requirement.
3. Write the terms the interview settled into a short list, each with its meaning and the words to avoid, and use the same words in the spec, the plan and the code (Domain-Driven Design Reference: Definitions and Pattern Summaries, Domain Language, 2015).
4. Check the spec and the plan against the term list. A drifted word is either a slip or a decision written down wrong, so read the whole line.
5. Start the plan in a fresh session that works from the spec and the term list, without the interview in its context.

#### Habit

The next time you hand an agent a feature that takes more than one sentence to describe, ask it to interview you before it writes a plan.

## References

- Best practices for Claude Code, Claude Code documentation, https://code.claude.com/docs/en/best-practices
- How Claude remembers your project, Claude Code documentation, https://code.claude.com/docs/en/memory
- Domain-Driven Design: Tackling Complexity in the Heart of Software, Addison-Wesley, 2003
- Domain-Driven Design Reference: Definitions and Pattern Summaries, Domain Language, 2015, https://www.domainlanguage.com/ddd/reference/
