Allan Buntoengsuk

AML compliance platform

Deciding where an AI agent can act on its own, and where it has to stop and ask.

Year
2026
Role
Lead Product Designer
Tags
RegTechAI InterfacesB2BSystems DesignInformation Architecture

Overview

An AI agent reads the transaction history behind a money-laundering alert and returns a scored report ending in the alert being cleared or escalated. A compliance investigator then signs it. A regulator may open that file two years later, and the name on it is the investigator's, not the model's. So how do we have AI help the investigators while having the output be defensible?

Designing on top of a model is one thing when the output is a suggestion. It is a different problem when the output is evidence.

I was brought in by a seed-stage compliance platform to run discovery across the product, then to design the first phase of the build: a co-pilot that lets an investigator correct the agent inside the case, with every correction leaving a record.

Strategic Frame

The feedback loop already exists, but investigators had abandoned it for a spreadsheet.

Notes and flag corrections fed the model's evaluation runs, but nothing was coming back to the person who wrote them. Corrections went into a black hole. The workflow had moved into a shared Google Sheet that had become the case notes, audit trail, and client communication layer at once—none of which the model could read.

The brief had asked for a faster correction loop. Three structured interviews and a heuristic eval on the current product told me the constraint was elsewhere: a correction an investigator cannot point to later is probably worse than no correction at all.

Another brief assumption was that investigators read the narrative first and flags last. The one investigator I could observe did the opposite, starting in raw transactions. Not enough to prove a better order, but enough to know the assumed one may not reflect the mental model.

The bigger gap was a distinction nobody had drawn:

  • Checked information — this account received twelve deposits under $10,000 last month
  • The agent's judgment — the deposits were split deliberately to avoid a reporting trigger

The product displayed both the same way. The investigator had to sign a report where the count and the conclusion looked identical.

The model's evals
Two independent sources named the same missing primitive

Decision 1

Asking and changing are different actions, so I didn’t try to fit them in one chat box

A query answers and does not touch the data. But a correction should open a chain: parse the input, propose a plan, rerun on approval, write to the log. Same panel, same text field, two entirely different contracts with the case file.

Investigators reach the co-pilot three ways.

  • A persistent panel, always open, for work that starts with a question.
  • A hover trigger on any block, which pre-loads that block as context so the investigator isn't retyping what they're already looking at.
  • Inline text selection, so a correction attaches to the disputed sentence rather than the whole block, which is the difference between correcting a fact and reopening a conclusion.

The founder's reference point was Cursor, and he was right about the mechanic. Plan first, approve, then execute. I kept that and dropped the rest of the analogy, because Cursor edits a file you can revert privately and this agent edits a document a regulator reads. The plan step in Cursor is a convenience. But for us, it’s what makes the correction admissible.

Collapsing both intents into one chat box would have been faster to build and would have made every state change indistinguishable from a question in the interface. Any AI surface that lets a user both ask and mutate has to make that boundary visible in the interaction model, not just handle it correctly in the backend.

Decision 2

Correcting one fact can change five conclusions. That’s the moment where the AI stops and asks.

A correction to an occupation field doesn't stay in the occupation field. It moves through whatever the model concluded downstream, and the investigator can't see that reach from the sentence they're editing. So the agent proposes a reprocessing plan that names every block the correction touches (blast radius), including the secondary ones, and nothing runs until the investigator approves the list.

That's a boundary I drew on autonomy. Parsing an unstructured correction, asking a follow-up when the input is ambiguous, calculating its own blast radius: all automated, all things the model does better than a form would.

The plan isn't a confirmation dialog, but the artifact that makes the correction reviewable, because it states what the system believed would change before anything changed. An investigator who approves a plan has made a decision on the record. An investigator who clicks yes on "are you sure" has not.

Decision 3

The audit trail is a byproduct of correcting, not a second job.

Every correction writes a change card with an undo action, preserves the prior version, and lands in the case history. Nobody assembles evidence of what changed, because then the documentation itself becomes additional work. That’s what led to the spreadsheet the first time

Undo initially looked like the wrong instinct. An audit trail that can be reversed sounds like a weaker record, but it ended up being opposite: the undo is itself a logged event. What makes a file defensible is that every change and every reversal is attributable and ordered.

The design is fully specified and hasn't been built. The correction path writes to the log today; the surface for reading it back doesn't exist yet.

Case history, designed

What I decided not to do

Rerunning the full investigation was the obvious build but it would have affected credibility.

Engineering surfaced the constraint that made this decision, and I would have designed straight past it: the model's scores drift between runs on identical inputs, even when nothing changed. Meaning a correction that reruns everything hands the investigator a report where their fix landed and four unrelated conclusions also shifted, for no reason they can explain to anyone. So instead of the correction earning trust, it makes the whole process look unstable.

Because of that, reruns scope to the blocks named in the plan. That isn't a preference for smaller diffs. It's designing around a stated limitation of the model rather than designing as though the limitation will be fixed later.

The other thing I left alone: the layout breaks below 768px, and investigators run this in split-screen next to other tools. The constraint predates the co-pilot, and the co-pilot's density makes it worse. I wrote it into the handoff as a named, undesigned constraint for engineering to solve or accept as it was out of scope of the initial phase.

Split-view layout at the breakpoint that breaks. Designed; the underlying constraint was handed off unsolved

Impact

The panel, the hover trigger, and the correction chain are live.

A correction parses, asks for approval, writes a note with an undo, and queues a rerun scoped to named blocks. The plan card doesn't render yet, so approval happens in chat prose. Inline text selection was designed and hasn't been built.

The handoff was annotated Figma covering both intents, the approval flow, layout at each breakpoint, the case history surface, and the co-pilot components.

The measure I set was whether corrections move out of the Google Sheet and into the product. That data doesn't exist yet but what's true now is structural: notes, corrections, and the record of both have somewhere to live inside the case. A spreadsheet the model couldn’t read is no longer the system of record.

Reflection

One investigator was available to interview, and they supervised the agent rather than working a client queue. Her reading order also inverted the brief's: raw transactions first, flags last as a sanity check.

With a sample of one, I couldn't tell whether that was the natural mental model or an adaptation to an interface that made the intended order impossible. Both readings are plausible and they imply different products. Designing to either one would have been guesswork on my part.

So I designed the correction surface to work under both and named the open question in the handoff. The decisions I could make without resolving it (where autonomy stops, what a correction has to leave behind) I made and stated the reasoning for. The one I couldn't, I left visible.