Teste com personas — clientes sintéticos que percorrem o seu produto¶
Cliente real encontra o que quem constrói não consegue: bug no caminho infeliz, tela que confunde, texto que não explica, fluxo que perde gente em silêncio. Esperar usuários reais baterem nessas paredes é o loop de feedback mais lento e caro que existe.
O módulo de persona coloca um cliente sintético na frente do seu produto: um arquétipo fundamentado em evidência que percorre um fluxo declarado com seus próprios objetivos, paciência, vocabulário e limites — percebendo a interface real, reagindo em personagem, registrando cada passo no diário — e termina o run com um relatório estruturado do que quebrou, do que confundiu e de onde ele desistiu.
Módulo diferente de Personas
Personas são os decisores que o Leopold sintetiza quando um run
encontra um nó @human. Esta página é sobre simulação de cliente — personas
que testam o produto. Compartilham uma filosofia (limitado, honesto, registrado),
não código.
As três peças¶
Duas skills portáveis são donas da semântica de persona, vendorizadas byte a byte e instaladas nos dois harnesses:
persona-contract-buildercompila umpersona-contract/1.0: um arquétipo fundamentado em evidência com catálogo de claims, ledger de fontes, fronteiras epistêmicas (o que essa persona sabe, meio-sabe, não pode saber), modelos de comportamento e comunicação, e um gate de validação explícito. Sem estereótipos, sem citação inventada — dimensão sem suporte fica registrada como desconhecida.persona-contract-runtimeexecuta um contrato um turno limitado por vez: `contrato + estado anterior + estímulo visível + tarefa → reação + ação observável- delta de estado`. O protocolo de sinceridade é o produto: confusão continua confusão, desconfiança continua desconfiança, e abandono é respeitado — nunca amaciado em elogio.
A terceira peça é do Leopold: /leopold-persona (Claude Code) /
$leopold-persona (Codex CLI) conduz o run — workspace, loop, diário,
continuidade, evidência, relatório.
A estrutura (nada solto)¶
.leopold/persona/
personas/<id>/contract.yaml # o elenco, construído de evidência
flows/<flow>.md # entrada, objetivo, sucesso, allowlist, limites
runs/<UTCstamp>-<flow>/ # uma árvore de entregáveis por run
<persona-id>/
JOURNEY.jsonl # um turno executado por linha, com deltas de estado
evidence/ # screenshots e gravações
FINDINGS.md # tipado: bug | ux | a11y | copy | perf + severidade
REPORT.md # síntese entre personas, versão do app pinada
Como um run funciona¶
- Preflight, barulhento: o arquivo de fluxo precisa declarar entrada, objetivo, critério de sucesso e allowlist de domínios; todo contrato passa pelo gate de auditoria do runtime; a sessão precisa conseguir de fato perceber a superfície (ferramentas de browser pra web, shell pra CLI). Sem browser → o run diz isso e para. Uma persona que nunca viu a tela não tem nada verdadeiro a dizer.
- O loop: captura o que a persona vê → executa um turno instrumentado → anexa o
resultado completo ao
JOURNEY.jsonl→ executa a ação pretendida da persona → repete, encadeando ostate_deltade cada turno no estado anterior do próximo. - O diário é a memória. Se a sessão bate na janela de contexto, a continuidade do Leopold rola a janela — e a janela seguinte retoma do rabo do diário, re-percebe a tela e continua do mesmo turno. Um fluxo longo nunca perde um passo, e tudo que é relido do diário é enquadrado como dado de run passado, nunca como instrução.
- O relatório: achados destilados só do diário (sem turno no diário, sem achado), ranqueados por severidade e por quantas personas bateram na mesma parede — "3 de 4 personas travaram no mesmo passo do checkout" vale mais que qualquer observação solitária. Abandono é dado: onde a persona desistiu costuma ser a linha mais valiosa do relatório.
Limites que não se movem¶
- A allowlist é fronteira dura — a persona nunca navega fora dos domínios que o
fluxo declara. Aponte fluxos pra staging. O ciclo de run do
/leopold-personaarma essa fronteira no preflight e desarma no fim do run, então com um run ativo ela também é imposta antes da chamada da ferramenta: um hookPreToolUsenega navegação MCP fora da allowlist em toda sessão que inicia sob o run ativo, nos dois harnesses, verificado ao vivo — a checagem do próprio condutor no loop vale sempre. Hooks do Persona Guard. - Ação irreversível nunca é executada. Pagamento, deleção, submit destrutivo: o condutor registra a intenção como achado em vez de agir — a mesma filosofia do lock de git. O run observa e prepara; um humano executa efeitos colaterais.
- Nenhum segredo em diário ou relatório. Credencial de teste vem do ambiente (o vault de secrets); texto gravado e reportado passa pela máscara de credencial.
O segundo motor: o driver¶
/leopold-persona é uma skill dizendo a uma sessão o que fazer. leopold persona
run é um harness fazendo: o driver SDK conduz os
mesmos artefatos de .leopold/persona/ de forma headless, com a profundidade do
motor de run. É o mesmo padrão de duas fases de /leopold-run
vs leopold run — um layout de artefato, dois motores sobre ele, e um teste
garante a paridade: um run iniciado na sessão e um run headless escrevem o mesmo
cabeçalho de diário e a mesma árvore de run, então quem lê o relatório nunca sabe
qual motor percorreu o fluxo.
O que o driver acrescenta é que tudo que a skill pede, o driver faz:
- O loop de condução, do driver. Uma sessão worker supervisionada por
persona. O worker percebe a tela, executa o turno pela skill de runtime
vendorizada e devolve o turno
persona-runtime-result/1.0num bloco cercado — mas quem escreve o diário é o driver, não o worker. Todo turno é validado antes de ser anexado; turno malformado é rejeitado em voz alta e re-pedido com a razão nomeada. Não existe reparo silencioso: uma linha de diário é válida ou não existe. - Supervisão, não esperança. Uma sessão que termina sem turno válido nem
desfecho declarado é continuidade de janela ou um travamento — o condutor
decide, registra o travamento com razão nomeada e limita os relançamentos,
então uma persona travada termina como uma linha honesta de
stallem vez de loop infinito. - Continuidade com prova. O diário é o único estado: o driver encadeia o
state_deltade cada turno no estado anterior do próximo e reconstrói um bloco de re-seed do rabo do diário a qualquer momento. O teste de regressão mata a janela depois do turno N e relança — a próxima linha do diário é o turno N+1, nenhum passo perdido, nenhum repetido. - Limites impostos em código. O condutor checa toda ação registrada no diário contra a allowlist de domínios do fluxo e a regra de irreversibilidade antes da ação executar. Violação anexa uma linha de parada nomeada e encerra o run daquela persona — o prompt reafirma os limites, o código os impõe. Os hooks do persona guard somam o mesmo limite antes da chamada da ferramenta, com a evidência ao vivo por harness naquela página.
- Fan-out.
--persona all --parallel Nroda o elenco em paralelo, cada persona no seu próprio subdiretório de run — sem worktree, personas escrevem artefatos, não código. - Relatório determinístico. O
REPORT.mdé sintetizado só dos diários, byte a byte estável: achados ranqueados por severidade × quantas personas bateram na mesma parede, versão do app pinada, evidência linkada, resumo de jornada por persona.leopold persona report <run-dir>re-sintetiza os mesmos bytes dos mesmos diários, a qualquer hora.
Qual motor quando¶
/leopold-persona (na sessão) |
leopold persona run (driver) |
|
|---|---|---|
| Onde roda | dentro da sua sessão Claude Code / Codex | headless, de qualquer terminal |
| Melhor pra | construir elenco e fluxos, ver uma persona ao vivo, iterar num contrato | runs do elenco inteiro, fluxos longos, runs de prova perto de CI |
| Contrato do diário | a skill segue | o driver valida e escreve |
| Travamento e janela | a continuidade da própria sessão | supervisionado: detecção de travamento, relançamentos limitados, retomada provada pelo diário |
| Limites | armados pelos guard hooks, reafirmados em prosa | impostos em código em toda ação registrada, além dos guard hooks |
| Fan-out | uma persona por vez | --persona all --parallel N |
| Saída | a mesma árvore .leopold/persona/runs/ |
a mesma árvore, mais o REPORT.md determinístico entre personas |
Regra de bolso: construa e depure na sessão; meça com o driver.
Os dois harnesses, com honestidade¶
As três skills instalam idênticas no Claude Code e no Codex CLI pelo mesmo instalador. O que difere são as ferramentas de percepção da sessão: um fluxo web precisa de controle de browser na sessão que o executa. Quando essa capacidade não existe, o run reporta e para — um run de persona que "imaginasse" a interface em silêncio seria pior que nenhum run.
leopold doctor reporta o módulo de persona por harness — skills presentes,
contratos encontrados, guard hook instalado, capacidade de browser dita com
honestidade — então uma capacidade ausente é uma linha nomeada, nunca um zero que
parece sucesso. Flags do driver e ambiente vivem em
Configuração do Driver.
Sob demanda hoje — na sessão (/leopold-persona run <flow>) ou headless
(leopold persona run <flow>, que escreve a mesma árvore de run e re-sintetiza o
relatório de qualquer run com leopold persona report <run-dir>); cadência
agendada vem numa release futura, depois de verificar ao vivo os schedulers dos
dois harnesses.
Inspirado no trabalho de personas do Daniel Mendes.