{"schema":"testaai.portfolio.v1","schemaUrl":"https://testaai-site.vercel.app/portfolio.schema.json","language":"pt-BR","reviewedAt":"2026-08-22","identity":{"brand":"TestaAí","technicalName":"TestaAI","builder":"Zero","role":"Product Engineer / Full-stack Developer","positioning":"Produtos digitais construídos do problema à operação, com decisões, limites e próximos sinais documentados.","disclosure":"Zero é uma persona pública. A identidade civil permanece protegida; os dados técnicos ficam abertos à inspeção.","contact":{"status":"pending"}},"capabilities":{"layers":[{"id":"L1","name":"Interface & produto","description":"Experiências responsivas, estado complexo e fluxos que deixam o domínio visível para quem opera.","technologies":["React 19","Next.js 16","React Native","Vite","TypeScript"],"evidence":"ERP, Auto Whats, AI_VTT, NEXO, Castle Wars e Our Home"},{"id":"L2","name":"Serviços & realtime","description":"APIs, gateways e processos isolados para proteger fronteiras e manter interações sincronizadas.","technologies":["ASP.NET Core","Fastify","Node.js","Socket.IO","Supabase Realtime"],"evidence":"Renaissance, Auto Whats, Castle Wars e Our Home"},{"id":"L3","name":"Dados & estado","description":"Persistência relacional, cache, séries de eventos e regras autoritativas desenhadas por caso de uso.","technologies":["PostgreSQL","Redis","ClickHouse","Firebase","Supabase RLS"],"evidence":"sete arquiteturas com estratégias de estado diferentes"},{"id":"L4","name":"Integrações & inteligência","description":"Modelos, voz, mensageria, pagamentos e APIs externas tratados como capacidades com limites claros.","technologies":["AI agents","Baileys","Asaas","ZapSign","ProfitDLL"],"evidence":"automação, RPG generativo, fintech e operação SaaS"}],"principles":[{"id":"BOUNDARIES","name":"Fronteiras explícitas","description":"Integrações frágeis ficam nas bordas; domínio, estado e política permanecem testáveis."},{"id":"SAFE DEFAULTS","name":"Falhar com segurança","description":"Execução financeira bloqueada, handoff humano e regras autoritativas são escolhas de arquitetura."},{"id":"VERTICAL SLICES","name":"Entregar ponta a ponta","description":"Primeiro fluxo utilizável antes da plataforma completa: menor tempo entre hipótese e evidência."},{"id":"VISIBLE GAPS","name":"Lacunas documentadas","description":"O que ainda está em memória, é conceito ou depende de validação aparece sem linguagem de lançamento."}]},"projects":[{"id":"renaissance","index":"01","name":"Project Renaissance","seoTitle":"Project Renaissance: pesquisa quantitativa e execução","domain":"QUANT / FINTECH","type":"SoftwareApplication","stage":"V1 / SHADOW + PAPER","status":"safe","summary":"Sistema quantitativo em .NET 10 com ProfitDLL, ticks, backtests, estratégias e OMS/Risk. Opera em shadow; execução real exige habilitação explícita.","question":"É possível separar pesquisa, risco e execução desde o primeiro MVP?","scope":"Pesquisa quantitativa, replay, risco e execução controlada","role":"Arquitetura de domínio, backend, dados e integração nativa","capabilities":["backend","data","realtime","integrations"],"stack":[".NET 10","ASP.NET Core","PostgreSQL","ClickHouse","ProfitDLL"],"architecture":{"summary":"Pesquisa e backtest → OMS/Risk → adaptador x64 isolado → corretora, com telemetria e persistência separadas.","nodes":[{"code":"INGEST","title":"Market data","detail":"ProfitDLL x64 / ticks normalizados"},{"code":"REPLAY","title":"Research engine","detail":"Backtest e reprodução determinística"},{"code":"POLICY","title":"OMS / Risk","detail":"Gates, limites e intenção de ordem"},{"code":"EXEC","title":"Broker adapter","detail":"Shadow, paper e habilitação explícita"}],"centralDecision":"Colocar a ProfitDLL em processo próprio e manter execução real atrás de gates explícitos; shadow e paper são o padrão.","tradeoffs":[{"axis":"ISOLAMENTO","choice":"Adaptador nativo fora do núcleo","gain":"Falhas da DLL não contaminam domínio e processo principal.","cost":"Mais coordenação entre processos, health checks e reconexão."},{"axis":"DADOS","choice":"PostgreSQL + ClickHouse","gain":"Estado operacional e séries densas recebem modelos adequados.","cost":"Dois armazenamentos exigem sincronização e operação consciente."},{"axis":"SEGURANÇA","choice":"Shadow e paper por padrão","gain":"Pesquisa pode evoluir sem ganhar autoridade financeira silenciosa.","cost":"Promoção para execução real exige critérios e cerimônia explícitos."}],"executionTrace":{"trigger":"Tick normalizado recebido durante uma sessão paper.","steps":[{"code":"INGEST","action":"Valida contrato, sequência e relógio do tick.","output":"tick.accepted"},{"code":"REPLAY","action":"Executa a estratégia ativa sobre o mesmo estado reproduzível.","output":"intent.created | no_op"},{"code":"POLICY","action":"Aplica risco, idempotência e gates do modo corrente.","output":"intent.allowed | blocked"},{"code":"EXEC","action":"Registra a simulação sem autorizar efeito financeiro real.","output":"execution.simulated"}],"invariant":"Sem modo explícito e autorização de risco, nenhum adaptador produz efeito financeiro real.","terminalState":"Decisão, motivo e correlação ficam disponíveis para replay e auditoria."}},"reliability":{"failureModes":["Desconexão ou travamento do processo que hospeda a DLL nativa.","Ticks ausentes, duplicados ou fora de ordem durante ingestão e replay.","Intenção de ordem repetida depois de timeout ou reconexão."],"candidateSignals":["Replays idênticos produzem a mesma sequência de decisões.","Taxa e motivo de bloqueio nos gates do OMS/Risk.","Diferença entre sinal, preço paper e resultado de execução simulado."],"incidentDrills":[{"code":"DRILL-01","scenario":"Desconexão ou travamento do processo que hospeda a DLL nativa.","containment":"Abrir o circuit breaker, retirar autoridade do adaptador e bloquear novas intenções antes de tentar reconectar.","recovery":"Reiniciar o processo isolado, restaurar assinatura de market data e reconciliar o cursor da sessão supervisionada.","proof":"Confirmar health check estável, ausência de gap e nenhuma ordem externa sem intenção correspondente no ledger."},{"code":"DRILL-02","scenario":"Ticks ausentes, duplicados ou fora de ordem durante ingestão e replay.","containment":"Quarentenar o segmento inconsistente e impedir que a estratégia avance sobre uma sequência não confiável.","recovery":"Solicitar backfill, normalizar a ordem e refazer o trecho a partir do último checkpoint determinístico.","proof":"Comparar sequência, checksum e decisões do replay recuperado com um corte íntegro da mesma janela."},{"code":"DRILL-03","scenario":"Intenção de ordem repetida depois de timeout ou reconexão.","containment":"Manter a mesma chave idempotente e suspender a retentativa até consultar o estado conhecido do adaptador.","recovery":"Reconciliar intenção, aceite e execução antes de decidir entre concluir, cancelar ou reenviar o comando.","proof":"Demonstrar um único efeito financeiro possível e uma cadeia causal completa para cada intenção persistida."}]},"nextSignal":"Expandir replays determinísticos, critérios de promoção de estratégia e observabilidade de execução paper.","interviewAngles":["Como desenhar idempotência entre intenção de ordem e adaptador externo.","Onde separar pesquisa, política de risco e infraestrutura de corretora.","Como promover uma estratégia sem transformar backtest em promessa."],"evidence":{"kind":"documented-architecture"},"links":{"caseStudy":"https://testaai-site.vercel.app/experimentos/renaissance"}},{"id":"erp","index":"02","name":"ERP","seoTitle":"ERP para escolas e academias","domain":"OPERAÇÕES / SAAS","type":"SoftwareApplication","stage":"BASE OPERACIONAL","status":"lab","summary":"Gestão para escolas, academias e operações esportivas: alunos, matrículas, contratos e cobrança. Integra assinatura, pagamentos e WhatsApp num fluxo único.","question":"Uma operação fragmentada pode caber em um fluxo único?","scope":"Operação de alunos, matrículas, contratos, cobrança e comunicação","role":"Produto full-stack, modelagem de fluxo e integrações SaaS","capabilities":["frontend","backend","data","ai","integrations"],"stack":["React","Vite","Firebase","Asaas","ZapSign"],"architecture":{"summary":"SPA operacional → serviços Firebase → adaptadores de cobrança, assinatura e WhatsApp.","nodes":[{"code":"OPS","title":"Console operacional","detail":"React / jornadas por papel"},{"code":"DOMAIN","title":"Fluxo do negócio","detail":"Alunos, matrícula e contrato"},{"code":"ADAPTERS","title":"Serviços externos","detail":"Asaas, ZapSign e comunicação"},{"code":"AUDIT","title":"Estado e conciliação","detail":"Firebase / histórico operacional"}],"centralDecision":"Modelar o fluxo do negócio primeiro e tratar pagamentos, assinatura e comunicação como integrações substituíveis.","tradeoffs":[{"axis":"DOMÍNIO","choice":"Jornada antes do fornecedor","gain":"O produto continua legível mesmo quando uma integração muda.","cost":"Adaptadores e estados intermediários exigem modelagem adicional."},{"axis":"ENTREGA","choice":"Vertical operacional em Firebase","gain":"Autenticação, dados e interface chegam cedo ao contexto real.","cost":"Auditoria e consultas analíticas pedem limites bem definidos."},{"axis":"AUTOMAÇÃO","choice":"WhatsApp e IA como borda","gain":"Comunicação acelera sem virar fonte autoritativa do contrato.","cost":"Contexto, consentimento e handoff precisam atravessar o fluxo."}],"executionTrace":{"trigger":"Operador confirma uma nova matrícula com contrato e cobrança.","steps":[{"code":"OPS","action":"Valida campos, papel do operador e contexto da unidade.","output":"enrollment.requested"},{"code":"DOMAIN","action":"Persiste a matrícula pendente e cria intenções do fluxo.","output":"workflow.committed"},{"code":"ADAPTERS","action":"Despacha contrato e cobrança com chaves idempotentes.","output":"provider.references"},{"code":"AUDIT","action":"Reconcilia retornos e expõe pendências sem colapsar estados.","output":"operation.visible"}],"invariant":"Nenhum retorno isolado de provedor equivale sozinho à conclusão da matrícula.","terminalState":"O operador enxerga estado, pendência, referência externa e próxima ação recuperável."}},"reliability":{"failureModes":["Webhook de pagamento duplicado ou recebido fora de ordem.","Contrato assinado enquanto a cobrança permanece inconclusiva.","Permissão ampla demais revela ou altera uma operação indevida."],"candidateSignals":["Tempo e abandono entre matrícula, assinatura e primeira cobrança.","Itens presos na fila de conciliação entre provedores.","Ações administrativas recuperáveis pela trilha de auditoria."],"incidentDrills":[{"code":"DRILL-01","scenario":"Webhook de pagamento duplicado ou recebido fora de ordem.","containment":"Persistir o recibo do provedor e rejeitar qualquer transição que viole a versão atual da cobrança.","recovery":"Reprocessar eventos idempotentes pela ordem causal e consultar o provedor quando a sequência permanecer ambígua.","proof":"Conciliar valor, referência externa e estado interno sem duplicar baixa, comissão ou comunicação ao aluno."},{"code":"DRILL-02","scenario":"Contrato assinado enquanto a cobrança permanece inconclusiva.","containment":"Preservar assinatura e cobrança como estados independentes e manter a matrícula numa pendência explícita.","recovery":"Retomar somente a etapa financeira, oferecendo ao operador ação segura de cobrança, espera ou cancelamento.","proof":"Exibir a jornada composta, a próxima ação e a trilha que comprova que nenhum estado intermediário foi apagado."},{"code":"DRILL-03","scenario":"Permissão ampla demais revela ou altera uma operação indevida.","containment":"Revogar a sessão afetada, negar a ação por padrão e preservar o registro para investigação de escopo.","recovery":"Corrigir a política por papel e unidade, recalcular autorizações e exigir nova autenticação do operador.","proof":"Executar a matriz de acesso e confirmar no audit log que leitura e mutação respeitam o menor privilégio."}]},"nextSignal":"Consolidar trilha de auditoria, permissões por papel e tratamento de falhas entre provedores.","interviewAngles":["Como modelar uma saga sem esconder estados intermediários do operador.","Quando trocar conveniência de backend gerenciado por serviços próprios.","Como tornar permissões e auditoria parte da experiência, não um remendo."],"evidence":{"kind":"documented-architecture"},"links":{"caseStudy":"https://testaai-site.vercel.app/experimentos/erp"}},{"id":"castle-wars","index":"03","name":"Castle Wars","seoTitle":"Castle Wars: estratégia multiplayer em tempo real","domain":"ESTRATÉGIA / GAME","type":"VideoGame","stage":"PROTÓTIPO REALTIME","status":"lab","summary":"Estratégia multiplayer inspirada em Tribal Wars 2. O protótipo cobre autenticação, lobby, mundos, realtime e o primeiro loop de recursos e construção.","question":"Sincronização e economia inicial sustentam uma partida multiplayer divertida?","scope":"Lobby, mundos, economia inicial e construção multiplayer em tempo real","role":"Frontend, servidor autoritativo e protocolo realtime","capabilities":["frontend","backend","realtime"],"stack":["React","Node.js","Socket.IO","Firebase Auth"],"architecture":{"summary":"Cliente React → gateway Socket.IO → loop de mundo em Node.js → autenticação Firebase.","nodes":[{"code":"CLIENT","title":"World client","detail":"React / comandos e projeções"},{"code":"GATEWAY","title":"Realtime gateway","detail":"Socket.IO / salas e presença"},{"code":"LOOP","title":"World process","detail":"Recursos, fila e relógio do servidor"},{"code":"STATE","title":"Persistence boundary","detail":"Memória agora / roadmap explícito"}],"centralDecision":"Validar o loop realtime em memória, declarando a persistência como lacuna em vez de fingir uma infraestrutura pronta.","tradeoffs":[{"axis":"PROTÓTIPO","choice":"Estado em memória no primeiro loop","gain":"Valida sincronização e diversão antes de operar infraestrutura maior.","cost":"Reinício perde o mundo e limita sessões longas deliberadamente."},{"axis":"AUTORIDADE","choice":"Comando no cliente, decisão no servidor","gain":"Economia e fila de construção preservam uma fonte de verdade.","cost":"A interface precisa prever latência, rejeição e reconciliação."},{"axis":"PROTOCOLO","choice":"Eventos pequenos por sala","gain":"Atualizações ficam focadas no mundo que realmente mudou.","cost":"Versionamento e reentrada precisam reconstruir um snapshot coerente."}],"executionTrace":{"trigger":"Jogador envia um comando para iniciar uma construção.","steps":[{"code":"CLIENT","action":"Emite intenção com versão conhecida do mundo.","output":"build.requested"},{"code":"GATEWAY","action":"Autentica presença, sala e contrato do evento.","output":"command.accepted"},{"code":"LOOP","action":"Valida recurso, fila e relógio no servidor autoritativo.","output":"build.started | rejected"},{"code":"STATE","action":"Avança a versão e publica a projeção da sala.","output":"world.version + 1"}],"invariant":"Saldo, relógio e fila nunca são alterados diretamente pela projeção do cliente.","terminalState":"Todos os jogadores recebem a mesma versão ou uma rejeição com motivo explícito."}},"reliability":{"failureModes":["Cliente retorna de uma queda com projeção anterior à do servidor.","Dois comandos simultâneos disputam o mesmo recurso ou slot de fila.","Reinício do processo invalida o mundo ainda mantido em memória."],"candidateSignals":["Diferença de versão entre snapshot do cliente e estado autoritativo.","Comandos rejeitados por saldo, relógio ou conflito de fila.","Taxa de reconexão que volta ao jogo sem intervenção manual."],"incidentDrills":[{"code":"DRILL-01","scenario":"Cliente retorna de uma queda com projeção anterior à do servidor.","containment":"Bloquear novos comandos até comparar a versão local com a versão autoritativa da sala.","recovery":"Entregar snapshot atual e cursor de eventos, então reabrir a entrada somente depois do reconhecimento do cliente.","proof":"Confirmar que todos os jogadores observam o mesmo mundo e que nenhum comando foi aplicado sobre versão obsoleta."},{"code":"DRILL-02","scenario":"Dois comandos simultâneos disputam o mesmo recurso ou slot de fila.","containment":"Serializar a decisão no processo do mundo e rejeitar o comando que perdeu a comparação de versão.","recovery":"Publicar a nova projeção e um motivo de rejeição que permita ao cliente recompor a intenção sem adivinhar.","proof":"Rodar cenários concorrentes e demonstrar conservação de recursos, uma fila válida e versão monotônica."},{"code":"DRILL-03","scenario":"Reinício do processo invalida o mundo ainda mantido em memória.","containment":"Encerrar a sala como sessão de laboratório, sem fingir que o estado efêmero continua disponível.","recovery":"Criar um novo mundo e usar o incidente como gate para introduzir checkpoint antes de sessões persistentes.","proof":"Garantir que nenhum cliente retome um mundo fantasma e que o limite do protótipo fique visível no lobby."}]},"nextSignal":"Persistir o estado do mundo, introduzir reconciliação e testar conflitos de comandos simultâneos.","interviewAngles":["Como migrar do protótipo em memória para persistência sem travar o loop.","Quando enviar evento incremental e quando reconstruir um snapshot.","Como testar relógio, economia e conflitos concorrentes de forma determinística."],"evidence":{"kind":"concept","image":"https://testaai-site.vercel.app/media/castle-wars-concept.webp","alt":"Mapa medieval noturno com castelos, povoados e rotas estratégicas verdes."},"links":{"caseStudy":"https://testaai-site.vercel.app/experimentos/castle-wars"}},{"id":"auto-whats","index":"04","name":"Auto Whats","seoTitle":"Auto Whats: automação de WhatsApp com IA","domain":"AUTOMAÇÃO / IA","type":"SoftwareApplication","stage":"SAAS ONLINE","status":"live","summary":"Conecta WhatsApp por QR, organiza o CRM e usa IA do negócio para responder, qualificar leads, agendar, fazer follow-up e repassar ao humano.","question":"IA pode acelerar o atendimento sem esconder a transição humana?","scope":"Atendimento, CRM, sessão WhatsApp, automação e handoff humano","role":"Produto full-stack, orquestração de IA e operação em tempo real","capabilities":["frontend","backend","data","realtime","ai","integrations"],"stack":["Next.js","Fastify","PostgreSQL","Redis","Baileys"],"architecture":{"summary":"Console web → API Fastify → filas e estado em Redis/PostgreSQL → sessão WhatsApp via Baileys.","nodes":[{"code":"CONSOLE","title":"Operator workspace","detail":"Next.js / inbox e CRM"},{"code":"SERVICE","title":"Conversation API","detail":"Fastify / políticas e comandos"},{"code":"STATE","title":"Queues + storage","detail":"Redis / PostgreSQL"},{"code":"CHANNEL","title":"WhatsApp + AI","detail":"Baileys / modelo / handoff"}],"centralDecision":"Tratar IA como modo controlável por conversa e manter handoff humano como caminho principal do produto.","tradeoffs":[{"axis":"CONTROLE","choice":"Modo de IA por conversa","gain":"O operador pode assumir sem disputar respostas com a automação.","cost":"Toda fila precisa respeitar a mudança de autoridade imediatamente."},{"axis":"ESTADO","choice":"Redis para trânsito, Postgres para memória","gain":"Baixa latência não transforma estado efêmero em histórico definitivo.","cost":"Retentativas e reconciliação cruzam duas camadas operacionais."},{"axis":"IA","choice":"Modelo propõe; política decide","gain":"Qualificação e resposta ganham velocidade dentro de limites auditáveis.","cost":"Contexto, validação e métricas custam mais que uma chamada direta."}],"executionTrace":{"trigger":"Uma mensagem nova chega por uma sessão WhatsApp conectada.","steps":[{"code":"CHANNEL","action":"Normaliza, correlaciona e elimina reentrega conhecida.","output":"message.received"},{"code":"SERVICE","action":"Resolve dono da conversa, política e elegibilidade da IA.","output":"reply | handoff | hold"},{"code":"STATE","action":"Persiste contexto e enfileira somente o efeito ainda válido.","output":"work.scheduled"},{"code":"CONSOLE","action":"Atualiza inbox, CRM e motivo da decisão para o operador.","output":"conversation.projected"}],"invariant":"Somente o dono atual da conversa pode autorizar uma resposta de saída.","terminalState":"Mensagem, decisão, handoff e efeito compartilham uma correlação auditável."}},"reliability":{"failureModes":["Sessão do WhatsApp desconecta durante uma sequência de atendimento.","Mensagem é reenviada e gera efeito duplicado no CRM ou follow-up.","Automação responde depois que a conversa já foi entregue ao humano."],"candidateSignals":["Tempo de recuperação e estabilidade das sessões conectadas.","Motivo do handoff, correção humana e retomada do fluxo.","Mensagens duplicadas, atrasadas, bloqueadas ou sem confirmação."],"incidentDrills":[{"code":"DRILL-01","scenario":"Sessão do WhatsApp desconecta durante uma sequência de atendimento.","containment":"Marcar o canal como indisponível, limitar a fila e impedir respostas que pareçam confirmadas ao operador.","recovery":"Reautenticar a sessão, retomar a partir do último ack e reconciliar mensagens pelo identificador do canal.","proof":"Confirmar conexão estável, backlog drenado uma vez e conversa projetada na mesma ordem reconhecida."},{"code":"DRILL-02","scenario":"Mensagem é reenviada e gera efeito duplicado no CRM ou follow-up.","containment":"Deduplicar pelo identificador externo e reutilizar a chave idempotente de cada efeito derivado.","recovery":"Reconciliar recibo, mensagem e ação do CRM antes de liberar qualquer retentativa ainda sem confirmação.","proof":"Demonstrar uma mensagem lógica, um efeito no CRM e uma única confirmação mesmo com múltiplas entregas."},{"code":"DRILL-03","scenario":"Automação responde depois que a conversa já foi entregue ao humano.","containment":"Incrementar a versão de autoridade e invalidar jobs cujo dono esperado deixou de ser a IA.","recovery":"Projetar o handoff no console, manter o humano como único emissor e descartar propostas obsoletas.","proof":"Executar testes de interleaving e confirmar que nenhuma saída antiga atravessa a mudança de autoridade."}]},"nextSignal":"Ampliar métricas de qualidade, recuperação de contexto e garantias operacionais das sessões conectadas.","interviewAngles":["Como garantir que o handoff invalida trabalhos já enfileirados.","Qual contexto enviar ao modelo e qual estado nunca confiar a ele.","Como observar qualidade sem registrar conversa sensível sem limite."],"evidence":{"kind":"build-artifact","image":"https://testaai-site.vercel.app/media/autowhats-field.webp","alt":"Painel do Auto Whats com CRM, conversas demonstrativas e controle da IA global."},"links":{"caseStudy":"https://testaai-site.vercel.app/experimentos/auto-whats","publicDeployment":"https://auto-whats.vercel.app/pt"}},{"id":"ai-vtt","index":"05","name":"AI_VTT","seoTitle":"AI_VTT: mesa virtual com mestre de IA","domain":"RPG / GENERATIVE GAME","type":"VideoGame","stage":"VERTICAL SLICE","status":"lab","summary":"Mesa virtual solo ou em dupla, com lobby persistente, exploração e combate. O mestre de IA atua por texto ou voz sem controlar as regras.","question":"Uma IA consegue mestrar sem sequestrar as regras?","scope":"Mesa compartilhada, campanha persistente, regras, narração e voz","role":"Arquitetura full-stack, realtime e IA generativa com guardrails","capabilities":["frontend","backend","data","realtime","ai"],"stack":["TypeScript","PostgreSQL","Voice AI","Rules engine"],"architecture":{"summary":"Mesa compartilhada → motor de regras e estado → contexto narrativo → mestre de IA por texto ou voz.","nodes":[{"code":"TABLE","title":"Shared tabletop","detail":"Mapa, turno, dados e presença"},{"code":"RULES","title":"Authoritative engine","detail":"Ações, movimento e combate"},{"code":"MEMORY","title":"Campaign state","detail":"PostgreSQL / cursor e snapshot"},{"code":"GM.AI","title":"Narrative layer","detail":"Contexto, texto, voz e fallback"}],"centralDecision":"Separar narração probabilística de resolução determinística; a IA propõe ficção, o sistema valida ações.","tradeoffs":[{"axis":"AUTORIDADE","choice":"Regras fora do modelo","gain":"A ficção pode improvisar sem alterar dado, vida ou inventário.","cost":"A narrativa precisa traduzir rejeições do motor de forma natural."},{"axis":"CONTEXTO","choice":"Cursor + snapshot de campanha","gain":"Retomada não depende de reenviar todo o histórico da sessão.","cost":"Resumo e estado precisam evoluir sem contradizer eventos passados."},{"axis":"INTERAÇÃO","choice":"Voz com fallback textual","gain":"A mesa continua operável quando síntese, rede ou modelo atrasam.","cost":"Turnos multimodais exigem cancelamento e coordenação cuidadosos."}],"executionTrace":{"trigger":"Jogador propõe uma ação durante seu turno na mesa compartilhada.","steps":[{"code":"TABLE","action":"Captura intenção, ator, alvo e versão observada.","output":"action.proposed"},{"code":"RULES","action":"Valida turno, alcance, dado e consequência determinística.","output":"action.resolved | rejected"},{"code":"MEMORY","action":"Persiste evento e deriva o novo snapshot da campanha.","output":"campaign.advanced"},{"code":"GM.AI","action":"Narra o resultado confirmado por texto ou voz.","output":"narration.emitted"}],"invariant":"A camada narrativa nunca confirma vida, posição, inventário ou dado por conta própria.","terminalState":"Evento de regra e narração apontam para a mesma causa e versão de campanha."}},"reliability":{"failureModes":["O mestre narra uma consequência que o motor de regras não autorizou.","Jogadores reconectam com versões diferentes da campanha compartilhada.","Latência ou interrupção de voz deixa um turno sem dono claro."],"candidateSignals":["Propostas narrativas rejeitadas ou corrigidas pelo motor de regras.","Consistência entre snapshot retomado e último evento confirmado.","Latência por turno e frequência de fallback de voz para texto."],"incidentDrills":[{"code":"DRILL-01","scenario":"O mestre narra uma consequência que o motor de regras não autorizou.","containment":"Interromper a narração divergente e preservar o evento determinístico como única fonte de estado.","recovery":"Gerar uma correção ou fallback textual a partir do resultado confirmado, sem alterar vida ou inventário.","proof":"Validar que narração, evento e snapshot apontam para a mesma versão e consequência de regra."},{"code":"DRILL-02","scenario":"Jogadores reconectam com versões diferentes da campanha compartilhada.","containment":"Recusar novas propostas até cada participante reconhecer o cursor atual da campanha.","recovery":"Enviar snapshot mais eventos posteriores e reconstruir mesa, turno e presença antes de reabrir ações.","proof":"Comparar versão e hash do estado retomado entre servidor e todos os jogadores conectados."},{"code":"DRILL-03","scenario":"Latência ou interrupção de voz deixa um turno sem dono claro.","containment":"Cancelar a síntese pendente, congelar a passagem automática e exibir o resultado confirmado em texto.","recovery":"Restituir o controle ao jogador atual e iniciar uma nova narração somente com token de turno vigente.","proof":"Confirmar uma única transição de turno, nenhum áudio tardio e continuidade operável pelo fallback textual."}]},"nextSignal":"Testar retomada longa de campanha, latência de voz e consistência narrativa em sessões com dois jogadores.","interviewAngles":["Como compor contexto de campanha sem transformar histórico em autoridade.","Como sincronizar dois jogadores e um agente que também produz eventos.","Como avaliar qualidade narrativa separadamente da correção das regras."],"evidence":{"kind":"build-artifact","image":"https://testaai-site.vercel.app/media/ai-vtt-field.webp","alt":"Quatro pessoas jogam RPG num tabuleiro de fantasia com miniaturas, dados e luz teal."},"links":{"caseStudy":"https://testaai-site.vercel.app/experimentos/ai-vtt"}},{"id":"desafio-online","index":"06","name":"Desafio Online","seoTitle":"Desafio Online: quebra-cabeças em equipe","domain":"PUZZLE / SOCIAL GAME","type":"VideoGame","stage":"MVP JOGÁVEL","status":"live","summary":"Plataforma para duplas e grupos com equipes, convites e expedições persistentes. O Mapa Impossível combina pistas, dicas cronometradas e progresso compartilhado.","question":"Pistas diferentes podem virar uma competição social memorável?","scope":"Equipes, convites, pistas, dicas cronometradas e progresso compartilhado","role":"Produto full-stack, modelagem de jogo e persistência transacional","capabilities":["frontend","backend","data","integrations"],"stack":["Next.js 16","React 19","PostgreSQL","Drizzle","Firebase Auth"],"architecture":{"summary":"Interface de expedição → ações de equipe no servidor → progresso persistente em PostgreSQL → identidade Firebase.","nodes":[{"code":"EXPEDITION","title":"Team interface","detail":"Next.js / mapa e pistas"},{"code":"COMMAND","title":"Server actions","detail":"Submissão, dica e prontidão"},{"code":"PROGRESS","title":"Game state","detail":"PostgreSQL + Drizzle"},{"code":"IDENTITY","title":"Access boundary","detail":"Firebase Auth / convites"}],"centralDecision":"Deixar solução e progressão autoritativas no servidor; o navegador recebe apenas o estado necessário da etapa.","tradeoffs":[{"axis":"SEGREDO","choice":"Respostas somente no servidor","gain":"O cliente não recebe a solução antes da validação da pista.","cost":"Pré-visualização e modo offline ficam deliberadamente limitados."},{"axis":"EQUIPE","choice":"Progresso compartilhado autoritativo","gain":"Todos enxergam a mesma expedição, dica e ordem de conclusão.","cost":"Ações simultâneas precisam de idempotência e conflito explícito."},{"axis":"CONTEÚDO","choice":"Pistas como mecanismos componíveis","gain":"Uma expedição combina lógica, mídia e interação sem uma tela por jogo.","cost":"O esquema editorial precisa limitar complexidade e validar cada tipo."}],"executionTrace":{"trigger":"Integrante envia uma resposta para a pista atual da equipe.","steps":[{"code":"IDENTITY","action":"Confirma identidade, convite e vínculo com a expedição.","output":"member.authorized"},{"code":"COMMAND","action":"Normaliza a tentativa sem devolver a solução esperada.","output":"answer.checked"},{"code":"PROGRESS","action":"Grava tentativa ou avanço numa transação idempotente.","output":"progress.version + 1"},{"code":"EXPEDITION","action":"Projeta pista, timer e estado comum para a equipe.","output":"team.synchronized"}],"invariant":"Resposta correta e conteúdo futuro nunca atravessam o payload enviado ao navegador.","terminalState":"Todos os integrantes observam a mesma versão, dica e posição da expedição."}},"reliability":{"failureModes":["Duas pessoas enviam a solução correta no mesmo instante.","Relógio de dica diverge depois de suspensão ou troca de dispositivo.","Uma resposta ou pista futura aparece no payload do navegador."],"candidateSignals":["Tempo de conclusão e taxa de uso de dica por mecanismo de pista.","Conflitos idempotentes e retomadas sem regressão de progresso.","Convites aceitos, equipes prontas e expedições efetivamente iniciadas."],"incidentDrills":[{"code":"DRILL-01","scenario":"Duas pessoas enviam a solução correta no mesmo instante.","containment":"Comparar e atualizar a versão da expedição dentro da mesma transação, aceitando um único avanço.","recovery":"Responder ao segundo comando com o estado já avançado, sem tratá-lo como nova conclusão ou penalidade.","proof":"Demonstrar um evento de avanço, uma posição seguinte e ranking invariável sob repetição concorrente."},{"code":"DRILL-02","scenario":"Relógio de dica diverge depois de suspensão ou troca de dispositivo.","containment":"Ignorar relógios do cliente e calcular elegibilidade somente pela deadline persistida no servidor.","recovery":"Reenviar instante de referência, deadline e estado atual quando a equipe retomar a expedição.","proof":"Simular relógios locais diferentes e confirmar a mesma liberação de dica para toda a equipe."},{"code":"DRILL-03","scenario":"Uma resposta ou pista futura aparece no payload do navegador.","containment":"Bloquear a rota afetada e retirar imediatamente o campo secreto do contrato entregue ao cliente.","recovery":"Mover validação e resolução para o servidor, invalidar caches e gerar um novo artefato sem a solução.","proof":"Inspecionar HTML, RSC, JavaScript e rede para confirmar que conteúdo futuro não cruza a fronteira pública."}]},"nextSignal":"Instrumentar dificuldade das pistas, ranking por conclusão e ferramentas editoriais para novas expedições.","interviewAngles":["Como criar novos tipos de pista sem espalhar condicionais pelo produto.","Como definir ranking justo quando rede e ações em equipe variam.","Como testar conteúdo secreto sem deixá-lo chegar ao bundle do cliente."],"evidence":{"kind":"build-artifact","image":"https://testaai-site.vercel.app/media/nexo-field.webp","alt":"Cartaz do NEXO: à esquerda, O tesouro não está escondido. Está codificado; à direita, mapa com rota e símbolos de enigmas."},"links":{"caseStudy":"https://testaai-site.vercel.app/experimentos/desafio-online","publicDeployment":"https://nexo-desafios.vercel.app/"}},{"id":"our-home","index":"07","name":"Our Home","seoTitle":"Our Home: organização doméstica compartilhada no iPhone","domain":"MOBILE / HOUSEHOLD","type":"SoftwareApplication","stage":"MVP iOS 1.0","status":"lab","summary":"Aplicativo para iPhone em que casais e famílias compartilham compras, tarefas recorrentes e responsabilidades, com sincronização em tempo real.","question":"A rotina fica mais leve quando compras, tarefas e contexto vivem no mesmo lugar?","scope":"Compras, tarefas recorrentes, moradores e convites compartilhados no iPhone","role":"Produto mobile full-stack, modelagem relacional e segurança multi-tenant","capabilities":["frontend","backend","data","realtime","integrations"],"stack":["Expo SDK 57","React Native","TypeScript","Supabase","PostgreSQL"],"architecture":{"summary":"App React Native → comandos e canais Supabase → PostgreSQL com RLS, RPCs e triggers → projeção sincronizada por casa.","nodes":[{"code":"APP","title":"iOS client","detail":"Expo / React Native / TypeScript"},{"code":"SYNC","title":"Realtime projection","detail":"Supabase channels / refresh"},{"code":"DOMAIN","title":"Database commands","detail":"RPCs, triggers e recorrência"},{"code":"DATA","title":"Household boundary","detail":"PostgreSQL / Auth / RLS"}],"centralDecision":"Manter autorização e transições críticas junto ao banco; o app envia intenções e reconcilia a projeção via Realtime.","tradeoffs":[{"axis":"AUTORIZAÇÃO","choice":"RLS e comandos críticos junto ao banco","gain":"A fronteira por casa continua válida mesmo fora da interface mobile.","cost":"Migrações, grants, RPCs e políticas precisam evoluir e ser testados como um conjunto."},{"axis":"SINCRONIA","choice":"Evento invalida; cliente recarrega a projeção","gain":"O MVP evita reconstruir localmente cada mutação concorrente recebida.","cost":"A convergência faz leituras adicionais e depende de uma retomada bem tratada."},{"axis":"ESCOPO","choice":"Uma casa ativa na interface inicial","gain":"Criação, convite e rotina chegam ao uso antes de um seletor mais amplo.","cost":"O banco aceita várias casas, mas a navegação entre elas fica para outra etapa."}],"executionTrace":{"trigger":"Um morador marca uma tarefa recorrente como feita no iPhone.","steps":[{"code":"APP","action":"Envia a intenção com tarefa, novo status e sessão autenticada.","output":"status.requested"},{"code":"DOMAIN","action":"A RPC valida vínculo com a casa e aplica a transição.","output":"status.changed | denied"},{"code":"DATA","action":"Triggers registram autor e horário e calculam a próxima ocorrência.","output":"history.appended"},{"code":"SYNC","action":"O evento invalida a projeção e cada morador recarrega o estado da casa.","output":"household.converged"}],"invariant":"Uma sessão só lê ou altera dados de casas das quais participa; toda mudança de status preserva autoria ou origem automática.","terminalState":"Os moradores observam o mesmo status, responsável e próxima ocorrência persistida."}},"reliability":{"failureModes":["Convite e remoção do mesmo morador acontecem quase ao mesmo tempo.","Uma tarefa mensal concluída perto da virada de fuso reabre na data errada.","O aplicativo perde eventos enquanto permanece suspenso no iPhone."],"candidateSignals":["Tempo entre uma mudança e a convergência nos dispositivos da mesma casa.","Negativas de RLS e falhas por RPC, tabela e papel do morador.","Recorrências reabertas na data correta por frequência e fuso horário."],"incidentDrills":[{"code":"DRILL-01","scenario":"Convite e remoção do mesmo morador acontecem quase ao mesmo tempo.","containment":"Serializar a entrada no banco, revogar convites do removido e consultar o bloqueio antes de criar o vínculo.","recovery":"Manter a conta fora da casa e permitir somente uma decisão administrativa explícita para um futuro desbloqueio.","proof":"Repetir a corrida transacional e confirmar ausência de membership, bloqueio persistido e códigos revogados."},{"code":"DRILL-02","scenario":"Uma tarefa mensal concluída perto da virada de fuso reabre na data errada.","containment":"Preservar a ocorrência atual e interromper rollovers derivados de uma referência temporal inconsistente.","recovery":"Recalcular a próxima data no servidor a partir da regra persistida e retomar a tarefa uma única vez.","proof":"Executar casos de borda de fuso, mês e ano e conferir status, next_due_at e evento automático."},{"code":"DRILL-03","scenario":"O aplicativo perde eventos enquanto permanece suspenso no iPhone.","containment":"Não assumir que a projeção em memória continua atual depois da troca de estado do app.","recovery":"Revalidar sessão e contexto ao voltar para ativo, então recarregar membros, compras e tarefas.","proof":"Alterar a casa em outro dispositivo durante a suspensão e confirmar convergência após a retomada."}]},"nextSignal":"Validar a versão 1.0 em iPhones reais antes de avançar para notificações e calendário compartilhado.","interviewAngles":["Como desenhar RLS e RPCs para que a fronteira multi-tenant não dependa do cliente.","Quando trocar invalidação com refresh por eventos incrementais ou estado offline-first.","Como testar recorrência, concorrência de convites e retomada mobile sem depender do relógio real."],"evidence":{"kind":"build-artifact","image":"https://testaai-site.vercel.app/media/our-home-field.webp","alt":"Tela demonstrativa do Our Home no iPhone com resumo e cartões de tarefas compartilhadas da casa."},"links":{"caseStudy":"https://testaai-site.vercel.app/experimentos/our-home"}}],"writing":[{"id":"interface-impressionante-sem-spa-inteiro","title":"Como criar uma interface impressionante sem entregar um SPA inteiro","seoTitle":"Interface impressionante sem entregar um SPA inteiro","category":"Frontend","tags":["web performance","progressive enhancement","React","acessibilidade"],"readingMinutes":8,"wordCount":1622,"publishedAt":"2026-08-22T07:35:00-03:00","modifiedAt":"2026-08-22T07:35:00-03:00","url":"https://testaai-site.vercel.app/blog/interface-impressionante-sem-spa-inteiro"},{"id":"handoff-humano-em-automacoes-com-ia","title":"Handoff humano em automações com IA: autoridade antes da resposta","seoTitle":"Handoff humano em automações com IA","category":"Arquitetura","tags":["IA aplicada","system design","concorrência","WhatsApp"],"readingMinutes":7,"wordCount":1485,"publishedAt":"2026-08-22T07:15:00-03:00","modifiedAt":"2026-08-22T07:15:00-03:00","url":"https://testaai-site.vercel.app/blog/handoff-humano-em-automacoes-com-ia"},{"id":"ia-com-limites-arquitetura-antes-do-prompt","title":"IA com limites: por que a arquitetura vem antes do prompt","seoTitle":"IA com limites: arquitetura antes do prompt","category":"Engenharia de software","tags":["inteligência artificial","arquitetura de software","guardrails","system design"],"readingMinutes":6,"wordCount":1233,"publishedAt":"2026-08-22T06:55:00-03:00","modifiedAt":"2026-08-22T06:55:00-03:00","url":"https://testaai-site.vercel.app/blog/ia-com-limites-arquitetura-antes-do-prompt"},{"id":"como-validar-uma-ideia-de-software","title":"Como validar uma ideia de software antes de construir tudo","seoTitle":"Validar uma ideia de software antes de construir tudo","category":"Produto","tags":["validação de produto","software","MVP","experimentos"],"readingMinutes":5,"wordCount":943,"publishedAt":"2026-08-22T06:40:00-03:00","modifiedAt":"2026-08-22T06:40:00-03:00","url":"https://testaai-site.vercel.app/blog/como-validar-uma-ideia-de-software"},{"id":"construir-em-publico-sem-vender-certezas","title":"Construir em público sem transformar o processo em espetáculo","seoTitle":"Construir em público sem vender certezas","category":"Construção em público","tags":["build in public","produto","transparência","aprendizado"],"readingMinutes":4,"wordCount":741,"publishedAt":"2026-08-22T06:10:00-03:00","modifiedAt":"2026-08-22T06:10:00-03:00","url":"https://testaai-site.vercel.app/blog/construir-em-publico-sem-vender-certezas"}],"implementation":{"rendering":"Static pages + React Server Components","interaction":"Progressive enhancement; core content works before client JavaScript","accessibility":["Keyboard navigation","Reduced motion and slow update support","Increased contrast and forced colors support","Print-specific recruiter brief"],"privacy":{"analytics":false,"cookies":false,"remoteFonts":false,"backgroundConnections":false},"quality":{"snapshot":{"canonicalPageCount":18,"contrastPairCount":84,"interactionModuleCount":9,"ownInteractionKilobytes":25.2,"trackerCount":0,"lintWarningBudget":0,"measured":{"totalClientJavaScriptGzipKilobytes":151.3,"cssGzipKilobytes":31.2,"localFontKilobytes":32.9,"serverKilobytes":1330.9},"budgets":{"ownInteractionKilobytes":28,"totalClientJavaScriptGzipKilobytes":156,"cssGzipKilobytes":32,"localFontKilobytes":35}},"gates":[{"code":"TYPE SYSTEM","value":"STRICT","title":"TypeScript como contrato","text":"Tipos estritos, opcionais exatos e acesso indexado defensivo bloqueiam ambiguidade antes da build."},{"code":"STATIC ANALYSIS","value":"0 WARN","title":"Lint sem anistia","text":"ESLint e regras JSX/ARIA falham tanto em erro quanto em aviso; acessibilidade não fica para o fim."},{"code":"CONTRAST","value":"84 AA","title":"Leitura mensurada","text":"Os pares informativos auditados passam WCAG AA, com adaptações próprias para contraste e cores forçadas."},{"code":"PRIVACY","value":"0 TRACK","title":"Sem observador oculto","text":"Nenhum analytics, cookie, fonte remota ou conexão de fundo entra na experiência institucional."},{"code":"INTERACTION","value":"25.2 KB","title":"Complexidade com teto","text":"Nove módulos próprios ficam isolados e abaixo do orçamento de 28 KB; conteúdo útil chega antes deles."},{"code":"DISCOVERY","value":"18 URL","title":"Encontrável e legível","text":"Sitemap, JSON-LD, RSS, canonicals e JSON Schema conectam páginas, cases, escrita, autoria e contrato."}],"deliveryPipeline":[{"code":"ROUTE","title":"Contrato da página","text":"Metadados, conteúdo semântico e JSON-LD nascem junto da rota, sem depender da hidratação.","output":"RSC + HTML"},{"code":"BUILD","title":"Compilação estática","text":"Vinext e Vite resolvem páginas, estilos e módulos antes da publicação; o sanitizador inspeciona a saída.","output":"DIST / CLEAN"},{"code":"DELIVERY","title":"Payload versionado","text":"CSS, JavaScript e fonte recebem nomes imutáveis; mídia responsiva mantém cache próprio e dimensões explícitas.","output":"CACHE / HASH"},{"code":"ENHANCE","title":"Interação acoplada depois","text":"Nove ilhas pequenas adicionam busca, movimento e controles sem tomar posse do conteúdo principal.","output":"09 ISLANDS"}],"interactionModules":[{"name":"SignalField","purpose":"campo generativo em canvas","fallback":"composição visual estática"},{"name":"ParticleLogo","purpose":"marca reativa em partículas","fallback":"wordmark estático e legível"},{"name":"LabInterface","purpose":"progresso, TOC e spotlight","fallback":"âncoras e leitura linear"},{"name":"CommandPalette","purpose":"busca e salto por teclado","fallback":"navegação e links nativos"},{"name":"EngineeringConsole","purpose":"lentes técnicas em abas","fallback":"primeira lente legível"},{"name":"ProjectLens","purpose":"filtro por capacidade","fallback":"catálogo completo"},{"name":"BlueprintToggle","purpose":"inspeção visual da grade","fallback":"interface editorial padrão"},{"name":"CopyLink","purpose":"cópia contextual de URL","fallback":"URL canônica navegável"},{"name":"PrintBrief","purpose":"atalho para impressão/PDF","fallback":"impressão nativa do navegador"}],"adaptiveModes":[{"signal":"prefers-reduced-motion","response":"movimento contínuo e transições decorativas são interrompidos"},{"signal":"update: slow","response":"canvas e animações entram no mesmo caminho econômico de movimento reduzido"},{"signal":"prefers-reduced-transparency","response":"superfícies recebem fundos opacos e bordas mais explícitas"},{"signal":"prefers-contrast: more","response":"texto secundário e separadores ganham contraste adicional"},{"signal":"forced-colors: active","response":"cor de sistema substitui efeitos que não carregam informação"},{"signal":"print","response":"o briefing vira documento A4 sem navegação ou decoração desnecessária"}],"architectureDecisions":[{"id":"ADR-001","status":"ACCEPTED","title":"Rota estática, ilhas explícitas","context":"O portfólio precisava combinar narrativa longa, descoberta por busca e ferramentas interativas sem transformar cada página em uma aplicação cliente.","decision":"Pré-renderizar conteúdo e metadados em Server Components; hidratar apenas nove módulos com responsabilidades estreitas e fallbacks nomeados.","rejected":"Um SPA único simplificaria o estado global, mas faria leitura, navegação e indexação dependerem de uma fronteira cliente maior.","consequence":"A composição exige contratos entre HTML e ilhas, porém mantém conteúdo, links e estrutura úteis antes de qualquer JavaScript.","proof":"STATIC HTML / 09 ISLANDS / NO-JS FALLBACKS"},{"id":"ADR-002","status":"ACCEPTED","title":"Movimento limitado pelo ambiente","context":"Partículas e transições ajudam a comunicar laboratório e tecnologia, mas podem competir com leitura, bateria, CPU e preferências do visitante.","decision":"Usar canvas 2D determinístico com densidade e DPR limitados, pausa por visibilidade e interseção, além de modos reduzidos por preferência.","rejected":"WebGL e uma cena 3D ampliariam o espetáculo, com custo desproporcional para uma camada que não carrega informação essencial.","consequence":"O efeito é deliberadamente menos cinematográfico, mas recua de modo previsível e não altera a hierarquia nem a navegação.","proof":"BOUNDED CANVAS / DPR CAP / ADAPTIVE MOTION"},{"id":"ADR-003","status":"ACCEPTED","title":"Primitivas nativas antes do controle customizado","context":"Cases densos precisam revelar detalhes progressivamente sem esconder conteúdo de teclado, tecnologia assistiva ou ambientes sem hidratação.","decision":"Priorizar links, âncoras, tabelas, meter, details e summary; adicionar comportamento cliente somente quando a primitiva não resolve a tarefa.","rejected":"Acordeões e medidores inteiramente customizados dariam mais controle visual, mas recriariam foco, estados e semântica já disponíveis no navegador.","consequence":"Algumas nuances variam entre navegadores; em troca, o caminho básico permanece operável, reconhecível e fácil de auditar.","proof":"NATIVE DISCLOSURE / SEMANTIC METER / KEYBOARD PATH"},{"id":"ADR-004","status":"ACCEPTED","title":"Inspeção pública sem observação oculta","context":"Recrutadores, leitores e crawlers precisam verificar autoria, projetos e qualidade, enquanto um portfólio institucional não precisa vigiar comportamento.","decision":"Publicar portfolio.json, RSS, sitemap e humans.txt com contratos testados; manter analytics, cookies, fontes remotas e pixels fora da origem.","rejected":"Telemetria terceirizada responderia perguntas de audiência, mas adicionaria identidade, rede e política de dados sem melhorar a avaliação técnica.","consequence":"Não há funil comportamental automático. A evidência passa a vir do artefato, dos checks e das conversas iniciadas por quem o inspeciona.","proof":"PUBLIC CONTRACTS / 0 TRACKERS / SAME-ORIGIN CSP"}],"securityBoundaries":[{"code":"EXECUTION","title":"Origem fechada, bootstrap explícito","text":"CSP fecha arquivos na própria origem e bloqueia atributos executáveis; o bootstrap inline exigido pelo runtime permanece como custo documentado."},{"code":"EMBEDDING","title":"Superfície não enquadrável","text":"Frame ancestors, frame source e X-Frame-Options impedem uso silencioso da interface em terceiros."},{"code":"CAPABILITIES","title":"Permissões negadas por padrão","text":"Câmera, microfone, geolocalização, pagamento, USB e browsing topics permanecem desativados."},{"code":"PRIVACY","title":"Nenhuma observação oculta","text":"Sem cookies, analytics, fontes remotas, pixels ou conexões de fundo no portfólio institucional."}],"verificationPipeline":[{"index":"01","title":"Contrato","commands":"schema / content / SEO / docs","result":"instância, dados e descoberta sincronizados"},{"index":"02","title":"Estática","commands":"TypeScript / ESLint / contraste","result":"zero erro e zero aviso"},{"index":"03","title":"Mídia","commands":"fidelidade / hashes / rollback","result":"derivados íntegros e recuperáveis"},{"index":"04","title":"Build","commands":"Vinext / sanitizer / budgets","result":"artefato limpo e dentro do teto"},{"index":"05","title":"Runtime","commands":"HTTP / semântica / headers","result":"rotas e políticas verificadas"},{"index":"06","title":"Borda","commands":"links públicos / audit npm","result":"dependências e portas conferidas"}],"buildHistory":[{"cut":"CUT. 01","date":"2026-08-21","title":"A marca virou interface","text":"Paleta, Sora, frasco e linguagem de laboratório ganharam uma composição editorial responsiva.","proof":"TOKENS / ICONS / STATIC ROUTES"},{"cut":"CUT. 02","date":"2026-08-21","title":"O manifesto virou sistema","text":"Home, Experimentos e Zero foram separados; blog, sitemap, RSS e dados estruturados abriram descoberta.","proof":"MULTI-PAGE / SEO / WRITING"},{"cut":"CUT. 03","date":"2026-08-22","title":"A vitrine virou evidência","text":"Cases ganharam mapas, trade-offs, traces, falhas e briefing imprimível para leitura de recrutador.","proof":"07 CASES / BRIEF / COMMANDS"},{"cut":"CUT. 04","date":"2026-08-22","title":"A evidência ganhou contrato","text":"Budgets reais, incident drills, superfícies legíveis por máquina e o próprio build ficaram inspecionáveis.","proof":"QUALITY / RESILIENCE / JSON"}],"dossier":"https://testaai-site.vercel.app/engenharia"}},"editorialNotice":"Stack and functional scope were checked against available sources. Impact metrics, hypotheses, stages and candidate signals remain editorial until replaced by measured evidence.","links":{"canonical":"https://testaai-site.vercel.app","recruiterBrief":"https://testaai-site.vercel.app/briefing","engineeringDossier":"https://testaai-site.vercel.app/engenharia","experiments":"https://testaai-site.vercel.app/experimentos","profile":"https://testaai-site.vercel.app/zero","blog":"https://testaai-site.vercel.app/blog","rss":"https://testaai-site.vercel.app/feed.xml","humans":"https://testaai-site.vercel.app/humans.txt","llms":"https://testaai-site.vercel.app/llms.txt","portfolioSchema":"https://testaai-site.vercel.app/portfolio.schema.json"}}