Watching an agent think before trusting what it did

The problem

Agents act faster than people can supervise. A gather-act-verify loop runs in seconds, touches live data, and produces a verdict. The person responsible sees the verdict and nothing else. When the verdict is right, the invisibility feels like efficiency. When it is wrong, there is nothing to inspect, no record of what the agent gathered, what it believed, or how confident it was when it acted.

I kept building agents where the final output looked convincing and I could not see what had happened between the prompt and the answer. The project crystallized in a demo. I was showing someone an agent I had built and they asked a basic question: why did it do that? I could show the prompt, the tool calls, and the final answer. I could not show the sequence that connected them. That gap became the project: make the loop inspectable while it runs, instead of debugging it after. Underneath it sat an older preoccupation of mine, the way judgment errors travel upstream through systems that transmit conclusions while stripping the uncertainty off them.

What I built

Loop-visibility is a working agent supervision surface. An agent runs a gather-act-verify loop over synthetic financial data. Every step writes a trace row to Supabase before anything renders. The interface reads from the trace, not from the agent, which means the display can never claim more than the record supports.

The governing rule is evidence beside the verdict. Every conclusion the agent reaches sits next to the material it reached it from. Confidence is captured verbatim at each step and shown, not summarized. If the agent was unsure, the interface is unsure with it.

Three design decisions carried the build.

Trace before render. The write happens before the UI updates. This ordering is the whole argument in one line of architecture: the record is the product, the interface is a view of it. An agent system that renders first and logs second is a demo. One that logs first can be audited.

Confidence as a first-class element. Stated confidence appears verbatim at every step, never averaged into a summary score, because the movement of confidence across a run turned out to matter more than any single value. The one red element on this page marks the moment that movement triggered action.

The verify step gets equal visual weight to the act step. Most agent UI treats verification as plumbing. Here it occupies the same space as the action it checks, because the thesis is that verification is where human attention should land first.

What it is not

This is synthetic data and a single loop shape. It does not handle multi-agent traces or long-horizon tasks, and it records decisions and evidence, not the reasoning inside the model, a limit that turned out to be the most important finding. It is a proof of a design position, not a product. I built it to make an argument inspectable, the same way the interface makes the agent inspectable.

What building it taught me

The absolute confidence number protected nothing. The clearest pattern in the traces was confidence staying high while the evidence underneath it was weak or conflicting. In the money check-in run shown here, the agent flagged an AWS charge as a subscription price increase and carried the claim confidently through the act step; nothing in its stated confidence said it had committed to an interpretation the raw data did not support. The verify step caught it, checking each claimed increase against the underlying charges and reversing the AWS claim as usage-based variation rather than a price change. What turned out to be informative was movement, not magnitude. When a gather step came back with zero rows, the next plan step visibly revised its approach, and when verification failed a claim, the verdict arrived with the exact charges that failed it. Confidence works as an input to loop control, not as a statement of how likely the agent is to be right. The trajectory carries the signal, the snapshot does not, and the reason to show the full trace is exactly this: you can see whether the loop responded to new evidence or merely arrived polished.

Trace-before-render was the right call and it charged rent the whole build. Every step became a small transaction boundary: generate, normalize into the trace schema, write, confirm, and only then let the interface represent it. That makes streaming and optimistic rendering awkward on purpose, and it complicates failure handling in a specific way: a model call can succeed while the trace write fails, and you have to decide whether the agent continues, retries, or halts. The writes also sit serially in the critical path of every step, and I accepted that overhead as a design priority rather than measuring it, which I would do differently now. I still hold the ordering was correct, because the alternative creates a class of failure that defeats the project: the user saw an action or a rationale that the audit trail never captured. If the trace is the source of truth, nothing can be shown that is not yet true. The implementation warning I would give anyone building this: do not couple durably recorded with the whole UI waits. Hold the invariant that no step becomes an accepted state transition before its trace persists, but let transient states like gathering render without their own blocking round trip, make writes idempotent, and give every step a deterministic ID, because retries that duplicate trace entries poison the trace precisely when you need it.

The hardest limit was not missing data, it was a complete trace that still could not answer the question I cared about: why this path and not another plausible one. The rows captured what the agent gathered, did, verified, and how confident it claimed to be, but those are outputs of judgment, not the judgment. If the agent privileged one piece of evidence, discarded another, or silently resolved a contradiction, the trace showed the resulting choice without the decision boundary that produced it. Branching made this concrete: gather, act, verify reads like a faithful account, while an important alternative vanished before act was ever written, and nothing records that another path was considered, how close the call was, or which assumption tipped it. Confidence did not rescue this; a number can say uncertainty existed without saying what it was about. A trace is an observable record of decisions and evidence, not a window into reasoning, and chasing the model’s private chain of thought is the wrong objective anyway. The right objective is designing agents to externalize the consequential parts of judgment as structured artifacts: the alternatives that were live, the evidence for and against each, the assumptions carried forward, where uncertainty changed, and why a branch was taken or dropped.

What comes next

Loop visibility answered what happened. The open problem it left is what shaped the decision, and what was lost when the system committed. I am building against that now: a verification loop that audits agent-generated interfaces against an explicit design contract, produces evidence packets, and measures how often its automated verdicts agree with mine. The work is documented at slowsignal.studio.

Stack: React, TypeScript, Next.js, Tailwind, Supabase, Anthropic API. Live at loop-visibility.vercel.app.