skip to content

Why is “add a retry policy to the webhook sender” under-specified even though it reads complete?

level: juniorimportance: must knowfreq 62%

answer

  1. Complete to its author, not its reader
  2. The facts you never say aloud
  3. Outcome named, behaviour left open
  4. Two readings, and who notices

basics

~20 s

The request names an outcome and no behaviour. Retrying a payload the receiver rejected, sending the same one twice, and giving up silently all satisfy it — so the agent picks one, and you usually find out from the diff.

solid answer

~40 s

The sentence reads complete because you finish it in your head. You already know the receiver treats a repeated delivery as a new event, that a payload it rejected as malformed will be rejected again an hour later, and that a queue held only in memory is gone after a deploy — none of which is in the text. A run handed that sentence fills each gap with something plausible and carries on. It may ask about one of them, and you cannot count on it asking about the one that matters. So before starting I read each sentence and ask: could two implementations both satisfy this and differ in something the receiver, a customer or an operator would notice? Every yes is a decision I delegated by accident.

code

text · 14 lines
text
REQUEST AS WRITTEN
  Add a retry policy to the webhook sender.

SATISFIED EQUALLY BY
  A. retry every failed delivery, immediately, five times, tracked in memory
  B. retry only deliveries that got no answer, spaced out, recorded durably
  C. retry everything, forever, until the receiver finally accepts it
  D. retry once, then drop the event with nothing written down

WHAT THE REQUEST NEVER SAYS
  - which failures are worth retrying, and which will fail the same way again
  - whether the receiver can safely be shown the same delivery twice
  - what happens to an event once the attempts run out
  - whether anything in flight has to survive a restart

go deeper

for a junior

Say plainly what your own request does not say. Before running anything, read the sentence as a stranger would and list what it leaves open: which failures are retried, whether a repeat is safe, what happens when the attempts run out.

for a middle

Explain the mechanism rather than the symptom: the author supplies the missing facts from memory while reading, so the gap never surfaces for them and is unmarked for the agent. Then show the two-readings test you apply to each sentence.

for a senior

Show which gaps you close and which you deliberately leave open. The ones worth words are those whose two readings differ in something a receiver, a customer or an operator could see; the rest make the request longer without making it clearer.

for a principal

Own the judgement about how much intent is worth writing down before a run starts, given that the same unwritten assumptions cost you on human handovers too. The words buy you a shorter review, and that trade is yours to set.

## The sentence is finished in your head, not in its text You are adding a retry policy to the outbound webhook sender of a parcel-tracking service, and you type one sentence: *add a retry policy to the webhook sender*. It reads like a complete instruction — an action, a component, a recognisable engineering noun. What it carries is an **outcome**. What it does not carry is any **behaviour**, and a retry policy is nothing but behaviour. The gap is invisible to you because you closed it yourself while reading. You know the receiver treats each delivery as a new event and will count a repeat twice. You know a payload the receiver rejected as malformed will be rejected the same way an hour from now. You know the sender restarts on every deploy, so anything held only in memory is lost. You have carried those three facts for months and never said them out loud, because everyone you have described this to already had them. **The run has the sentence and nothing else.** ## One request, several finished features Read the same words as someone with no memory of this service. Every row below is a defensible implementation of exactly what you wrote. | what you wrote | one reading | another reading | where the difference shows | |---|---|---|---| | "retry" | try again after any failure | try again only when no answer came back | a rejected payload is resent forever, or never resent | | "a retry policy" | a burst of immediate attempts | attempts spaced out over hours | a struggling receiver is hammered, or given room | | (unsaid) | attempts tracked in memory | attempts recorded durably | a deploy silently drops everything in flight | | (unsaid) | a repeat is harmless | a repeat carries the original's identity | one parcel scan is counted twice downstream | | (unsaid) | give up quietly | give up where an operator will see it | a customer's event disappears without trace | None of these is the run being obtuse. Each is a reading of your sentence, and it had to pick one. The uncomfortable part is that it picked **silently**: nothing in the request marked these as open, so nothing marked the choice as worth reporting back. ## Why you cannot rely on being asked A coding agent may ask a clarifying question, and many do. Three things stop that from solving the problem for you: - **It asks about what stands out in the text, not about what matters in your system.** The identity of a repeated delivery matters most here and is mentioned least. - **A run spanning many turns meets these gaps continuously**, not once at the start; it cannot stop at every one and still be a run. - **Answering the question it asked closes that gap and no others**, while leaving you with the feeling that the request has now been clarified. Being asked is a bonus. Producing the list is still your job. ## The audit that takes a minute Before the run starts, read your own request as a stranger would, and apply one test per sentence. 1. **Name two implementations** that both satisfy the sentence as written. 2. **Ask who could tell them apart** — the receiver, a customer, an operator, the person on call. 3. If somebody could, **the sentence is doing less work than you thought**; write down the reading you actually want. 4. If nobody could, **leave it open**, and mean it. Step four matters as much as the rest. A request is not a specification and does not improve by getting longer: detail that changes no decision is more material to review and one more chance to contradict yourself. What earns its words is a difference somebody would notice. ## What "under-specified" is not It is not a complaint about the model, and it is not an argument for finishing the design before you are allowed to start. The claim is narrower and duller: **a sentence that reads complete to its author can still admit several behaviours**, and on a run that takes many turns the chosen one is built on before you ever see it. How you cut the work into units and order them is a separate question; this one is about the sentence you hand over. ## What a good answer sounds like A weak answer blames the tool, or promises to "be more specific next time" without saying about what. A strong one is mechanical, and it works on any tool: *here is my sentence, here are two readings it allows, here is who would notice the difference between them, so here is the one line I would add before starting.* That answer is about your own request rather than the model's abilities, which is why it stays true as the tools change.

  • Does adding more detail always produce a better result?
    No. Detail earns its place by changing a decision; detail that changes none is more material to review and one more chance to contradict yourself. The test is whether removing the sentence would leave two implementations that differ in something the receiver, a customer or an operator notices. If it would not, leave it out.
  • The agent asked one clarifying question before starting — does that close the gap?
    It closes the gap it noticed. The others are unchanged, and what it chose to ask about reflects what stood out in your wording rather than what matters in your system. Answer it, then work through your own list anyway — the question you were not asked is the one worth checking.
  • How do you find the ambiguity when you are the person who wrote the request?
    Read it against the system rather than against your intent. For each sentence, name two implementations that satisfy it, then ask whether the receiver, a customer or an operator could tell them apart. Where somebody could, the sentence is carrying less than you assumed, and that is where the next line goes.

It is the difference between a note left for a colleague who has sat beside you for a year and the same note pinned up for a contractor who starts tonight with nothing but the note. The words are identical; only one reader can fill in what you left out.

saying these in an interview costs you the question

  • An ambiguous request comes back as a question, not a guess
  • A shorter request is always clearer, so leave the detail out
  • Any reasonable implementation will do; the rest is fixed in review
  • The request was clear — the model simply is not good enough yet
  • Writing down behaviour before starting is waterfall thinking