From vague request to ready ticket
An agent given a vague request either guesses or stalls, and guessing is worse. The step that fixes it reads the request against the actual code, checks it against a readiness standard, and sends it back with specific questions rather than proceeding on an assumption.
Hand a builder a note saying the kitchen is wrong and they can start knocking down a wall, or they can ring you and ask which wall. The second call feels like a delay and is the cheapest part of the whole job.
This is the part that decides whether the rest works, and it is the part nobody demos, because a demo starts from a well-formed request. Real requests are not well-formed. They say the export is broken, or ask for a feature and omit half of what it would need. Hand one of those to an agent and it will either stall or, far more expensively, guess.
The arrow that goes backwards#
The mechanism is four steps and only one of them is interesting. Read the request together with the code. Check what is there against a readiness standard — a goal, acceptance criteria, the affected area, the expected behaviour, what is explicitly out of scope. If something is missing, post specific numbered questions and send it back. If it is complete, produce a work item with a context pack.
The interesting step is the third, and it is interesting because it is the one under pressure. Sending a request back feels like the automation failing to do its job — a person filed something, and the machine has handed it straight back. It is the opposite. A request returned with three specific questions has cost one round trip. A request guessed at has cost an implementation, a review, a merge, a deploy, and the conversation where somebody explains that this is not what they meant.
Ona’s ten-day run is the clearest available evidence for this, precisely because of how favourable its conditions were: a brand-new small application, built by the company that makes the agent platform, with the people who wanted the features in the room. It still reported unclear requirements as the single biggest cause of failure. That is the best case. On an existing system with requesters outside the team, the same problem is larger.
Two details matter for the questions themselves. They go back in the requester’s own language, so that answering is ordinary work and not a translation exercise — which is how you get good input from people who have no interest in your pipeline. And the message says plainly that it is automated, names the human or team accountable for it, and offers a way to disagree with the questions or ask for a person instead. A requester should never be left uncertain about whether a product decision has just been made on their behalf by software.
What a context pack holds#
A ready work item is not a tidier version of the request. It carries the results of the reading: which services are affected, which files and classes are the entry points, which existing implementation to copy the shape of, the acceptance criteria in testable form, the dependencies, and what would count as verification. The builder that receives it starts with direction instead of discovery, and discovery in a large repository is where most of the money goes.
It is worth being strict about the shape rather than trusting prose. A hand-off validated against a versioned schema — required fields for criteria, affected components, dependencies, assumptions, risks, verification — fails loudly when it is incomplete, and routes to a person, rather than arriving at the builder looking plausible and missing the one field that mattered. A free-form Markdown hand-off cannot fail; it can only be wrong.
This step is also where duplicates die cheaply. An agent that searches the backlog before decomposing anything will regularly find that the work exists, or was done last quarter, and can link it and stop. That is a small feature which pays for itself the first time it prevents two people building the same thing in parallel — and it only works because the step reads the repository rather than only the request.
Never rewrite what they typed#
One rule stands above the rest here: the original description is never edited. Questions, labels and the context pack are added alongside it. The requester’s own words remain exactly as filed, because they are the record of what was actually asked for, and every later argument about whether the right thing was built resolves against them.
Stating that as a rule in the harness is not enough, and this is the general lesson rather than a detail about work items. Anything an agent must never do is better expressed as something it cannot do. Give the readiness agent a credential with no write access to the description field, and a bug in the instructions cannot rewrite what somebody typed. Neither can a hidden instruction smuggled into the ticket body — which is not a hypothetical, and is the reason untrusted text needs its own design rule. A prompt is a request; a permission is an answer.
The last case is the one that separates a useful readiness step from a checklist. Sometimes the request is complete and still wrong — a button asked for on a screen that cannot hold that state, a feature that contradicts how the system works. A requester describes a symptom in whatever vocabulary they have. Treating their exact wording as a specification builds the wrong thing accurately. The right move is to name the concern, propose the alternative, and hand the decision to a person who owns the product — which is the same escalation route every other agent needs when it stops being sure.
IF YOU REMEMBER ONE THING
A request sent back with three specific questions costs one round trip. A request guessed at costs an implementation, a review, a deploy and an apology.
Questions people also ask
4 QUESTIONSWhy is request quality the hardest part of a software factory?
Because everything downstream inherits it, and no amount of capability compensates. Ona's own ten-day run reported unclear requirements as the single biggest cause of failure — on a greenfield application the team was building itself, where the requirements were as close to hand as they will ever be. On an existing system with external requesters the same problem is larger, not smaller.
Should the readiness check read the code, or just the ticket?
The code, or it cannot do the job. Checking a request against a checklist tells you whether the words are complete; checking it against the repository tells you which parts of the system it touches, whether something like it already exists, and whether the thing being asked for is even where the requester thinks it is. The second is a different and much more useful question.
Should a request that spans several services be split automatically?
No — that rule is wrong often enough to hurt. A change can legitimately be atomic across services, and splitting it produces partial implementations and incompatible intermediate states. The decision turns on release atomicity, ownership, API compatibility, rollback boundaries and whether each part delivers value alone. Some of those are lookups; the rest need judgement.
What happens when the request is architecturally wrong rather than incomplete?
It is flagged, not implemented literally. A requester asking for a button on the wrong screen has described a symptom in the vocabulary available to them. The right response is to name the concern and propose the alternative for a person to decide, rather than treating the exact wording as a specification — and to be visibly automated when doing it.