Ship the answer with the question
Asking clarifying questions has a bad reputation. With a new client it supposedly reads as indecision; under time pressure, as friction; the standard advice is to impress with output instead. I think that advice mixes up two kinds of questions. An open question hands the other side homework. A question that arrives with its own candidate answer hands them a veto. Only the first kind stalls you.
A brief with a missing contract
The brief asked for a weather API whose endpoint contract is "defined in openapi.yaml". The repository contained a README and nothing else. The central artifact of the whole assignment was missing.
The obvious move is to ask where the file is and wait. But an open question blocks the asker, not the answerer. Until the requester sits down and authors an answer, the builder cannot move — and authoring is precisely the work that gets deferred to tomorrow. That asymmetry is why ambiguity survives: it is priced cheap for the person who owns the answer and expensive for the person who needs it. A tight schedule has no runway for paying someone else's deferral.
The spec I proposed instead
Instead of asking where the file was, I reverse-engineered a proposed spec from the live ARSO response, committed it to the repo root, and posted the question with the artifact attached: confirm I should build against my proposed contract, or send the canonical one — "I'll build against mine until I hear otherwise."
The committed file changed what the other side had to do, and that is why it worked: an open "where is the spec?" gets parked because it asks someone to author a document, while mine could be answered by reading one. Authoring needs a free afternoon; a veto needs a glance. The canonical file arrived, and my reply is still on the Slack log: "Provided file looks very aligned with my expectations." Two contracts written independently — one from the brief's intent, one from a live payload — had converged, which was also the check that my proposal was grounded rather than presumptuous.
Questions you can run
ARSO, Slovenia's environment agency, publishes weather data but no official public API. There were three ways in: a reverse-engineered public JSON endpoint, the official XML feeds, and a third-party mirror. Before asking which one to build on, I wrote two small scripts — arso-feeds.mjs and arso-fetch.mjs — that fetched each candidate and parsed what actually came back.
So the question I posted was not "which source should we use?" It was three options with their costs on record and a call already made: long-term the XML feed, for now the public JSON, "shout if you'd rather I commit to #2 from the start." Nobody had to argue from a guess, because the question carried its own evidence — the discussion starts from parsed output rather than from opinions about parsing. That is the shape I would now call an executable question: a question posed as a committed file, a runnable script, or a working default, so that answering it means reacting to something real. (Version 1.0.0 shipped on the XML feed in the end; the option I had filed under "later" arrived before release.)
Defaults with a veto
Testing surfaced an edge case: what should /v1/current?lat=55&lon= return — a query with half a coordinate? I implemented an answer first — treat the incomplete pair as absent, return all stations — and then asked: "If you prefer different behaviour of this please point out." The distance math went the same way: Haversine, with a note attached that "if there is not a really good reason to use other one this should do job good enough."
The work never waited on a reply, because every question left the system in a decided state. The default is the answer until somebody overrides it, and if the override comes later, applying it costs a small diff. I did not have a name for any of this while it was happening — in the moment it mostly felt like impatience. The shape only appeared when I reread the Slack log afterwards and noticed every message on it does the same thing: here is the situation, here is my answer, override me.
The portable version: take the vaguest requirement you are holding right now, write down the answer you would pick if forced, and send that — "building against this unless you say otherwise" — instead of the question alone. On solo work there is no requester to veto, but the move still pays: future-you would rather inherit a committed default than an open TODO.
There is a limit here I have not worked out. The pattern equates silence with consent, and on this project the equation held — a short build, one channel, one reviewer who read what I sent. On a slower project, with a busier requester, a confident default can sail through unread, and then "aligned" is something I declared rather than something we agreed on. I know how to keep a question from blocking the work; what I cannot yet tell, from inside the project, is whether a default nobody vetoed was a decision somebody made, or only silence.