Define personas before you write tests
Name them. Give them a goal, a device, a level of familiarity. The more specific the persona, the more useful the test.
Playwright can verify that a route renders and that buttons exist. What it cannot do is tell you whether a real person would understand the page, get stuck at an unexpected flow, or abandon a checkout because of an unclear error message. Synthetic users fill that gap.
agents/synthetic_users (registry slug synthetic-customer) runs scripted personas through product flows and reports on what each persona experienced.
A synthetic user is an agent with a persona definition — a name, a background, a goal, and a level of technical sophistication — that navigates a product the way that person would.
The persona definition answers questions like:
The agent then navigates the product, makes the decisions that persona would make, and reports what it encountered: pages that loaded slowly, error messages it didn’t understand, flows it couldn’t complete, things it tried that didn’t work.
Route-level QA (the qa_agent) verifies that every page is reachable and renders correctly. It passes if /checkout returns 200 and the expected elements are present.
A synthetic user navigates from / to /product/[id] to /cart to /checkout, makes a purchase decision, enters payment information, and tries to complete the order. If the billing-address field is missing (one of the three bugs caught on the merch store’s first real sale, CHANGELOG 2026-06-09), a route-level test won’t catch it. A synthetic user trying to check out will.
The billing-address bug, the confirm-button bug, and the expand-details bug were all caught this way: the merch operator’s end-to-end test ran the full Stripe→Printful checkout flow as a real user would. Route-level tests had passed. The bugs only appeared when someone actually tried to buy something.
synthetic-customer patternThe synthetic_users agent was built as part of the merch build (registry synthetic-customer). It runs as a browser-automation agent that:
The persona definition says whether this is a first-time buyer, a returning customer, someone on mobile, someone with an older browser. The agent navigates accordingly and reports differently based on persona.
Build ships to preview → Route-level QA (qa_agent): do all pages render? → Synthetic user: can a real person accomplish their goal? → Human review of synthetic user report → Ship to productionSynthetic users are not a replacement for human testing — they are a filter. They catch the bugs that are obvious to a user but invisible to a test suite: confusing copy, missing fields, flows that work on the happy path but break when someone makes an unexpected choice.
The constraint is honest: a synthetic user is only as good as its persona definition. A well-defined persona that matches your real users will catch relevant bugs. A vague persona will miss the ones that matter.
Unit tests verify implementation. Synthetic users verify experience.
These are not competing approaches. You need both. A unit test proves that the checkout function accepts a valid card. A synthetic user proves that a person who just discovered your store for the first time can get from landing page to receipt without getting lost.
The merch store had both. The unit tests passed. The synthetic user’s checkout run caught three bugs. Neither test type would have caught the other’s failures.
Define personas before you write tests
Name them. Give them a goal, a device, a level of familiarity. The more specific the persona, the more useful the test.
Run against staging before production
Synthetic users should never post real reviews, send real messages, or generate real orders in production. Test on preview/staging URLs.
Report friction, not just failures
A page that loads and renders is not the same as a page a user can use. Have the synthetic user describe what it tried and what confused it, not just what returned an error.
Update personas after real users surface bugs
After the first real sale caught three bugs, the right follow-up is to update the synthetic user’s persona to include “tries to check out on mobile without filling all fields.” Each real-user failure is a new persona variant.
Next: The system that routes LLM calls between local and cloud. The Ollama Smart Router covers local-first model routing and the cost-tier approach inherited from OpenClaw.