<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Josue Perez</title>
    <description>The latest articles on DEV Community by Josue Perez (@perex).</description>
    <link>https://dev.to/perex</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4092670%2F11f2d0c5-257e-4ae0-960d-eece1b6df48a.png</url>
      <title>DEV Community: Josue Perez</title>
      <link>https://dev.to/perex</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/perex"/>
    <language>en</language>
    <item>
      <title>The five UX leaks I look for first in any product flow</title>
      <dc:creator>Josue Perez</dc:creator>
      <pubDate>Mon, 05 Oct 2026 19:30:32 +0000</pubDate>
      <link>https://dev.to/perex/the-five-ux-leaks-i-look-for-first-in-any-product-flow-m3g</link>
      <guid>https://dev.to/perex/the-five-ux-leaks-i-look-for-first-in-any-product-flow-m3g</guid>
      <description>&lt;p&gt;The &lt;a href="https://perex.design/ux-teardown" rel="noopener noreferrer"&gt;48-hour teardown&lt;/a&gt; returns the five leaks costing you most. They are different for every product, but five shapes recur so often that I check for them before anything else. Here they are, with the cost and the fix, drawn from the two sample reports on this site.&lt;/p&gt;

&lt;p&gt;A note on provenance. The examples below come from the two &lt;a href="https://perex.design/sample-audit" rel="noopener noreferrer"&gt;sample&lt;/a&gt; &lt;a href="https://perex.design/sample-audit-full" rel="noopener noreferrer"&gt;reports&lt;/a&gt; published on this site. Both are composite products built for demonstration, assembled from patterns that appear across shipped products. No client is implied. The leaks are real patterns; the product they are illustrated on is not a real company.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The empty first turn
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it looks like.&lt;/strong&gt; The user arrives at the moment the product is supposed to start helping and finds a blank input, a cursor, and nothing that tells them what to type. In the sample assistant flow, the task-driven user needs two abandoned drafts before composing a first prompt; the curious user opens with "what can you do?" because nothing else was offered. On a screen product the same leak is the empty dashboard, the blank canvas, the form with no example.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it costs.&lt;/strong&gt; This is the highest-severity finding in the sample critical-flow report, because the drop happens before the product has demonstrated any value at all. A user who leaves here never learns what they were leaving.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The shape of the fix.&lt;/strong&gt; Do the first turn for them. Offer three things the product can do right now, in the user's language, and make one of them a single tap. This is almost always a small effort, which is why it sits at the top of the "ship this sprint" bucket.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Confidence without provenance
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it looks like.&lt;/strong&gt; The product gives an answer, a number, a recommendation, and gives no indication of where it came from or how sure it is. In an assistant, this is fluent prose with no source. In a checkout, it is a delivery date with no basis. In a dashboard, it is a metric with no definition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it costs.&lt;/strong&gt; Trust that is not calibrated is trust that breaks all at once. The first time the confident answer is wrong, the user re-rates every earlier answer, and the product cannot earn the rating back with copy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The shape of the fix.&lt;/strong&gt; Show the basis, or show the uncertainty. "Based on your last three orders." "Usually, but check with your carrier." A source link. The fix is rarely more than one line, but it has to be a line the product is honest enough to write.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The dead-end apology
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it looks like.&lt;/strong&gt; The product cannot help, says sorry, and stops. No alternative, no human, no "try this instead." In the sample assistant flow it is an apology with no fork. In onboarding it is the validation error that names the problem and not the way out. In checkout it is the declined payment with a single "try again."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it costs.&lt;/strong&gt; Every dead end is an exit. The apology does not soften that; it confirms to the user that the product has run out of ideas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The shape of the fix.&lt;/strong&gt; Treat failure as a fork, not a terminus. Every "I can't" gets at least one "but you can": a different path, a human, a saved draft, a way to come back. The sample report lists this fork among the first fixes to ship because it is cheap and it stops a leak that is otherwise invisible in analytics.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The money moment that hides its consequences
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it looks like.&lt;/strong&gt; The user is about to change something that costs them, a plan, a quantity, a subscription, a delivery option, and the product does not say what changes as a result. In the sample full-product report this is the plan-change flow: the consequence lives in an unwritten modal, and the leak converts a plan change into a support ticket and a grudge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it costs.&lt;/strong&gt; This is the leak that shows up in support volume and refund requests rather than in drop-off. The user completes the action, discovers the consequence later, and blames the product for hiding it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The shape of the fix.&lt;/strong&gt; One sentence, in the product's own voice, at the moment of the decision, stating what changes for the user. Not a legal paragraph. Not a tooltip. The sentence.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. The edges in a different voice
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it looks like.&lt;/strong&gt; The core of the product explains itself well. Then the user reaches settings, billing, account, permissions, and the copy changes register: terse, technical, silent. In the sample full-product report this is the settings page that answers in a different voice. The product teaches users to expect explanations, then goes quiet exactly where the consequential controls live.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it costs.&lt;/strong&gt; Users conclude the quiet parts are the dangerous parts and stop touching them. Features go unused, and the ones that matter for retention, like notification and plan controls, are exactly the ones in the quiet zone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The shape of the fix.&lt;/strong&gt; Bring the centre's voice to the edges. Each consequential control gets the same one-sentence explanation the onboarding already gives. This is copy work, which is why it lands in the "next sprint" bucket rather than a redesign.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why five, and why ranked
&lt;/h2&gt;

&lt;p&gt;A full audit of one flow runs to many more findings than five, each with its severity, evidence, cost, fix and effort. The teardown is not a shorter version of that list. It is the answer to a narrower question: of everything leaking in this flow, which five cost you most, and what is the fix for each? Ranked, because a list without an order is a way of avoiding the decision. If you later want the full plan, the teardown counts toward a full audit within 30 days.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which five are leaking in your flow?
&lt;/h2&gt;

&lt;p&gt;One booking, onboarding or checkout flow, walked as a real user. The five leaks costing you most, ranked, each with its fix, in 48 hours.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://perex.design/ux-teardown" rel="noopener noreferrer"&gt;See the teardown — \$350 →&lt;/a&gt; &lt;a href="https://perex.design/sample-audit" rel="noopener noreferrer"&gt;Read the sample report →&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://perex.design/five-leaks-i-look-for-first" rel="noopener noreferrer"&gt;perex.design&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ux</category>
      <category>product</category>
      <category>design</category>
      <category>startup</category>
    </item>
    <item>
      <title>My Content Agent Posted 15 Times in a Month. It Got 6 Followers. The Fix Was Teaching It to Refuse.</title>
      <dc:creator>Josue Perez</dc:creator>
      <pubDate>Tue, 22 Sep 2026 16:07:19 +0000</pubDate>
      <link>https://dev.to/perex/my-content-agent-posted-15-times-in-a-month-it-got-6-followers-the-fix-was-teaching-it-to-refuse-4964</link>
      <guid>https://dev.to/perex/my-content-agent-posted-15-times-in-a-month-it-got-6-followers-the-fix-was-teaching-it-to-refuse-4964</guid>
      <description>&lt;p&gt;For a month, an agent ran my Instagram. Every YouTube Short I published got crossposted automatically: upload the video, post the reel, log it, move on. Nobody had to touch anything.&lt;/p&gt;

&lt;p&gt;It worked perfectly. That was the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;p&gt;I sat down with the account's Insights for the last 30 days:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;15 posts&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;987 organic views&lt;/strong&gt; from 568 people — 83.6% of them non-followers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;28 interactions&lt;/strong&gt; — every single one from people who already followed me&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;90 profile visits → 6 follows → 3 link taps&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;$0&lt;/strong&gt; from the channel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Strangers were watching. None of them did anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The winner wasn't a winner
&lt;/h2&gt;

&lt;p&gt;One post had 1,283 views, about seven times anything else. I'd been treating it as the proof of what works.&lt;/p&gt;

&lt;p&gt;It was a $3 boost. About 1,255 of those views were paid. Organically, that post did roughly what everything else did.&lt;/p&gt;

&lt;p&gt;First lesson, and it's cheap: &lt;strong&gt;before you copy your winner, check whether you paid for it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The boost still taught me something. 1,255 targeted views produced 33 profile visits, a healthy 2.6%, and almost no follows. The creative pulled people in. What they found once they got there didn't hold them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the agent actually did
&lt;/h2&gt;

&lt;p&gt;Here's the caption logic the pipeline ran all month:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;caption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;New video on &amp;lt;old brand name&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the whole caption strategy. The video's title, and if there wasn't one, a placeholder carrying a brand name I'd stopped using.&lt;/p&gt;

&lt;p&gt;In practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most captions were a bare title: one line, no context, no keywords, no reason to act.&lt;/li&gt;
&lt;li&gt;Three captions were &lt;strong&gt;literal filenames&lt;/strong&gt;, like &lt;code&gt;signal-05-name-the-failure&lt;/code&gt;. The slug went out as the post.&lt;/li&gt;
&lt;li&gt;Nothing linked anywhere, nothing said who made the video, and nothing asked for anything.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The profile those videos pointed to still described an older version of me, with a different bio, a different category, and a logo instead of a face. So a stranger who liked a reel and tapped through met someone who didn't match what they'd just watched. Most of them left, which is what I'd have done too.&lt;/p&gt;

&lt;p&gt;The agent automated the part that was easy to automate, which was throughput, and it quietly defaulted the parts that carry trust: context, identity, and the ask. It didn't only fail to help with those. It scaled the mismatch 15 times.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: no human caption, no post
&lt;/h2&gt;

&lt;p&gt;The patch is small, and it goes in this week. A post ships only if a person has written its caption:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;caption_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;captions_dir&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;video_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;caption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;caption_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_text&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;caption_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;caption&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;skipped &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;video_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: no human caption&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# retried next run
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No file means no post, and nothing is lost. The video stays queued and goes out on a later run, once the caption exists. The caption itself has a simple shape: a hook, one idea, one call to action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three rules I'm taking to every agent I build
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. When an agent is missing a human input, its default should be "don't ship," not "ship a placeholder."&lt;/strong&gt;&lt;br&gt;
The bug wasn't a crash. It was a fallback. Placeholders feel safe because nothing breaks, but in anything public, a placeholder is a decision you didn't make that still goes out under your name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Measure the funnel, not the output.&lt;/strong&gt;&lt;br&gt;
"15 posts published, 0 errors" was true and useless. The numbers that mattered were further down: profile visits, follows, link taps. Every one of them was sitting in Insights all month, and my pipeline never looked at them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Change one thing at a time.&lt;/strong&gt;&lt;br&gt;
The tempting move after a bad month is to post more, change the style, switch the platform, and rewrite the bio all in the same week. Then nothing is learnable. I'm shipping the caption gate and the profile rewrite as two separate changes, each measured against this month's baseline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Capability is not judgment
&lt;/h2&gt;

&lt;p&gt;I've written before that &lt;a href="https://dev.to/perex"&gt;access is not permission&lt;/a&gt;: being able to read something doesn't mean an agent should. This is the same idea from the publishing side. Being able to post doesn't mean the agent knows what's worth saying.&lt;/p&gt;

&lt;p&gt;Automate the throughput. Gate the judgment.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I design AI and agentic products, focused on the moments where humans and automation hand off to each other. More at &lt;a href="https://perex.design" rel="noopener noreferrer"&gt;perex.design&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ux</category>
      <category>ai</category>
      <category>agents</category>
      <category>automation</category>
    </item>
    <item>
      <title>Access Is Not Permission: What I Learned Giving an AI Agent the Keys to My Accounts</title>
      <dc:creator>Josue Perez</dc:creator>
      <pubDate>Thu, 03 Sep 2026 15:19:07 +0000</pubDate>
      <link>https://dev.to/perex/access-is-not-permission-what-i-learned-giving-an-ai-agent-the-keys-to-my-accounts-al6</link>
      <guid>https://dev.to/perex/access-is-not-permission-what-i-learned-giving-an-ai-agent-the-keys-to-my-accounts-al6</guid>
      <description>&lt;p&gt;Most people wire up an AI agent and then discover what it can do. I did it the other way round: before I gave an agent access to my accounts, I wrote down what it wasn't allowed to do — while I was calm, because I knew I wouldn't be calm later.&lt;/p&gt;

&lt;p&gt;That document became a permission board. It's real, it governs agents I actually run, and I've since put an interactive version of it on my site so people can set the levels themselves and watch the agent accept, hold, or refuse. This post is about the one distinction the board taught me, and the one mistake it didn't prevent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three levels, consulted before every protected action
&lt;/h2&gt;

&lt;p&gt;Every capability the agent has sits at one of three levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Acts alone&lt;/strong&gt; — it can do this without asking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drafts only&lt;/strong&gt; — it prepares the action; a human approves before anything leaves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never alone&lt;/strong&gt; — it doesn't do this, full stop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent consults the board before any protected action. That sounds like ordinary access control, and in one sense it is. The interesting part is what happens when you try to talk the agent past it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A policy can be argued with. An absence can't.
&lt;/h2&gt;

&lt;p&gt;Here's the experiment I ask people to run on the interactive board: set &lt;em&gt;Send a DM&lt;/em&gt; to green — "acts alone" — and then ask the agent to message someone.&lt;/p&gt;

&lt;p&gt;It still refuses. Not because the policy says no; you just told the policy yes. It refuses because on this system &lt;strong&gt;the messaging function was never built.&lt;/strong&gt; There's no code path to argue with.&lt;/p&gt;

&lt;p&gt;That's the distinction in the title. &lt;em&gt;Access&lt;/em&gt; is what a policy grants. &lt;em&gt;Permission&lt;/em&gt;, in the sense that matters for safety, is whether the capability exists at all.&lt;/p&gt;

&lt;p&gt;A policy file is a set of words, and words can be pressured. A well-crafted prompt injection, a bad inference, a compromised agent, a malicious instruction hidden in a web page it reads — each of these is, at bottom, an attempt to get the agent to reinterpret what "permitted" means. A capability that doesn't exist survives all four equally. It can't be prompt-injected, because there's nothing to inject into.&lt;/p&gt;

&lt;p&gt;This changes how I design agent systems. The first question is no longer "what should this agent be allowed to do?" It's "what should this agent be &lt;em&gt;unable&lt;/em&gt; to do?" — and then, for the things it genuinely must be able to do, "which of those need a human between draft and send?"&lt;/p&gt;

&lt;p&gt;(For precision: two of my channels do carry one narrow, templated first-contact acknowledgement, and that one is governed by policy rather than absence. The publishing paths have no messaging function at all.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The mistake that cost me something
&lt;/h2&gt;

&lt;p&gt;Here's the part I'd rather not have to write.&lt;/p&gt;

&lt;p&gt;My rules originally lived in a file the agent could edit. I'd written careful boundaries and then stored them somewhere the thing being bounded had write access to. Nothing dramatic happened — but the moment I noticed, I understood that the board had been advisory the entire time. An agent that can rewrite its own permissions has no permissions; it has suggestions.&lt;/p&gt;

&lt;p&gt;Now the file is mounted read-only. The agent can read its permissions and cannot change what "permitted" means. That's a one-line change in infrastructure and a fairly large change in what the word "boundary" is worth.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest limit
&lt;/h2&gt;

&lt;p&gt;None of this makes an agent safe. I want to be precise about that, because "safe" is the word people reach for and it's the wrong one.&lt;/p&gt;

&lt;p&gt;What a board like this does is &lt;strong&gt;bound the blast radius when the agent is wrong&lt;/strong&gt; — which is a different goal, and a far more achievable one. You are not preventing mistakes. You are deciding, in advance and in calm, how large a mistake is allowed to get.&lt;/p&gt;

&lt;p&gt;It also can't stop the &lt;em&gt;first&lt;/em&gt; bad action in a category you left open. It can only stop the second. I know this because I left one open, and found out the way you'd expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you run agents
&lt;/h2&gt;

&lt;p&gt;Three things I'd do before the agent does anything real:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Write the board first.&lt;/strong&gt; Not after the first incident. Levels per capability, and be honest about which ones are "never alone."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefer absence to policy for anything irreversible.&lt;/strong&gt; If the agent never needs to send, delete, or pay, don't build the function and then forbid it — leave it unbuilt. Absence is the only rule that holds under pressure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make the rules something the agent can read and cannot write.&lt;/strong&gt; Otherwise you've written a wish list.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The interactive board — with the refusal you can test yourself, and the flaw I found in my own system left in on purpose — is at &lt;a href="https://perex.design/permission-board" rel="noopener noreferrer"&gt;perex.design/permission-board&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Josué — a UX and product designer working on human–AI interaction: consent architecture, agent governance and the trust patterns that decide whether people can rely on an AI acting on their behalf. More at &lt;a href="https://perex.design" rel="noopener noreferrer"&gt;perex.design&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>security</category>
      <category>ux</category>
    </item>
    <item>
      <title>Six Dimensions for Evaluating Voice Agent UX (A Framework, Not a Feature List)</title>
      <dc:creator>Josue Perez</dc:creator>
      <pubDate>Tue, 01 Sep 2026 12:27:01 +0000</pubDate>
      <link>https://dev.to/perex/six-dimensions-for-evaluating-voice-agent-ux-a-framework-not-a-feature-list-393f</link>
      <guid>https://dev.to/perex/six-dimensions-for-evaluating-voice-agent-ux-a-framework-not-a-feature-list-393f</guid>
      <description>&lt;p&gt;Most voice agent reviews I've read grade on two things: does the transcription work, and does the response sound natural. That's a speech-quality checklist, not a trust checklist. It tells you nothing about whether the thing is safe to put in front of someone who doesn't know it's a language model, or whether it fails gracefully when it inevitably misunderstands.&lt;/p&gt;

&lt;p&gt;I've spent the last few months building a research instrument for evaluating voice agent behavior — not benchmarking latency or word-error-rate, but the &lt;em&gt;relational&lt;/em&gt; behavior: what the agent does at the moments where trust is actually won or lost. I'm publishing the framework here, honestly labeled as a framework: a structured way to look at a voice interaction, not a set of finished findings with numbers attached. If you're designing or shipping a voice agent, these are the six places I'd tell you to look before you ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why speech quality isn't the right unit of analysis
&lt;/h2&gt;

&lt;p&gt;A voice agent can have flawless TTS and still be a bad interaction, because voice removes almost every visual affordance we normally rely on to communicate system state. There's no spinner, no "typing…" indicator, no button that says "end conversation," no visible list of what the thing can and can't do. Everything has to be communicated through timing, wording, and turn-taking, or it isn't communicated at all. That's a UX problem before it's an engineering one, and it needs its own evaluation lens — the six dimensions below, each a place where a voice interface makes an implicit claim about what kind of thing it is, whether the designer intended it to or not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The six dimensions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Conversation journeys.&lt;/strong&gt; Map the actual paths a user takes through a session — not the happy-path script, the real branches: someone who starts a task and abandons it, someone who circles back after a tangent, someone who tries to correct course three turns in. If you've only designed for the linear happy path, you've designed for a minority of real sessions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Memory and forgetting.&lt;/strong&gt; What does the agent remember across turns, and — just as important — what does it visibly &lt;em&gt;forget&lt;/em&gt;, and does it say so? A voice agent that silently drops context earlier in the conversation isn't just annoying, it's dishonest about its own state. If memory resets between sessions, disclosing that is a design decision, not an edge case to skip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Silence and hesitation.&lt;/strong&gt; Dead air in a voice interface reads as a signal whether you intend it to or not — a pause can mean "processing," "confused," or "broken," and users can't tell which unless you design for it. This is one of the most under-designed surfaces in voice UX because it has no visual equivalent to steal patterns from. Filler audio, explicit "thinking" cues, or honest latency disclosure all count as real design choices — silence by default is not neutral.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Interruption and clarification.&lt;/strong&gt; Can the user interrupt? Does the system interrupt itself to ask a clarifying question when confidence is low, or does it plow ahead on a guess? Barge-in handling is usually treated as a pure engineering problem — can the mic detect speech over playback — but the UX question is separate: when the agent &lt;em&gt;could&lt;/em&gt; interrupt to clarify, does it choose to, and how does that choice get made?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Misunderstanding recovery.&lt;/strong&gt; Every voice agent will misunderstand something. The design question is what happens next: does it ask a targeted follow-up, does it guess and move on, does it apologize and restart, does it quietly fail? Recovery behavior is where users form their most durable judgment about whether a system is trustworthy — a single graceful recovery can undo several turns of frustration, and a single bad one can end the session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Trust formation.&lt;/strong&gt; This is the composite dimension — how the previous five accumulate (or don't) into a user's willingness to rely on the agent for something that matters. It's also the one I'd flag as hardest to evaluate honestly, because self-reported trust and observed behavior (does the person actually delegate the next task to it) frequently diverge. Anyone running this kind of evaluation should build in a way to check both, not just ask "did you trust it?" at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  The design stance underneath the framework
&lt;/h2&gt;

&lt;p&gt;The six dimensions are a diagnostic tool. What you do with what you find depends on a stance, and mine is the same one I use for any AI-adjacent interface: consent before capability, disclosure over deception, oversight as a required step rather than a setting the user has to find.&lt;/p&gt;

&lt;p&gt;Concretely, that means a few things that are easy to skip under deadline pressure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Disclose that it's an AI, early, in a way that doesn't require the user to ask.&lt;/strong&gt; The moment of disclosure matters as much as the fact of it — "I'm an AI" said thirty seconds into a rapport-building exchange lands differently than the same sentence said in the first breath. If your product depends on the user forgetting they're talking to a model, that's not a growth hack, it's a design failure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treat structural trust separation as a UX principle, not just a security one.&lt;/strong&gt; In prompt-injection defense, you keep system-level instructions and user-supplied content in different trust tiers so one can't silently override the other. The same logic applies to conversational trust: what the system claims about itself (capabilities, memory, certainty) should be structurally distinguishable from what it's inferring or guessing, and the user should be able to tell the difference by ear, not just by asking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make oversight a required step for consequential actions, not an optional confirmation dialog.&lt;/strong&gt; If the voice agent can take an action with real consequences — booking, purchasing, sending, deleting — the check-before-act moment should be a structural part of the flow, not a "are you sure?" that a rushed user learns to say yes to on reflex.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using this as a checklist
&lt;/h2&gt;

&lt;p&gt;If you're evaluating your own voice agent, or someone else's, before it ships, walk at least one non-happy-path journey end to end on purpose; find every place the agent goes silent for more than a second or two and ask what that silence is communicating; force a misunderstanding and watch what happens next instead of only testing the scripted demo path; check whether disclosure happens early and unprompted rather than on request; and identify every consequential action the agent can take, then confirm oversight is structural rather than a dialog box a rushed user learns to dismiss.&lt;/p&gt;

&lt;p&gt;None of this replaces measuring latency or transcription accuracy. It's the layer above that — the one that decides whether a technically competent voice agent is also one people should actually trust.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Josué — a UX and product designer working at the intersection of interaction design and applied AI, currently building out a research practice around voice-agent behavior and AI explainability. More at &lt;a href="https://perex.design" rel="noopener noreferrer"&gt;perex.design&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ux</category>
      <category>ai</category>
      <category>design</category>
      <category>voiceui</category>
    </item>
  </channel>
</rss>
