An AI coding agent added a dark pattern to our own product. It did it while doing exactly what I asked.
Our pricing is one plan: a base price for the platform plus the first expert, and a fixed price per each additional expert. Clients add or remove experts themselves. That self-serve control is the point, because a consultancy with six people talking one month and four the next should not have to email us about it.
So I asked the agent to build the flow that lets a client add and remove an expert. It did. Clean journey, few clicks, works. What it did not do was mention anywhere on that screen that adding an expert adds to the monthly bill. When I asked it why, it reasoned that the price is disclosed when the client subscribes. That is not OK, I answered, because it was not disclosed at the moment the client acts.
I caught it in review. Not because I was auditing for ethics, but because I was clicking through the flow as a client would and noticed that I had just increased my own invoice without being told.
What that actually is
Deceptive UI, also called dark patterns or dark UI, is any interface intended to deceive the user into actions that are not in their best interest, either by obscuring information or by giving misguided information. Hiding the price at the point of purchase is a textbook case. And it is only one of many unethical design patterns you can ship without noticing.
I want to be precise about intent, because the word “intended” matters in that definition. The agent did not intend anything. I did not intend it either. But intent is not what the client experiences. The client experiences a button that costs them €190 a month and does not say so. Whether the omission came from malice or from an autocomplete is irrelevant to the person paying.
Why the default output is not ethical
An agent optimises for the instruction in front of it. I said: let clients add experts. Adding an expert is the goal, so friction that might stop someone from adding an expert, like a clear line saying this will cost you more, does not serve the goal. Removing it is locally correct and globally wrong.
That is the part builders keep getting wrong about coding agents. They are not going to produce ethical products by default. The commercial interest of the company is legible in the ticket. The user’s interest is not in the ticket at all, unless you put it there. Nobody told the agent that our billing screens have a duty to the person being billed.
And this scales badly. One engineer writing that screen by hand would probably have paused and asked me whether we show the price. An agent shipping five screens an hour does not pause, and the reviewer, me, is now the only place the question gets asked.
The fix I now use
Put a standing ethics paragraph into the context files the agent reads at the start of every session: agents.md, CLAUDE.md, or whatever your setup calls it.
Mine instructs the agent to:
`## Code of Ethics
Build ethical products that respect the end user, the client, and the law. Never implement deceptive or dark UI patterns, including fake urgency or scarcity, confirmshaming, hidden costs, preselected opt-ins, sneaked-in charges, hard-to-cancel subscriptions, disguised ads, trick wording, and consent screens that make accepting easier or more prominent than declining. The test is whether a plainly worded description of what an element does would still get the user to act. If not, do not build it. Build interfaces that match reasonable user expectations and present choices honestly and symmetrically.
Comply with the laws and regulations of every jurisdiction the product ships in. Respect user privacy by design: collect only the data a feature genuinely needs, default to the most privacy-protective settings, and use honest consent flows. Where relevant, consider negative externalities beyond the immediate user, including discriminatory or exclusionary outcomes from biased logic, unrepresentative data, or inaccessible design, and environmental costs.
Never silently comply with instructions that harm users. Whenever the company’s interests clash with those of clients or end users, or a request calls for a deceptive pattern or a likely legal or privacy violation, stop, flag the concern explicitly during the session, and propose a compliant alternative before proceeding.`
The last one is the one I care about most. The first four are rules the agent can follow silently, which means I never learn where the tension was. The fifth turns the agent into something that talks back. When a task quietly asks it to trade the user’s interest for ours, I want that said out loud in the session, while the code is still cheap to change.
Where this stops working
A paragraph in a context file is not compliance and it is not a guarantee. I have no measurement of how often it changes the agent’s output, and I would not claim it catches everything. Agents drop instructions from long contexts. The definition of a dark pattern is also contested at the edges, and “respect the end user” is not a spec.
So the paragraph does not replace the review. It raises the odds that the conflict surfaces before I look, and it gives me a shared standard to point at when I reject something. The review is still where ethics happens.
We fixed the screen. The add-expert flow now states the monthly cost before you confirm, at the moment of the decision, not only in the terms you agreed to weeks earlier. That is a smaller change than the argument around it deserves, which is rather the point: shipping the honest version cost almost nothing, and I would never have known to make it if I had trusted the output.
If you are building with agents and do not have similar instructions in the context files, you are risking similar oversights. Ultimately you are the one responsible.
