Gate
Depois que uma Submission entra, o Forma pode avaliá-la. Se passar, dispara submission.accepted para o AI do cliente começar o trabalho. O Forma não escreve código no repo deles.
O fluxo
1. Ingest grava a Submission e dispara submission.created como hoje.
2. Se o Form é feedback e o gate está ligado, avalia nesta ordem: URL do avaliador, senão a key OpenAI do Workspace, senão regras locais. Categoria é Auto classify, um recurso à parte.
3. Passou → webhooks com evento submission.accepted, corpo com evaluation + a Submission crua. Falhou → fica no Studio, não chega no destino do cliente.
Survey não entra neste fluxo. Ligar o gate num survey não dispara aceite.
OpenAI
Cole uma API key sk-… em Workspace → Configurações. O Gate chama gpt-4o-mini (ou OPENAI_MODEL no ambiente) com as instruções do Form, em ordem, e pede JSON: pass, reason, summary. Se Auto classify também estiver ligado, pede category na mesma resposta.
A categoria aparece na lista de Submissions quando Auto classify está ligado. A lista padrão é bug, feature, question, praise, spam, other — ou a que você escrever no Form.
Enquanto o Studio não tem login, quem abre o Studio alcança a key. Não use uma key de produção compartilhada.
Instruções
Uma por linha na Integração do Form. O modelo segue a sequência. Sem key e sem URL, as linhas min:N e -palavra ainda funcionam como gate local.
Gate local
Na aba Integrações do Form. Critérios, uma regra por linha:
- min:N
- Mínimo de caracteres de texto no payload. Padrão 12.
- -palavra
- Bloqueia se o texto (case-insensitive) contém a palavra.
- resto
- Vai no body do avaliador remoto; o gate local ignora.
Avaliador remoto
Opcional. O Forma POSTa e o teu serviço decide. Timeout 5 s. 2xx com pass boolean. Qualquer outro resultado vira error no Studio e não dispara aceite.
export async function POST(request: Request) {
const { submission, criteria } = await request.json();
// o teu modelo decide
return Response.json({
pass: true,
reason: "actionable",
summary: submission.payload.message,
});
}Destino do cliente
Crie um webhook com evento submission.accepted. É o mesmo POST assinado dos webhooks. O agente no cliente (Cursor, CI, bot) escuta esse URL e começa o build.
{
"event": "submission.accepted",
"evaluation": {
"pass": true,
"reason": "actionable_bug",
"summary": "O botão de salvar some no mobile.",
"category": "bug"
},
"submission": {
"id": "7e583034-1a0a-47d5-ab72-74d4541f8486",
"formId": "form_demo",
"receivedAt": 1788182240254,
"origin": "https://app.acme.com",
"userAgent": "Mozilla/5.0 …",
"payload": { "email": "ana@acme.com", "message": "…" }
}
}A mesma Submission nunca gera dois aceites: o status do gate é gravado, e cada par webhook+Submission só tem uma entrega.