Personas
A synthetic panel for testing an idea, a business model or a price before spending money on it. Built to be pessimistic on purpose, because a language model left alone likes everything.

0 of 3,680 answers chose to pay the listed pricePersona attributes drawn from INSEE tables, never by the modelBase populations for France, Singapore and the USA sales pitch lifts the trust objection from 27% to 93%
The problem
I have more product ideas than evenings. For each one the questions are the same: does anyone need it, at what price, and what will make them say no. Real user interviews answer that, but nobody runs twenty interviews for an idea that may not survive the first five.
Asking a language model to play the customer is the obvious shortcut, and it is useless as is. The model is polite, approves of everything, and invents a convenient need for whoever it is asked to be.
What it does
I describe an offer in a file: the pitch a user would see, the price, the free tier, the alternatives that already exist. Personas draws a few hundred people from a statistical base population, optionally a target group and a control group, and asks each of them what they would actually do this week after coming across it.
What comes back is read by segment: who ignores it, who signs up for free, who would pay and at which price tier, and which objections stop the others. Two variants of an offer can be run on the same people, and the difference between them is the most reliable thing the tool produces.
It is a filter for bad ideas and a generator of objections, not a forecast. Absolute purchase levels are always shown with a correction and a confidence index, never alone.
- Engines
- Claude through the CLI, or an open model on a local GPU
- Also accepts
- The user's own key: Anthropic, OpenAI, Gemini, OpenRouter
- Storage
- One SQLite file per user
- Interface
- Web dashboard, CLI and a local MCP server, in French and English
Where an idea gets stopped, and by what
A study spends one model call per persona, so code checks the offer, the target and every answer around those calls. The results then have to prove their figures.
- 1Offer file
- 2Target previewOther branch: too broad: Offer file
- 3Tone check(clear)
- 4Neutral rewrite(refused)
- Back to step 3, Tone check (accepted)
- 5Frozen sample(neutral)Other branch: Persona answers
5 scenariosPick one, the steps above follow itPick one, the diagram replays its path
An oversold pitch scores 100 on toneRewritten first
- Decided by
- Code. A lexical score of 25 or more refuses the study. A person accepts the rewrite, or forces the study and the confidence index flags it.
- Personas saw
- No persona has seen anything yet. An assistant rewrites the pitch, and code checks that every number and name survived.
- You get
- The same offer in a factual voice, scoring 0, with a word-level diff to accept.
A target too broad for the offerWarned first
- Decided by
- Code, on the local model's estimate: above 10% likely not concerned, an alert appears before launch. A person tightens the filter or goes ahead.
- Personas saw
- Only a local open model, two one-token calls per persona. Built after Voxa spent 450 calls on a target nobody had looked at.
- You get
- The estimated share with its interval, and the profiles to filter out.
A persona mentions a child its profile does not haveRepaired once
- Decided by
- Code compares the answer with the drawn profile. One repair is allowed, and it may not make the answer kinder to the offer.
- Personas saw
- Its profile, the offer, and the list of contradictions in its first answer.
- You get
- A corrected answer, with the original kept. If the repair fails, the answer stays flagged.
A follow-up study aimed at the wrong populationDropped
- Decided by
- Code. Every cited figure and proposed study is checked against the data, with one repair. This one used a Singapore module on the French base.
- Personas saw
- The computed summary and a selection of verbatims, not the people behind them.
- You get
- The readout without that study, and a line saying why it left. All 173 figures cited across five readouts passed.
Voxa at €29 once, then €4 a month, on the same 200 peopleOne-time wins
- Decided by
- The gap between two runs on the same sample, the most reliable thing the tool produces.
- Personas saw
- The same profiles. Only the price changed between the runs.
- You get
- "Would never pay" at 32% against 46%, with absolute levels still marked indicative.
Voxa figures are single runs, made before a persona card fix.
Architecture
- DashboardReact
Study engine
- Personas HubHono, Postgres
Study engine
- Study engineTypeScript, SQLite
Claude, Local model
- ClaudeCLI or API key
- Local modelOllama, local GPU
Base population
A country pack of sourced statistical tables: age, region, occupation, household, income, spending, subscriptions. Each persona is drawn deterministically from a seed, then given a short narrative by the model, which never touches the attributes.
Thematic modules
Declarative YAML that adds domain attributes such as gaming habits or work software, with conditional distributions and their sources. An assistant drafts them from web research, and a human validates them before any study can use them.
Study engine
One call per persona, a closed seven-day behaviour scale, Van Westendorp and Gabor-Granger for price, and about ten consistency checks that trigger one repair toward the cautious answer. Every response is written as it arrives, so a study interrupted by a usage limit resumes where it stopped.
Analysis and dashboard
Aggregation by segment, target against control, engagement drivers with permutation tests, and recommendations whose evidence is checked against the summary before they are shown.
Personas Hub
A library of modules and country packs with immutable signed versions and a quality score the server recomputes itself, so a module cannot grade its own sourcing.
Built with
Engine
- TypeScript
- Engine, CLI, dashboard API and Hub, one language end to end
- Zod
- Validates every model answer and every country pack table at load time
- SQLite
- Personas, studies and responses, with uniqueness that makes a rerun fill only the gaps
Inference
- Claude Code CLI
- Interviews and narratives, with the JSON schema enforced on the output
- Ollama
- A 27B open model on a local GPU, used for one-token relevance triage
Interface
- Hono
- Dashboard API and the Hub's server-rendered pages
- React
- Dashboard, with hand-made SVG charts and no chart library
Hub
- PostgreSQL
- Catalogue, immutable versions and full-text search in French and English
- Ed25519
- Signs every published version so an install can be verified
Measured
Every study here ran Claude Sonnet through the CLI. Calibration: the same 300 personas from the France base, each known product pitched once without its brand and once with it, compared with published adoption figures. Tone: the same 60 personas, a fictional concierge service, three pitches carrying the same information in a factual, commercial and oversold voice.
Replaying products with a known outcome
| Product | Trial, unbranded | Trial, branded | Real reference |
|---|---|---|---|
| ChatGPT | 16% | 18% | 20% in year one |
| Yuka | 1% | 22% | about 16% in 2018 |
| Canva | 1% | 0.3% | 1 in 8 monthly |
Close on ChatGPT, far off on Canva, whose real use comes from curiosity that a rational seven-day decision does not capture.
Same offer, three tones
| Pitch | Trust objection | Would never pay |
|---|---|---|
| Factual | 27% | 53% |
| Commercial | 55% | 45% |
| Oversold | 93% | 30% |
Hype raises distrust and anchors perceived value at the same time, so it distorts the test of the idea in both directions.
What this does not prove
Single runs. Replaying the same prompt on 20 personas moved "would never pay" by 15 points, so smaller gaps are noise. The real ranking of the products was not recovered, which is exactly why absolute levels are labelled indicative.
Under the hood
01Ask what they do this week, not what they think
An opinion costs a persona nothing, so the model hands out approval. The protocol asks for one behaviour on a closed scale, from ignore to pay and recommend, and states that ignoring is the normal answer. Acting has to be justified by a need the persona can name and that appears in its profile. Each persona also carries a monthly discretionary budget and its existing subscriptions in plain figures, so saying yes means saying where the money comes from.
02The model never chooses who someone is
Left to invent people, a language model produces the same handful of stereotypes. Attributes are drawn from sourced tables through a conditional chain, with a seeded generator keyed on the seed and the rank, so persona number 400 is the same whether 500 or 5,000 are drawn and a sample can be extended later. The draw is checked against the source margins with a chi-squared test. The model only writes a short narrative on top, and a narrative that contradicts the profile is rejected.
03A pitch with a sales tone is refused
The tone experiment showed that superlatives move the results more than most changes to the offer itself. The current protocol scores the pitch lexically and refuses a study above the threshold unless the refusal is explicitly overridden. An assistant proposes a neutral rewrite, checks that every number and name survived it, and shows the word-level diff for a human to accept or keep the original.
04The Hub recomputes quality instead of trusting it
A module that declares its own quality is a module that will declare it high. On publication the Hub revalidates the YAML with the engine, runs a preview on 10,000 virtual personas, and computes the score from sourcing, margin checks, preview alerts and documentation. Versions are immutable, enforced down to a database trigger, so a study can always name exactly which population it ran on.
Gallery


Try it
Not yet. It runs on my own network and is not reachable from outside.
There is a hosted version where each account brings its own AI key, and a Hub for sharing modules, but neither is open to the public while the methodology is still being calibrated. This page carries the protocol, the measured limits, and what went wrong, which is what would decide whether to trust it anyway.
What broke
Nobody ever pays
Across 20 studies and 3,680 answers, not one persona chose to pay the listed price within seven days, while 431 said yes to a lower tier. Loosening the horizon, the need rule or the price question changed nothing measurable: the pessimism is structural. Absolute levels are now shown as indicative, with an estimate and its interval, and that estimate is still labelled uncalibrated.
450 calls spent before looking at who was being asked
The first full study on Voxa ran without a look at the target. 16% of it turned out not to be concerned, including site workers who counted morning briefings as meetings. A study can now start with a preview of the target and a cheap relevance triage on the local model, before a single expensive call. Both are optional steps, outside the study run itself.
Hiding the brand did not hide the product
Calibration pitched known products without their name to measure the brand effect. 42% of the unbranded Canva answers named Canva anyway, and saw the offer as a copy. The unbranded column measures something, but not what it was designed to measure.
The objections were worth it on their own
For Voxa the first objection was not the cloud, which I expected, but the employer-managed Mac and consent to record, cited by three quarters of the target. A follow-up study confirmed that a message aimed at IT departments does not lift it. That one finding changed the product's positioning, and no conversion figure was needed to get it.
Links
Nothing to open from here.
Source
Not public
Not public. The engine, the Hub and the hosted service live in a private repository.