Every dev shop you talk to this year will tell you they use AI. That sentence now covers everything from "a senior engineer uses it to move faster through work they'd know how to do by hand anyway" to "we paste your spec into a chatbot and ship whatever comes back with minimal review." Asking "do you use AI" doesn't distinguish between those. You need a question that does.
The question: "What happens between the AI's suggestion and the code that ships?"
A shop with a real answer will describe a review step: a specific person, with specific judgment, who reads the generated code before it merges, understands what it does, and would catch it if it did the wrong thing. A shop without a real answer will describe a process, or a tool, or how fast it makes them — and quietly skip the part where a human actually checks the work.
Here's a concrete version of why that gap matters. Say the spec calls for: "a freelancer can have at most one active contract at a time." An AI coding assistant, working from that sentence alone, might generate something close but not quite right:
// AI's first draft
async function createContract(freelancerId: string, data: ContractInput) {
const existing = await db.contracts.findFirst({
where: { freelancerId, status: "active" },
});
if (existing) {
return { error: "Freelancer already has an active contract" };
}
return db.contracts.create({ data: { freelancerId, ...data } });
}
Read quickly, this looks correct — it checks, then creates. But there's no transaction around the check-then-create, so two requests arriving close together can both pass the check before either one creates a row, and the "at most one" rule silently breaks under real concurrent traffic. It's a classic race condition, the kind of bug that doesn't show up in a demo and does show up three weeks after launch, during the exact moment — two people racing to grab the same contract — that the rule existed to prevent.
// After review
async function createContract(freelancerId: string, data: ContractInput) {
return db.$transaction(async (tx) => {
const existing = await tx.contracts.findFirst({
where: { freelancerId, status: "active" },
// lock the row set so a concurrent request can't pass
// the same check before this transaction commits
});
if (existing) {
throw new ConflictError("Freelancer already has an active contract");
}
return tx.contracts.create({ data: { freelancerId, ...data } });
});
}
Neither version is "wrong" in an obvious way. That's the point. The gap between them isn't something a founder reading a proposal can catch — it's something an engineer who understands concurrency has to catch, on your behalf, before it ships.
Why this is nuube's whole pitch, not an aside
This is the actual mechanism behind "senior engineering judgment paired with AI-assisted delivery" — AI compresses how fast the first draft gets written, and an accountable senior engineer is still the one who reads it, understands it, and owns what ships. The speed comes from the first part. The "production-grade" part comes entirely from the second. A shop that's fast because of the first half and skipping the second half isn't actually faster — they've just moved the debugging to after launch, where it costs more and you're the one who finds it.
What to actually ask
Don't ask whether AI is used. Ask who reviews what it produces, what that person is specifically checking for, and whether they'd be comfortable putting their name on the code that ships. If the answer is a process diagram, push once more. If the answer is a person, you've got a real one.