From AI Testing to Designers
Shipping the Fix

As Usability Lead for Ads Manager, I built an AI workflow that changed how our team dogfoods: from automated persona testing to shipping the frontend fixes myself. It cut our design to ship cycle in half.

50%
Design to Ship Cycle Reduced
10+
Frontend Fixes Shipped by Design in a Week
2
Personas Auto-Testing the Team’s Flows

I own the whole loop, from automated testing to shipping the frontend fixes myself. When a designer can put fixes into production, product quality stops waiting on engineering bandwidth.

Context

Keeping our flow at the org’s quality bar is a manual job. My team owns the experience advertisers use to promote an app; as its Usability Lead, I own that bar. We enforce it two ways, both by hand: quarterly dogfooding with our design leads, and rigorous external scoring from a central usability team.

In H1 2026, as the org began adopting AI, I asked a sharper question: how do I streamline that whole loop for my team, not just speed up one step?

Before & after

The dogfooding loop, rebuilt

Before · the manual loop
Manual dogfooding
Record & task every finding
Prioritization session
Usability roadmap
UI fixes cut for bandwidth
↻ repeats next quarter
After · with the dogfooding agent
AI agent dogfoods both platforms
Screenshots captured
Tasks filed
Effort sized
Fixes recommended
Quick UI fixes shipped by design
+157 −87
A leaner usability roadmap
The bottleneck

Every finding in the old loop, big or small, had to squeeze through the same gate: one quarterly prioritization session and a finite pool of engineering bandwidth. Big problems earned their spot. Small UI fixes queued behind them and rarely shipped, piling up as usability debt. Learning to vibe code as a designer clears that bottleneck. I find the issue, then ship the fix myself.

Automating UX Evaluation

Most of this work lived in systems design, cognitive modeling, and service design, not in Figma.

01

Eliminate inconsistency

Manual dogfooding surfaces different issues depending on who runs it. My CAPTURE → EVALUATE → ACT protocol runs an identical pass every session, so findings don’t hinge on the tester.

02

Scale coverage

One person now runs several sessions a day across personas and platforms, each a structured report with every issue graded against Meta’s quality rubric. A week’s work, done in an afternoon.

03

Embed the user’s perspective

It doesn’t just check whether things work. It plays specific advertiser archetypes, catching confusing defaults, jargon, and missing controls that functional testing walks right past.

Beyond Prompt Engineering

Steering the LLM, not just prompting it

The prompts hold the agent in character all session and block lazy AI habits like defaulting to “add a tooltip.”

Automating what everyone says needs a human

I broke “judgment” into concrete checks: can the persona tell what this page is for? Do they know what to do next?

Personas built from Meta’s own frameworks

Distilled from our Product Quality Scorecard and Usability Playbook, so the agent grades the way my team does.

Runs against the real shipped flows

Our codebase is linked in Claude, so the agent tests the actual app-ad flows from source, not whatever a test account surfaces.

Five sources of internal design knowledge, the same standards my team already used to judge quality, became a single evaluation protocol the agent runs every session.

Evaluation Criteria
What to inspect at every step of the flow.
Quality Axes (PQS)
The dimensions Meta grades UX on.
Product Quality Process
Severity, effort sizing, and triage rules.
Usability Scoring (UPB)
Meta’s 0 to 100 usability score.
Design System Patterns
App promotion pattern docs & conventions.
The Dogfooding Agent
Takes on a persona, checks every screen against those standards, and writes up what it finds.
Filed tasks
Classified tickets on the engineering board.
Prioritized
Severity scored and effort sized.
Screenshots
Captured and attached per issue.
Tracker log
A row per session in our sheet.

Filed straight into the tools the team already uses, ready to triage the moment a run ends.

First Time Priya
First Time Priya
Small Business Owner
personas/priya_first_time.md
name: "First Time Priya" archetype: "Small business, first app campaign on Meta, based in India" evaluation_lens: - "Is the terminology understandable for someone whose only reference point is Google UAC?" - "Are the defaults safe for a small budget?" system_instruction: | You must stay in character for the entire session. Do NOT evaluate based on standard UI heuristics. Evaluate strictly based on Priya's knowledge gaps.
Enterprise Marcus
Enterprise Marcus
Senior UA Manager ($2M+/mo)
personas/marcus_enterprise.md
name: "Enterprise Marcus" archetype: "Senior UA Manager running $2M+/month in app campaigns, based in US" evaluation_lens: - "Are power-user controls (SKAdNetwork, optimization events) easily accessible?" - "Does the system try to automate things I need manual control over (e.g. Advantage+)?" system_instruction: | You must stay in character for the entire session. Evaluate strictly based on Marcus's need for control, measurement confidence, and efficiency.
The same screen, two verdicts

I model personas by how someone thinks. Run the same screen through Marcus and Priya and one default flips from a power user’s frustration to a beginner’s relief, a conflict the same design has to resolve.

Real screen (Run 1)
Enterprise Marcus · measured
First Time Priya · projected
Advantage+ defaults ON
Friction. Hidden automation he’d want to disable.
Relief. The “let the system handle it” she expects from Google.
SKAdNetwork not visible
Blocking. Needs full control to protect measurement.
Hidden risk. She’ll mismeasure iOS and never know why.
Unconnected app, click does nothing
Friction. Knows to leave and use the App Dashboard.
Dead end. The most likely abandonment point in the flow.

Advantage+ defaulting ON is a retention risk and a retention aid at the same time, depending only on who’s looking. The persona system catches that contrast on every run, instead of leaving it to whoever happens to be testing.

What One Session Surfaced

For its first production run, the agent took Enterprise Marcus through the full App Promotion flow on iOS and Android, back to back, in about 90 minutes. One pass surfaced 18 issues, including things our manual sessions had been walking past. I’ve kept running it since; the numbers on this page are from that first session.

The agent narrating its CAPTURE and EVALUATE reasoning as Enterprise Marcus in the terminal while driving live Ads Manager in the browser
The agent mid-run. On the left it narrates the CAPTURE → EVALUATE loop in Marcus’s voice (“where is the conversion location picker?”); on the right it’s driving the real Ads Manager campaign setup. Every issue it files comes out of a live session like this one.
Persona
Enterprise Marcus
Flow
E2E App Promotion
Platforms
iOS + Android
Duration
~90 minutes
18
Issues surfaced
4
Launch blocking
58/100
iOS usability score
2/5
Cross platform consistency
43
Screenshots captured
What manual testing missed

When we dogfood our own product, we rarely step all the way into the advertiser’s shoes, so issues like these slip right past us. The agent doesn’t have that problem. Each one is filed as a task in the persona’s own voice, with the structured record attached for triage.

Launch blocking Task 01

SKAdNetwork configuration missing

The ad set has no SKAdNetwork section, so enterprise advertisers can’t configure their iOS measurement. Wrong defaults quietly degrade reporting, a real risk for advertisers spending $2M+/month.

Enterprise Marcus Enterprise Marcus

“I scrolled through the entire ad set for my iOS campaign. Where is SKAdNetwork? If the system is making SKAN decisions for me, I need to know what they are.”

agent_output/issue_01.yaml
issue_id: "SKAN_Config_Missing" quality_axis: "Coherent End to End" classification: "Launch-Blocking" rock_size: "Large (6+ months)" problem: "No SKAdNetwork section exists. For an iOS campaign, SKAN configuration is foundational to measurement." user_impact: "Enterprise advertisers cannot configure their iOS measurement strategy." persona_quote: | "I scrolled through the entire ad set for my iOS campaign. Where is SKAdNetwork? My entire iOS strategy depends on getting the conversion schema right." recommended_fix: "Surface current SKAN configuration as read-only summary in ad set."
Why the system beats a manual pass

A single report was never the goal. I wanted a system that runs the same way every time, faster, and catches what a tired tester on one platform would miss, like the cross platform bugs it caught running iOS and Android back to back.

Dimension
Manual
AI driven
Issues per session
3–5 typical
18 (first session)
Time
45 min – 1 hr, not exhaustive across platforms
~90 min, full pass on both platforms
Cross platform bugs
Rare (needs 2 sessions + a manual diff)
2, found automatically
Output
Manual table with screenshots
Structured report, scored & classified
Task creation
Often deferred, filed later if at all
Filed automatically to the board
Consistency
Varies with the tester
Identical protocol every run

The agent isn’t a replacement for manual testing. It handles the repetitive parts and hits both platforms every run, so I spend my time on the judgment calls instead of the clicking. A human still catches what it misses, and every issue it flags is still mine to verify.

I Found the Issues, Then Shipped the Fixes Myself.

The agent gave me a reliable, repeatable way to surface issues. But I didn’t stop at filing tickets. I tested every issue it flagged, confirmed it was real, then used vibe coding to write the frontend fix myself. An engineer on the team reviewed every diff before it landed in production.

Learning enough to close the gap between finding a problem and shipping the fix is what changed how I work. 10+ frontend changes landed in a single week, fixed by the person who understood the UX problem best instead of waiting for sprint planning.

10+
Frontend fixes shipped in one week
1
Person: detect, verify, fix, ship
0
Tickets filed to another team’s backlog
The loop
Agent finds issue I verify manually I vibe code the fix Engineer reviews Shipped
Repeated until all issues are resolved
↻ Repeated until all issues are resolved
One fix, end to end

A usability pass flagged the Attribution model field in ad set settings: an always-visible dropdown adding clutter to an already dense page, out of step with neighboring fields like Performance goal that stay collapsed until you need them. I converted it to the same progressive disclosure pattern, a read-only summary that expands to the full selector on click, then shipped it. An engineer reviewed the diff before it landed.

The committed diff: Convert Attribution model to progressive disclosure pattern, plus 157 minus 87
Committed and reviewed. A flagged usability issue going all the way to production code, written and shipped by the person who caught it.
Before Always-visible dropdown
Attribution model shown as an always-visible dropdown in ad set settings

Open by default, adding height to an already long page.

After · shipped Progressive disclosure
Attribution model collapsed to a read-only summary that expands on click

Collapses to a read-only summary, matching the Performance goal field. Expands to the full selector on click.

The system now runs the same way for our team dogfooding sessions. The agent handles detection, I handle verification and fixes, and an engineer handles review. The whole design to ship cycle dropped by half.

When design can ship frontend, the small fixes that used to die in prioritization get caught by the person who cares most. Design holds the quality bar and enforces it directly in the code.

What I’d Watch, and Where It Goes

This didn’t stay my experiment. Once it was working, I presented it to our usability design leads, who adopted it across the org as a shared skill for other teams to fork and iterate on. I’ve built it twice now; a third would take about a day, so it’s a template, not a one-off.

What I’d build next

Today the skill stops once an issue is filed. Next is closing the loop: let it propose the fix, then rerun the same session after the fix ships to confirm it held. That turns a testing tool into regression detection on a schedule.

If tokens were the constraint

The full two platform pass is token heavy. On a tight budget I’d cut scope before rigor: point runs at whatever changed that week instead of the whole flow, drop to one persona per session, and capture screenshots only on failures. Judgment calls are where the spend pays off, so screen description would move to a smaller model first.

Where it’s still thin
  • Still a small sample. The headline numbers come from the first session. Later runs have told a similar story, but this is early data, not a study.
  • Personas validated only by me. Built from internal docs and my own read, never sat next to a real advertiser.
Next Project Horizon VR Work Events →