The most important thing an AI interface can make obvious is also the easiest to blur: what has actually happened, and what is only proposed.
A person using an AI product should always be able to tell three things apart. What did the model merely suggest. What did it generate but not apply. What changed something in the real world. When those run together, the product can feel magical in a demo and then lose trust the first time it does something the user did not expect.
Good AI interfaces make agency visible. That is not a copywriting task. It is part of the product model.
Why this is a real risk, not a nicety
Two things make trust boundaries concrete rather than philosophical.
The first is prompt injection. When a model reads untrusted content, such as a web page, an email, or a document, that content can carry instructions. OWASP lists prompt injection as the top risk for LLM applications, and the practical consequence is that you cannot assume a proposed action reflects the user’s intent. A request to summarize a malicious page can come back as “delete the calendar.” If the interface executes that without a boundary, the injection succeeds.
The second is irreversibility. Sending, publishing, deleting, paying, and granting access are not undone by a refresh. The cost of a wrong automated action is not symmetric with the cost of asking first.
Both push the same way. The interface needs explicit boundaries between what is proposed and what is committed.
Three states
Most AI moments fall into one of three states, and each deserves different treatment.
- A suggestion is advice. Nothing has changed.
- A draft is generated work. It exists but is not applied.
- An action changes state somewhere: sending, publishing, updating, deleting, buying, granting access, committing.
stateDiagram-v2 [*] --> Suggestion Suggestion --> Draft : accept / refine Draft --> Suggestion : revise Draft --> Action : approve Action --> Draft : undo / rollback Action --> [*] : execute
The rule to place anything is simple.
flowchart TD
Q1{"Does it change<br/>external state?"} -->|"Yes"| Action["Action"]
Q1 -->|"No"| Q2{"Is it generated<br/>content?"}
Q2 -->|"No"| Suggestion["Suggestion"]
Q2 -->|"Yes"| Draft["Draft"]
If nothing changed, it is a suggestion. If something was generated but not applied, it is a draft. If the world changed, it is an action.
Suggestions should be easy to ignore
A suggestion should be lightweight and easy to challenge. Show why the assistant thinks it is useful, offer alternatives, and make it low-friction to dismiss. The failure mode is a suggestion styled like a committed result, so the user assumes something happened when nothing did. Invite, do not trap.
Drafts need editing, comparison, and safe rendering
A draft is an editable artifact, not a chat answer to copy out by hand. The user should inspect it directly, edit in place, and see what changed from a previous version. This is what Claude’s Artifacts and ChatGPT’s Canvas provide: a place for generated work to live as an object you can revise.
Drafts also raise a rendering question people underestimate. Model output is untrusted input. If you render its markdown or HTML directly, you have a cross-site scripting hole: the model, or an injection upstream of it, can emit a <script> or a malicious link, and a naive dangerouslySetInnerHTML will run it. Trusted rendering means you sanitize, allow a known set of elements, and never execute model-produced markup just because it looks like content. The model proposes the content. Your renderer decides what is safe to show.
Actions need a preview and a confirm
The closer a feature gets to external side effects, the more explicit the UI has to be. A good action preview answers four questions before it asks for approval:
- what will happen;
- where it will happen;
- what data it will use;
- whether it can be undone.
This is the human-in-the-loop step, and it is where you spend your trust budget well: confirm the irreversible and the high-impact, let the cheap and reversible flow through. Pair it with least privilege on the tools the agent can call, so a confirmed “send email” cannot quietly also delete a file.
A contract for boundaries
type TrustBoundary =
| { state: "suggestion"; dismissible: true }
| { state: "draft"; editable: true; versioned: boolean }
| { state: "action"; requiresConfirmation: true; reversible: boolean };
This is not a full implementation. It is a reminder that the state of trust belongs in the data model, so the interface can render the right treatment instead of leaving it to copy.
Product implication
A trustworthy AI interface is not one that pretends the model is always right. It is one that makes uncertainty, authorship, and approval legible. The user can see what is proposed, what exists, and what changed, and can stay in control of the decisions that matter.
That is what turns a surprising demo into something people will run against real data and real accounts.
What to watch next
As agents take more steps on their own, the gap between suggestion and action compresses. An agent that books, sends, or commits across several steps without a clear pause removes the boundary this post depends on. The interesting work is keeping a meaningful checkpoint without making the agent useless.
Watch for reusable approval components and standard action-preview patterns, the way forms and modals became standard parts of the toolkit. Teams that ship trustworthy agents will treat confirmation as part of the system, not a dialog bolted on at the end.
The last post in the series looks at what holds all of this together over time: durable workflow state.