Habr author lists five decisions an engineer must make before AI writes the code
A new Habr post looks at which engineering decisions need to be made before an AI agent starts writing code. The starting point is a bug in a marketplace's payment handler: two simultaneous webhooks both passed the PENDING check, and the money was credited twice. The author wrote that code himself, without AI. He walks through five situations from two projects: payment idempotency, data migrations, message delivery between service instances, provider integrations, and brand architecture. The result is a checklist of 12 questions. - The agent builds what the description says, and concurrency usually isn't in the description - Five risk areas: payments, migrations, messages, providers, brands - Run through 12 questions before generating code
AI-processed from Habr AI; edited by Hamidun News
One of the nastiest bugs in payment logic looks harmless: check that the operation is in PENDING status, move it to SUCCESS, and credit the balance. If two webhooks arrive at the same time, both see PENDING, both pass the check, and the user gets the money twice. The author of a recent Habr post found exactly this bug in his own marketplace. He wrote the code himself, without AI.
He uses this example to ask the central question: if an agent can now implement a handler like this in minutes, who sets the constraints that the functional description leaves out? The author then goes through five situations from a marketplace and a multi-brand platform, and closes with a checklist of 12 questions to work through before generating code.
Where the spec is silent
An agent does well what is described. The phrase "credit the balance on a successful webhook" is formally satisfied by both a correct implementation and a vulnerable one. The difference shows up only under parallel load, and a single-threaded test won't reveal it.
This is not a property of language models but of any task statement that omits non-functional requirements. A human usually fills the gap with experience and memories of past outages. An agent has no way to get that context unless it is passed in explicitly.
The author identifies five areas where such decisions need to be made in advance:
- payment idempotency: what counts as a repeated request and where that is guaranteed;
- data migrations: the order of changes and how the system behaves in intermediate states;
- message delivery between service instances: what happens if the recipient is the wrong one or is unavailable;
- provider integrations: how the system behaves with retries, delays, and non-standard responses;
- brand architecture: what is shared across all of the platform's brands and what is configured separately.
The author gives the full list of 12 questions in the original article. One caveat: the announcement doesn't include details of the solutions, so what follows describes how the industry usually handles such problems, not the author's conclusions.
How this is usually solved
The standard set of measures for the webhook problem is well known. A unique event key or an idempotency key on the request. An atomic conditional update of the form "move to SUCCESS only if the status is still PENDING," plus a check of the number of affected rows. A row lock held for the duration of the transaction. Any of these turns "check, then write" into a single indivisible operation.
The logic is similar for migrations and messages. Schema changes have to work while the old and new versions of the service run side by side. Delivery needs an upfront agreement on whether losses and duplicates are acceptable. These decisions shape the structure of the code, so making them after generation is already expensive: you will have to rewrite, not add on.
How to use this in practice
If you hand a task to an agent, attach a short block of constraints. What must stay true on a repeated call? On two parallel calls? On a partial failure of an external provider? When a new version is rolled out next to the old one?
It also helps to ask the agent not only to write the code but to list the assumptions it made about concurrency and event ordering. The gap between its assumptions and yours is the fastest way to find a hole in the task statement.
Finally, tests. A payment path needs at least one test with simultaneous requests; otherwise correctness is checked only at the "looks right" level. That is exactly how the handler looked in the author's story: the logic read as correct and broke only in a race.
The article's conclusions apply to human-written code as well. AI speeds up implementation, but decisions about the system's invariants still have to be made before it, and an engineer makes them.
- Oct 25, 2026Anthropic: Claude Sent Philadelphia Police a False Tip About a Murder on Its Own
- Oct 25, 2026Claude Can Now Run Up to 1000 Subagents and Find 66 of 70 Bugs
- Oct 25, 2026Microsoft Announces Maia 300: 40% More Tokens per Megawatt Than GPUs
- Oct 25, 2026Anthropic cuts internet access for all internal model tests after incidents
Key Questions Answered
Where the spec is silent?
An agent does well what is described. The phrase "credit the balance on a successful webhook" is formally satisfied by both a correct implementation and a vulnerable one. The difference shows up only under parallel load, and a single-threaded test won't reveal it. This is not a property of language models but of any task statement that omits non-functional requirements. A human usually fills the gap with experience and memories of past outages. An agent has no way to get that context unless it is passed in explicitly. The author identifies five areas where such decisions ne
How this is usually solved?
The standard set of measures for the webhook problem is well known. A unique event key or an idempotency key on the request. An atomic conditional update of the form "move to SUCCESS only if the status is still PENDING," plus a check of the number of affected rows. A row lock held for the duration of the transaction. Any of these turns "check, then write" into a single indivisible operation. The logic is similar for migrations and messages. Schema changes have to work while the old and new versions of the service run side by side. Delivery needs an upfront agreement on whet
How to use this in practice?
If you hand a task to an agent, attach a short block of constraints. What must stay true on a repeated call? On two parallel calls? On a partial failure of an external provider? When a new version is rolled out next to the old one? It also helps to ask the agent not only to write the code but to list the assumptions it made about concurrency and event ordering. The gap between its assumptions and yours is the fastest way to find a hole in the task statement. Finally, tests. A payment path needs at least one test with simultaneous requests; otherwise correctness is checked o
Delegate Deep Research, Coding & Workflows to an AI Agent
Deploy autonomous multi-step execution with NomadNet Agent (agent.nomadnet.ai) — automated web research, data synthesis, code generation, and complex task orchestration.
The AI world, distilled — once a week
Seven stories that actually mattered, hand-picked. No noise, no reposts, no press releases.
Done! Check your inbox for a confirmation.