# Luis Junior > Luis Junior é desenvolvedor e empreendedor brasileiro que constrói produtos com inteligência artificial, como o estúdio de sites Pagenello e os apps ClipLeve e Garfim. Luis Junior constrói produtos com inteligência artificial, da ideia à loja, e escreve sobre as decisões de tecnologia e negócios no caminho. São mais de 20 anos transformando ideias em sistemas, operações e negócios. - Atuação: Desenvolvedor e empreendedor. Constrói produtos digitais próprios com inteligência artificial, do conceito ao lançamento. - Reconhecimentos: Finalista da 9ª edição do Prêmio Mario Covas (2013), na categoria Inovação em Gestão Municipal; Reconhecimento da OpenAI pelo uso de mais de 10 bilhões de tokens. - Contato: eu@luisjunior.ai (convites, imprensa e parcerias). - Idioma do site: português do Brasil. ## Produtos - [Pagenello](https://pagenello.com/): Estúdio de sites. Sites de uma página com a cara do negócio. Meu estúdio de sites para pequenos negócios. O cliente vê o topo do próprio site antes de pagar qualquer coisa, e eu cuido do design ao lançamento. - [ClipLeve](https://apps.apple.com/br/app/clipleve-comprimir-v%C3%ADdeos/id6821932730): App para iPhone. Vídeos mais leves, sem arriscar os originais. Cria uma versão menor do vídeo no próprio iPhone, compara antes de salvar e confere a cópia. O original só sai com a sua confirmação. - [Garfim](https://play.google.com/store/apps/details?id=br.com.garfim): App para Android e iPhone. Calorias e macros por foto, com comida de verdade. Fotografe a refeição, confira a estimativa da IA e ajuste as porções em medidas caseiras. A decisão continua com quem usa. ## Lançamentos - 27 de setembro de 2026: Garfim, primeiro capítulo da construção. https://luisjunior.ai/blog/da-ideia-ao-produto-na-era-da-ia - 3 de outubro de 2026: Pagenello, estúdio de sites aberto. https://luisjunior.ai/blog/pagenello-sites-para-pequenos-negocios - 16 de outubro de 2026: Garfim, aprovado na app store. https://luisjunior.ai/blog/garfim-aprovado-lancado-app-store - 20 de outubro de 2026: ClipLeve, lançado na app store. https://luisjunior.ai/blog/clipleve-aprovado-lancado-app-store - 22 de outubro de 2026: Garfim, chegou ao google play. https://luisjunior.ai/blog/garfim-lancado-google-play ## Textos - [Teste local verde até no S23, e o staging ainda achou um defeito.](https://luisjunior.ai/blog/garfim-teste-local-nao-valida): Como validei o Garfim em staging com serviços reais e aparelhos de verdade, achei um defeito antigo e preparei o envio da versão 0.1.4 às lojas. - [Outra IA revisou 4.170 traduções da IA em inglês e corrigiu 307.](https://luisjunior.ai/blog/traducoes-revisadas-contra-portugues): Como fechei 4.170 revisões em inglês e 4.136 em espanhol no Currículo para Vaga, com português como base, glossário fixo e build barrando falta e variável. - [A conta live do Stripe estava ativa, mas falhou na minha conferência.](https://luisjunior.ai/blog/stripe-conferido-antes-de-vender): O roteiro de conferência da conta live do Stripe no Currículo para Vaga: chaves restritas, versão dos webhooks, e-mails, Radar e retomada de entrega. - [Três regras de HSTS num só domínio: por que deixei o preload de fora.](https://luisjunior.ai/blog/hsts-sem-preload): Como resolvi a divergência entre borda, repositório e SRS no Currículo para Vaga e por que uso 6 meses de HSTS sem preload nas zonas da conta. - [Uma palavra a menos derrubou 13 páginas que já estavam no ar.](https://luisjunior.ai/blog/paginas-sumiram-do-google-portao): Como um portão do build tirou 13 páginas do Currículo para Vaga quando a nota caiu de 100 para 98, e os dados da primeira semana de busca e robôs de IA. - [Outro agente de IA revisou meu código 71 vezes e criou dois defeitos.](https://luisjunior.ai/blog/ia-revisou-meu-codigo-71-vezes): O que 71 rodadas de revisão por IA e 448 commits mudaram no Currículo para Vaga, os dois defeitos que entraram e o roteiro de auditoria que ficou. - [Depois de 20 anos de carreira, publiquei meu primeiro pacote no npm.](https://luisjunior.ai/blog/primeiro-pacote-npm-cli): Como coloquei a CLI do Currículo para Vaga no npm com GitHub Actions, teste no Node 22.13, empacotamento em monorepo e a correção do ./ no npm publish. - [Sozinho com IA: iPhone, Android, SaaS com MCP e CLI, e já faturando.](https://luisjunior.ai/blog/um-dev-com-ia-apps-saas-mcp-cli): Um app nativo em Swift, um app iOS e Android em React Native, um SaaS com API, CLI e MCP e um desktop a caminho, feitos por um dev só com IA. - [Copiei a mecânica dos líderes e recusei a mentira deles.](https://luisjunior.ai/blog/anuncio-copiar-mecanica-recusar-mentira): Garimpei anúncios, funis e avaliações da categoria para separar a mecânica que funciona da mentira que vende. Seis conceitos saíram dessa leitura. - [A pergunta de LGPD que trava a venda: e o backup?](https://luisjunior.ai/blog/lgpd-perguntas-de-produto): A pergunta que trava vendas é o destino do dado no backup. Veja as respostas sobre retenção, restauração e exclusão em até 90 dias que adotei. - [A IA calibrou minha câmera pelos números. Ficou cara de lanterna.](https://luisjunior.ai/blog/estudio-calibrar-camera-a-olho): A IA calibrou a Logitech Brio pelos números e a cena parecia uma lanterna no escuro. Veja como ajustei OBS, luz e foco manual comparando quadros. - [Um usuário não via o dia de ontem. Abri todo o passado do Garfim.](https://luisjunior.ai/blog/garfim-historico-dias-passados): A decisão de liberar a edição de qualquer dia passado no Garfim, sem limite de tempo e sem cobrar pelo que não consome IA. Veja as regras definidas. - [62% baixavam o Garfim. O problema estava antes da página.](https://luisjunior.ai/blog/garfim-ficha-das-lojas): Cerca de 62% de quem via a página baixava o Garfim, mas a busca não trazia visitas. Veja como mudei palavras-chave, capturas e textos nas lojas. - [O idioma certo na tela pode virar o errado no servidor.](https://luisjunior.ai/blog/padrao-de-idiomas-paraglide): Veja como organizo URLs e mensagens com Paraglide JS e guardo o idioma escolhido para respostas e comunicações posteriores. - [O limite de 10 por minuto que deixou passar muito mais.](https://luisjunior.ai/blog/rate-limit-cloudflare-aproximado): Entenda quando o Rate Limiting dos Workers é aproximado e como testei em produção um contador exato com rajadas em IPv4 e IPv6. - [Um PR do Dependabot travou meu banco e as rotas voltaram 500.](https://luisjunior.ai/blog/dependabot-postgres-4-hyperdrive): Veja como identifiquei conexões presas atrás do Hyperdrive e provei a correção antes de liberar uma atualização do driver. - [Meus produtos novos não começam do zero. Começam de um clone.](https://luisjunior.ai/blog/base-de-produto-clone): Uma base privada marcada como template traz site, app, conta, pagamentos e IA prontos. Cada produto clona, renomeia e apaga o que não usa. - [Tirei uma trava da minha IA e a resposta caiu de 5,5 s para 3,7 s.](https://luisjunior.ai/blog/openrouter-velocidade-primeiro): Veja como comparar provedores no OpenRouter e configurar o roteamento por throughput sem restringir a escolha de endpoints. - [Troquei velocidade por uma auditora que confere cada frase.](https://luisjunior.ai/blog/ia-auditora-confere-cada-frase): Dois recursos que escrevem em nome do usuário ganharam agente, guarda em código e auditora frase a frase. O acerto subiu e a espera também. - [Escrevi o método CERNE lendo seis especificações reais.](https://luisjunior.ai/blog/metodo-cerne-srs-com-ia): Como seis especificações reais viraram o método CERNE para escrever um SRS completo com IA, sem deixar dúvida para quem implementa. - [Como anunciar na Meta e vender online no CPF sem abrir empresa.](https://luisjunior.ai/blog/anunciar-e-vender-no-cpf): Descubra as regras oficiais para anunciar na Meta e vender produtos digitais como pessoa física no Brasil, evitando que a burocracia atrase o lançamento. - [Pausei anúncios depois de ignorar o resultado anterior.](https://luisjunior.ai/blog/pausar-canal-de-anuncio): Por que pausei um canal do Pagenello e como passei a avaliar intenção, histórico e sinais de tráfego antes de manter um canal pago. - [Como depurei um erro de API sem log no registro do Garfim.](https://luisjunior.ai/blog/garfim-voz-texto-erro-sem-log): O caso da API que falhava silenciosamente em voz e texto enquanto a foto funcionava, a mudança súbita no provedor e a lição de nunca esconder a causa no log. - [Como forçar atualização no React Native antes de um defeito grave.](https://luisjunior.ai/blog/garfim-bloquear-versao-antiga): Como o Garfim usa uma versão mínima para pedir atualização pela loja e evita bloqueios quando falta conexão ou versão conhecida. - [Como levei o LCP do ClipLeve de 9,9 s para menos de 1,5 s.](https://luisjunior.ai/blog/clipleve-site-novo-lighthouse): O diagnóstico do PNG pesado no topo, a migração para Astro em Workers e a reconstrução do site com 100 de pontuação e calculadoras úteis. - [Publiquei 650 páginas contra a regra do meu método.](https://luisjunior.ai/blog/laboratorio-busca-650-paginas): Como publiquei cerca de 650 páginas do Pagenello de uma vez, o que o build encontrou e quando vou medir a indexação delas. - [Uma conta para organizar erros, métricas e IA dos meus produtos.](https://luisjunior.ai/blog/sentry-posthog-openrouter-uma-conta): O padrão para gerenciar erros, métricas de produto e chaves de inteligência artificial em múltiplos projetos usando uma única conta central e regras claras. - [Separei o painel do site e pus o Access na porta.](https://luisjunior.ai/blog/painel-administrativo-cloudflare-access): Um script injetado no site público alcançava o painel pela sessão do operador. Separei o painel em app e endereço próprios, atrás do Access. - [Uma lista de 69 itens encontrou requisitos só no papel.](https://luisjunior.ai/blog/padrao-entre-produtos-69-itens): Como uso estados, evidências e divergências registradas para alinhar 69 itens entre produtos sem apagar o que cada um exige. - [O antispam esperou tanto que parou o formulário.](https://luisjunior.ai/blog/turnstile-barrando-visitante): Como defini o que bloquear quando o Turnstile falha, o que deixar passar e o que registrar para manter a captura disponível. - [Cortei a publicação de 17 minutos para 4 na minha máquina.](https://luisjunior.ai/blog/publicar-da-minha-maquina-ci-cd): Como medi o gargalo do build, passei a publicar da minha máquina com gate e ship e mantive uma rede curta no GitHub Actions. - [Eu gravo. A IA corta, legenda e entrega o vídeo curto.](https://luisjunior.ai/blog/edicao-de-video-com-ia): Eu gravo uma vez e a IA corta pausas, acerta legendas e normaliza a voz com regras fixas. Veja o passo a passo que uso nos vídeos curtos. - [Como criar anúncios UGC com IA usando o método PROVA.](https://luisjunior.ai/blog/metodo-prova-ugc-por-ia): As cinco batidas do método PROVA, o teste do corte e os dados que favorecem demonstrar o produto em anúncios curtos com IA. - [A IA disse que usou as skills. A página provou o contrário.](https://luisjunior.ai/blog/ia-disse-que-usou-as-skills): A IA afirmou que aplicou as skills e entregou uma página reprovada. Aprenda a conferir o que foi aberto, executado e deixado de fora. - [Nove páginas reprovadas antes de encontrar uma identidade.](https://luisjunior.ai/blog/metodo-mundo-site-com-identidade): Como usei uma régua, regras e arte própria para criar uma identidade de site com IA e o que a medição ainda não consegue provar. - [Em 48 horas, juntei domínios, e‑mail, sites e medição num padrão só.](https://luisjunior.ai/blog/arrumando-a-casa-48-horas): Por que juntei domínios, e-mail, sites, busca e medição de todos os meus produtos num padrão só, e a regra que guiou cada escolha. - [Por que tirei os três sites do GPT Sites.](https://luisjunior.ai/blog/por-que-sai-do-gpt-sites): O GPT Sites colocou meus três sites no ar, mas não dava HSTS na raiz, código no repositório nem controle sobre o que cada página carrega. - [Como troquei o luisjunior.ai com cerca de 10 segundos fora do ar.](https://luisjunior.ai/blog/migrar-site-astro-cloudflare-workers): O roteiro para levar três sites no ar para Astro em Workers da Cloudflare sem mudar URLs: o inventário, a ordem da troca e a conferência depois. - [Refiz o luisjunior.ai do zero: cada afirmação com prova.](https://luisjunior.ai/blog/novo-luisjunior-ai): Como o site novo do luisjunior.ai ganhou prova para cada afirmação, por que a grade de tokens saiu e quais números medidos ele entregou. - [Um padrão para todos os domínios, inclusive os de produtos futuros.](https://luisjunior.ai/blog/padrao-de-dominios-cloudflare): Os oito pontos do padrão de domínio que defini, como os domínios estavam, o que apliquei em 29 e 30 de outubro e o que ficou pendente. - [Todo o e‑mail dos meus domínios saiu do VPS num só dia.](https://luisjunior.ai/blog/email-dos-produtos-na-cloudflare): Como levei as caixas de todos os meus domínios do VPS para a Cloudflare, com Email Routing, Email Sending e um webmail que atende a todos. - [Decidi mover o envio do Garfim do Resend para a Cloudflare.](https://luisjunior.ai/blog/resend-para-cloudflare-email-sending): O Garfim ainda envia pelo Resend. Explico por que vou mover esse envio para o Cloudflare Email Sending, o que se perde e o que falta resolver. - [O método FONTE para aparecer no Google e nas respostas de IA.](https://luisjunior.ai/blog/seo-aeo-geo-metodo-fonte): SEO, AEO e GEO explicados, os números de 2026 sobre AI Overviews e citações, a escada de visibilidade e as cinco camadas do método FONTE. - [Três sites, três decisões de busca, e uma delas é não gerar páginas.](https://luisjunior.ai/blog/seo-aeo-geo-na-pratica): Na primeira rodada do método FONTE, cada um dos meus três sites recebeu uma decisão de busca. No site pessoal, a decisão foi não gerar páginas em escala. - [Medição de vários sites num painel só, com consentimento.](https://luisjunior.ai/blog/google-analytics-varios-sites-um-painel): Como medi todos os sites dos meus produtos no mesmo GA4, com consentimento, e juntei os dados num painel só. Também conto o site que não coletava visitas. - [Como a IA me apresenta mídias para aprovação](https://luisjunior.ai/blog/como-a-ia-me-apresenta-midias-para-aprovacao): Nos bastidores do Garfim: uma galeria com 13 peças, filtros por loja e imagens ampliáveis transforma a entrega da IA em algo que posso revisar e aprovar. - [O Garfim chegou ao Google Play. Agora tem Android e iPhone.](https://luisjunior.ai/blog/garfim-lancado-google-play): O Garfim está disponível para Android. Depois dos testes e da espera, os links de download, o que dá para fazer no app e os aprendizados de chegar às duas lojas. - [Conseguir testadores e esperar 14 dias: a reta final do Garfim no Android.](https://luisjunior.ai/blog/garfim-testadores-14-dias-antes-do-lancamento): Reunir pessoas para testar o Garfim foi uma das partes difíceis do lançamento. O que aprendi sobre convites, tempo, responsabilidade e a espera pelo Google Play. - [O ClipLeve chegou à App Store. O que aprendi até aqui.](https://luisjunior.ai/blog/clipleve-aprovado-lancado-app-store): Meu aplicativo para deixar vídeos mais leves no iPhone foi lançado. As decisões sobre imagem, originais, compras e acessibilidade que deram trabalho e mudaram minha forma de construir produtos. - [O ClipLeve foi rejeitado de novo. Dessa vez, por uma palavra.](https://luisjunior.ai/blog/clipleve-nova-rejeicao-subtitulo-app-store): Depois de gravar a demonstração no iPhone e responder à Apple, um termo no subtítulo em inglês trouxe outra negativa. O que esse percurso me ensinou sobre preparar um produto para a loja. - [O Garfim foi aprovado. E já está na App Store.](https://luisjunior.ai/blog/garfim-aprovado-lancado-app-store): Depois das revisões, dos testes e do reenvio, o Garfim chegou ao iPhone. O que está disponível no lançamento e o trabalho que começa com as primeiras pessoas usando. - [A última negativa do Garfim: câmera, assinatura e o caminho inteiro.](https://luisjunior.ai/blog/garfim-ultima-negativa-camera-assinaturas): A Apple apontou dois problemas na revisão de 15 de outubro. O que precisei conferir entre explicar uma permissão, carregar os planos e recuperar uma compra. - [ClipLeve: o cuidado por trás de um vídeo mais leve.](https://luisjunior.ai/blog/clipleve-videos-mais-leves-no-iphone): Qualidade da imagem, segurança do original e navegação com VoiceOver: as decisões que estão dando forma ao meu aplicativo para iPhone. - [Por que restaurar uma assinatura pode falhar em outra conta.](https://luisjunior.ai/blog/garfim-assinaturas-iphone-testflight): Uma assinatura ativa pode parecer perdida quando a compra pertence a outra conta do aplicativo. O que esse caso me fez ajustar no Garfim. - [Quando um aplicativo pode dizer que sua conta foi excluída?](https://luisjunior.ai/blog/garfim-confirmacao-exclusao-conta): Receber um pedido de exclusão e concluir a remoção são etapas diferentes. Como organizei a confirmação do Garfim para respeitar essa diferença. - [O que a primeira negativa da App Store me fez explicar.](https://luisjunior.ai/blog/garfim-primeira-negativa-app-store): A Apple pediu uma demonstração do Garfim e mais informações. Preparar a resposta exige olhar o produto com os olhos de quem acaba de chegar. - [O que quero aprender com o teste fechado do Garfim.](https://luisjunior.ai/blog/garfim-testadores-teste-fechado-google-play): Ter participantes inscritos ainda não mostra se o aplicativo cabe na rotina. Como observo dificuldades de uso no teste fechado do Garfim. - [O trabalho de uma assinatura continua depois da compra.](https://luisjunior.ai/blog/garfim-assinaturas-google-play): Cancelamento, restauração e avisos atrasados: as decisões por trás da integração direta do Garfim com o Google Play. - [Por que o Garfim ganhou um plano gratuito.](https://luisjunior.ai/blog/garfim-plano-gratuito): Um diário alimentar precisa caber na rotina antes de pedir uma assinatura. Como essa escolha mudou a entrada, os limites e a continuidade do Garfim. - [O login funcionou. Por que a tela do Garfim não saiu do lugar?](https://luisjunior.ai/blog/garfim-testes-internos-android): Um teste no Android mostrou a distância entre uma sessão criada e uma pessoa que consegue entrar. O que esse episódio mudou na forma de conferir o aplicativo. - [Pagenello: um site começa pelo que o visitante veio fazer.](https://luisjunior.ai/blog/pagenello-sites-para-pequenos-negocios): Cardápio, endereço, trabalhos ou orçamento: como a intenção de quem visita orienta os sites que estou construindo para pequenos negócios. - [Como uma foto do almoço vira um produto.](https://luisjunior.ai/blog/da-ideia-ao-produto-na-era-da-ia): Porções, comida brasileira e espaço para corrigir a IA: as decisões que dão forma ao Garfim antes de escrever a primeira tela. - [As decisões que continuo tomando ao desenvolver com IA.](https://luisjunior.ai/blog/desenvolver-com-ia-alem-do-codigo): De onde vêm os números, quanto custa cada uso e como lidar com falhas: o que preciso resolver para transformar código em um aplicativo útil. - [Apresentar o Garfim ao público também é um teste do produto.](https://luisjunior.ai/blog/garfim-preparando-o-lancamento): A página de lançamento coloca uma pergunta à prova: alguém que nunca viu o aplicativo consegue entender o que ele faz e o que esperar dele? ## Páginas - [Início](https://luisjunior.ai/): Quem é Luis Junior, produtos, lançamentos, reconhecimentos e contato. - [Sobre](https://luisjunior.ai/sobre): Bio para citar, fatos com data, produtos, fotos para imprensa e canais. - [Bastidores](https://luisjunior.ai/blog): Todos os textos, com as séries Construindo o Garfim, Construindo o ClipLeve, Arrumando a casa, Como trabalho com IA, Laboratório de busca e Vender pelo anúncio. - [Versão completa](https://luisjunior.ai/llms-full.txt): Todos os textos na íntegra, em um só arquivo. - [Privacidade](https://luisjunior.ai/privacidade) e [Termos de uso](https://luisjunior.ai/termos). ## Redes - [YouTube](https://www.youtube.com/@LuisJunior): @LuisJunior - [Instagram](https://www.instagram.com/luisjuniorj/): @luisjuniorj - [LinkedIn](https://www.linkedin.com/in/luisjuniorj/): /in/luisjuniorj - [TikTok](https://www.tiktok.com/@luisjuniorjj): @luisjuniorjj - [X](https://x.com/luisjuniorj): @luisjuniorj - [Facebook](https://www.facebook.com/luisjuniorj/): @luisjuniorj --- # Textos na íntegra ## Teste local verde até no S23, e o staging ainda achou um defeito. URL: https://luisjunior.ai/blog/garfim-teste-local-nao-valida Publicado em 8 de novembro de 2026 · Desenvolvimento · Construindo o Garfim, parte 20 Como validei o Garfim em staging com serviços reais e aparelhos de verdade, achei um defeito antigo e preparei o envio da versão 0.1.4 às lojas. O histórico do Garfim passou nos testes locais no emulador Android, no Galaxy S23, no simulador do iPhone e no iPhone 17 Pro Max, e mesmo assim travei a entrega com uma frase: "não vejo sentido de testar local e não testar staging". Isso aconteceu em 7 de novembro, no teste do recurso de ver e editar qualquer dia passado. ## O teste local ajuda no desenvolvimento e a validação acontece em staging Virou regra dos produtos: o teste local ajuda enquanto se desenvolve, mas a validação de fluxos, aparelhos e integrações de IA, fotos, e-mail e pagamentos é feita em staging, com os serviços reais de staging, antes de produção. Num app, isso quer dizer rodar um build apontado para a API de staging. Teste local verde dá falsa segurança quando os serviços reais ficam de fora da bateria. A versão 0.1.4 foi a primeira a seguir a ordem de publicação com aceite em staging. ## A 0.1.4 precisou provar nove fluxos apontada para staging Em 8 de novembro, builds de release apontados para staging passaram nos nove fluxos do Maestro no simulador do iPhone e no emulador Android. Nesse aceite, uma foto da galeria foi analisada pela IA real e a miniatura voltou do armazenamento depois de reabrir o app. Os fluxos do Maestro precisaram de ajustes para passar nos aparelhos: fechar o aviso de desenvolvimento do Expo Router, centralizar o botão de consentimento e tocar o "Voltar" do app longe da tecla de voltar do sistema da Samsung. Também entraram rolar até o conteúdo que uma fonte maior do sistema empurra para baixo e esconder o teclado da Samsung só no Android. ## O iPhone e o Galaxy S23 mostraram a diferença do aparelho real No iPhone, um build de release apontado para staging e instalado pelo cabo cobriu o onboarding com "Guardar fotos" ligado, uma foto real da câmera analisada pela IA e o salvamento. Ao reabrir o app, a miniatura foi lida de novo. No Galaxy S23, um build de teste interno do projeto de staging, instalado pelo Google Play, passou nos fluxos de histórico, registro por busca, plano gratuito e voz e água. À mão, conferi um dia passado aberto pela faixa da semana, o seletor de fotos do sistema, uma foto real da câmera com análise e salvamento, o app forçado a fechar e a miniatura de volta ao reabrir. ## O staging achou um defeito antigo do plano gratuito O teste em staging achou um defeito antigo, que não veio desta versão, quando a tela do Galaxy S23 apagou 30 segundos depois do início da análise de uma foto. Se a conexão cai durante a análise, o servidor termina o trabalho e conta o registro do dia do plano gratuito, mas o app mostra erro e não recupera o rascunho. Quem está no plano gratuito perde a análise do dia nesse caso. A correção ficou para depois, separada da 0.1.4. ## A publicação saiu com freio nas duas lojas Depois do aceite, o backend e a infraestrutura foram para produção, com uma única mudança na infraestrutura: as fotos das refeições deixaram de expirar depois de 30 dias. Nas 24 horas seguintes, o Sentry não teve nenhum evento das versões anteriores do app contra o backend novo. Os builds 0.1.4 passaram no teste interno da Play e no TestFlight com a minha conta, em produção, e nenhum registro de teste ficou nela. Autorizei o envio da versão às duas lojas em 8 de novembro: no Google Play, lançamento gradual em 20% em todos os países; na App Store, liberação manual e em fases, esperando revisão. Quem publica um app pode copiar a ordem: desenvolva com teste local, valide apontado para staging nos aparelhos de verdade e publique com freio nas lojas. O recurso que puxou essa entrega está em [o histórico dos dias passados](/blog/garfim-historico-dias-passados) e a base de testes no celular aparece em [os testes internos no Android](/blog/garfim-testes-internos-android). --- ## Outra IA revisou 4.170 traduções da IA em inglês e corrigiu 307. URL: https://luisjunior.ai/blog/traducoes-revisadas-contra-portugues Publicado em 8 de novembro de 2026 · Inteligência artificial · Construindo o Currículo para Vaga, parte 3 Como fechei 4.170 revisões em inglês e 4.136 em espanhol no Currículo para Vaga, com português como base, glossário fixo e build barrando falta e variável. Tradução por IA sai rápido, mas conferir a fila do Currículo para Vaga contra o português corrigiu 307 mensagens em inglês e 65 em espanhol em 8 de novembro. Antes dessa data, a lista acumulava 4.170 mensagens em inglês e 4.136 em espanhol esperando revisão. ## O português sustenta a interface nos três idiomas O Currículo para Vaga tem a interface em português do Brasil, inglês e espanhol, com Paraglide JS 2. O português é a base e reúne 4.398 mensagens. Sem revisão contra essa base, a tradução feita por IA promete o que o produto não faz e troca a palavra que o cliente procura. Em 4.398 mensagens, o português define o limite do que cada tela pode dizer nos outros dois idiomas. ## A lista de revisão fica visível para o build Um script preenche com IA as mensagens que faltam em inglês e espanhol e coloca cada uma numa lista de revisão, o arquivo `review.json`. Assim cada tradução nova entra marcada como pendente até passar pela conferência. A verificação do build falha quando falta uma mensagem em um idioma. Ela também falha quando a tradução perde uma variável que o português tem. ## Seis revisões fecharam a lista contra o português Em 8 de novembro, outro agente de IA, em esforço muito alto, fez seis revisões, uma por grupo de módulos. A conferência comparou cada mensagem com o português em sentido, variáveis, tom e um glossário único, sem aceitar nenhuma promessa que o português não faz. O glossário fixou antes da revisão, em inglês, os termos resume, job posting, ATS score e tailoring. Em espanhol, fixou currículum, vacante, puntuación ATS e ajuste, para o cliente encontrar a palavra que procura. As seis passagens corrigiram 307 mensagens em inglês e 65 em espanhol e deixaram a lista de revisão vazia. O método cabe em quatro regras: uma lista do que falta revisar que o build enxerga, glossário antes da revisão, revisão por módulo e nenhuma promessa a mais. ## A mensagem para recrutamento passou a seguir o currículo No mesmo dia, o recurso que escreve a mensagem que vai para quem recruta passou a escrever no idioma do currículo usado na candidatura, como já fazia a carta de apresentação. A avaliação desse recurso passou em 15 de 17 casos, incluindo o caso em inglês. Interface traduzida e mensagem para quem recruta seguem a mesma trava: o idioma muda, mas o texto continua preso à fonte que deu origem a ele. A organização dos idiomas está em [o padrão de idiomas com Paraglide](/blog/padrao-de-idiomas-paraglide) e o desenho desse recurso aparece em [a auditora que confere cada frase](/blog/ia-auditora-confere-cada-frase). --- ## A conta live do Stripe estava ativa, mas falhou na minha conferência. URL: https://luisjunior.ai/blog/stripe-conferido-antes-de-vender Publicado em 8 de novembro de 2026 · Lançamento · Construindo o Currículo para Vaga, parte 2 O roteiro de conferência da conta live do Stripe no Currículo para Vaga: chaves restritas, versão dos webhooks, e-mails, Radar e retomada de entrega. Ter cobranças, repasses diários, PIX e cartão ligados no painel do Stripe não quer dizer que a conta live está pronta para vender. O modo de teste valida o fluxo de desenvolvimento, mas não garante versão de webhook, chaves restritas nem ajustes manuais do painel real. O Currículo para Vaga cobra pelo Stripe, com PIX e cartão, e vende no meu CPF. Com a conta ativada em modo live, fiz em 8 de novembro de 2026 a conferência da produção no terminal e à mão no painel. ## Um script confere a conta live e alinha a versão dos webhooks O repositório tem um script que confere a conta inteira com `bun stripe:check:production --live`. Ele só passou em tudo depois de os dois webhooks de produção serem recriados na versão de API do SDK, `2026-10-28.endive`, com os segredos novos guardados no Wrangler. Os dois webhooks têm segredos distintos. Em staging, os webhooks seguem na versão `2026-08-26.dahlia`, o que não afeta clientes. Um script cria o catálogo: os preços do plano Pro, o portal do cliente e os dois webhooks. ## As chaves de acesso são restritas com permissões por tabela As chaves do Stripe são restritas, com permissões por tabela. Uma chave atende os scripts de operação e fica só no arquivo local do ambiente. Outra chave atende a API e fica só no Wrangler, depois de um teste de permissões passar. Assim, os scripts locais de operação e a API em produção nunca usam a mesma chave. ## O painel exige conferência manual de e-mails, tentativas e Radar Na conferência à mão no painel, os e-mails de pagamento e de reembolso do próprio Stripe estavam desligados e o idioma dos e-mails estava em Português (Brasil). O Smart Retries ficou com 8 tentativas em 2 semanas e cancelamento no fim, o padrão que o Stripe recomenda e que o SRS passou a registrar. No Radar, conferi os controles de risco ligados. Entram nessa lista contestação por fraude, alerta antecipado, cartão roubado e fraude fora do cartão. ## O código foi corrigido para tratar tentativas antigas e entregas pendentes Antes disso, na fase de testes, dois defeitos graves tinham sido corrigidos no fluxo de pagamento. No primeiro, uma tentativa antiga de cartão continuava válida. Agora uma nova tentativa expira a sessão ou cancela o PIX anterior, o webhook só confirma a tentativa atual com o valor do pedido, e qualquer outro pagamento, seja tentativa antiga, segundo pagamento ou pedido vencido, é reembolsado inteiro e fica no registro de auditoria. No segundo defeito, uma falha depois do pagamento deixava o pedido sem entrega. Agora o pedido pago fica marcado como entrega pendente até a transação que aplica o efeito, e a repetição do webhook ou uma rotina agendada, depois de 5 minutos, retoma a entrega uma vez só. ## A troca do mensal para o semestral segue com decisão pendente No portal do cliente, a troca do plano mensal para o semestral vale na hora e cobra sem rateio. Isso acontece porque o portal do Stripe só adia para o fim do período a troca que reduz o valor ou encurta o intervalo. O SRS pede outro comportamento, e essa decisão ainda está pendente comigo. Ver o modo de teste passar valida a integração, mas só uma conferência própria na conta live protege quem cobra e quem compra. Para ver a base dessa operação como pessoa física, leia sobre [anunciar e vender no CPF](/blog/anunciar-e-vender-no-cpf) e confira também como publiquei o [primeiro pacote no npm](/blog/primeiro-pacote-npm-cli). --- ## Três regras de HSTS num só domínio: por que deixei o preload de fora. URL: https://luisjunior.ai/blog/hsts-sem-preload Publicado em 8 de novembro de 2026 · Desenvolvimento · Arrumando a casa, parte 22 Como resolvi a divergência entre borda, repositório e SRS no Currículo para Vaga e por que uso 6 meses de HSTS sem preload nas zonas da conta. No teste em produção do Currículo para Vaga, em 5 de novembro de 2026, três lugares davam três respostas diferentes para o mesmo cabeçalho de segurança. Dois deles pediam HSTS com `preload`, justamente a diretiva mais difícil de desfazer depois que entra em vigor. O HSTS é o cabeçalho que manda o navegador usar só HTTPS num domínio durante o período definido em `max-age`. Com `includeSubDomains`, a regra vale também para os subdomínios. A diretiva `preload` sinaliza consentimento para inclusão numa lista embutida nos navegadores; ela sozinha não inclui o domínio. É preciso também solicitar a inclusão e cumprir os [requisitos da lista de preload](https://hstspreload.org/). Com o domínio incluído, a regra vale até na primeira visita. ## Borda, repositório e SRS pediam prazos diferentes A divergência apareceu marcada como de prioridade baixa. A borda da Cloudflare servia 6 meses, ou 15.552.000 segundos, sem `preload`. Os arquivos `_headers` do repositório pediam 1 ano com `preload`, e o requisito do SRS pedia 2 anos, ou 63.072.000 segundos, também com `preload`. ## O requisito mais seguro no papel era o mais difícil de desfazer Entrar na lista de preload parece a escolha mais segura na documentação, mas é difícil de desfazer e obriga HTTPS também nos subdomínios. Se surgir um subdomínio sem HTTPS válido, o navegador não permite contornar o erro para acessá-lo. Antes de pedir o `preload`, faça uma pergunta: todos os subdomínios, hoje e no futuro, aguentam só HTTPS? Os 6 meses de `max-age` com `includeSubDomains` já obrigam HTTPS depois que o navegador recebe o cabeçalho, sem incluir a zona nessa lista. A primeira visita é a diferença: sem preload, o navegador ainda precisa aprender a regra. ## O padrão da conta alinhou todos os arquivos à borda Em 8 de novembro de 2026, ficou o meu padrão de domínios, que vale para as zonas da conta: `max-age=15552000`, com `includeSubDomains` e sem `preload`. O requisito do SRS e os três arquivos `_headers` passaram a dizer exatamente o mesmo que a borda da Cloudflare. O mesmo padrão de domínios define SSL `strict`, TLS mínimo 1.2, TLS 1.3, Always HTTPS e Automatic HTTPS Rewrites. Esse conjunto exige HTTPS na borda. A proteção da primeira visita oferecida pela lista de preload é uma decisão separada. ## A exceção do Garfim ficou documentada no alinhamento No portfólio, a exceção é o Garfim, em que o próprio app envia 1 ano com `preload`. A divergência ficou registrada no documento de alinhamento do produto, em vez de ser escondida. Quando três arquivos dizem três coisas, decida uma vez num padrão e alinhe todos ao que a produção realmente serve. Para ver o restante dessa base, leia sobre [o padrão de domínios na Cloudflare](/blog/padrao-de-dominios-cloudflare) e veja como organizo [o padrão entre produtos](/blog/padrao-entre-produtos-69-itens). --- ## Uma palavra a menos derrubou 13 páginas que já estavam no ar. URL: https://luisjunior.ai/blog/paginas-sumiram-do-google-portao Publicado em 8 de novembro de 2026 · Desenvolvimento · Laboratório de busca, parte 2 Como um portão do build tirou 13 páginas do Currículo para Vaga quando a nota caiu de 100 para 98, e os dados da primeira semana de busca e robôs de IA. Em 7 de novembro, 13 páginas de desenvolvedor front-end do Currículo para Vaga saíram do ar de uma vez e passaram a responder 404 em produção. Uma delas, a página de headline do LinkedIn para desenvolvedor front-end, já estava no índice do Google em 6 de novembro. A queda veio de dentro do meu próprio pipeline de verificação. Eu já vinha testando travas automáticas de publicação em [as 650 páginas contra a regra do método](/blog/laboratorio-busca-650-paginas), e desta vez um portão desenhado para segurar qualidade excluiu em silêncio um conjunto inteiro que o buscador já conhecia. ## Uma palavra abaixo do mínimo derrubou a nota de 100 para 98 As páginas de cargo do Currículo para Vaga são geradas a partir de dossiês, e cada uma só vai ao ar se passar pelos portões de qualidade do build. Um deles exige que a nota calculada do exemplo bem feito bata a nota declarada no dossiê. Quando os números divergem, o portão exclui o dossiê da saída. Em 7 de novembro, uma mudança na contagem de palavras passou a dar 349 palavras ao exemplo de desenvolvedor front-end, uma abaixo do mínimo de uma das regras. Com isso, a nota do exemplo caiu de 100 para 98. Como o dossiê declarava 100, o portão excluiu o dossiê inteiro, os sitemaps de cargo ficaram com 119 cargos e a produção passou a responder 404 nas 13 páginas de desenvolvedor front-end. O caso deixa um alerta prático para quem mantém páginas programáticas com validação no build. Um portão que exclui itens reprovados sem avisar protege páginas inéditas, mas derruba URLs que o Google já indexou se uma regra mudar depois da publicação. ## A volta das 13 páginas esperou o código alcançar a produção A correção entrou em 8 de novembro: o dossiê passou a declarar 98, porque as palavras contam exatamente como as exportações imprimem. Com esse ajuste, a conferência de conteúdo voltou a passar com 1.557 páginas aprovadas. Mesmo com a conferência aprovada, a volta ao ar dependia da publicação seguinte do código. Isso acontece porque a publicação automática de conteúdo fica parada quando há código à frente da produção. Assim que o código foi publicado no mesmo dia 8 de novembro, as 13 páginas voltaram a responder 200. ## Como ler 39 impressões na primeira semana sem inventar demanda No fechamento da primeira semana do Search Console, de 1 a 7 de novembro, o site somou 39 impressões, 1 clique e posição média de 27,2. O Google mostra só 10 consultas, com 1 impressão cada, e deixa o restante anônimo. Ler o topo dessa tabela sem filtro leva ao erro. As páginas com mais impressões aparecem em posição de 1 a 9, o que interpretei como sinal de buscas pela marca ou com `site:`, inclusive as da própria medição. Isso ainda não comprova demanda pelos temas. Nas consultas que já têm página própria no site, apareceram quatro termos: - "curriculo cirurgião dentista" em 16º lugar. - "curriculo de jornalista" em 18º lugar. - "curriculo analista de sistemas" em 29º lugar. - "curriculo recepcionista" em 97º lugar. Uma impressão por consulta em uma semana é dado fino demais para sustentar decisão de conteúdo. Nenhuma consulta pediu página nova, e a releitura ficou marcada para quando houver 4 semanas de dados. ## O Google foi a 104 páginas, os robôs de IA correram e o Bing parou no zero Na leitura de 8 de novembro, o `site:` do Google passou de 62 para 104 páginas listadas. Já o Bing seguia com zero páginas indexadas, parado há 5 dias mesmo com a chave do IndexNow aceita e os sitemaps lidos. O passo seguinte é abrir um pedido ao suporte do Bing Webmaster. Os robôs de IA caminharam bem mais rápido nesse começo. O OAI-SearchBot, que alimenta a busca do ChatGPT, leu 504 páginas do site em 24 horas, depois de registrar 1 e 8 acessos nos dias anteriores. O Applebot leu 294 páginas em 7 de novembro. Olhar para a saúde das URLs publicadas vale mais na primeira semana do que tentar adivinhar pauta em cima de uma impressão isolada. Essa separação entre infraestrutura de indexação e leitura de demanda segue o que aplico em [o método de busca na prática](/blog/seo-aeo-geo-na-pratica). --- ## Outro agente de IA revisou meu código 71 vezes e criou dois defeitos. URL: https://luisjunior.ai/blog/ia-revisou-meu-codigo-71-vezes Publicado em 8 de novembro de 2026 · Inteligência artificial · Como trabalho com IA, parte 9 O que 71 rodadas de revisão por IA e 448 commits mudaram no Currículo para Vaga, os dois defeitos que entraram e o roteiro de auditoria que ficou. Em 7 e 8 de novembro, o Currículo para Vaga passou por 71 rodadas seguidas de revisão feitas por outro agente de IA, em esforço alto. O ciclo inteiro gerou 448 commits em dois dias. Quando a fila parou, fiz uma auditoria comparando o produto com o estado anterior às rodadas. Eu precisava conferir se todo aquele trabalho tinha afastado o sistema de [o método de SRS](/blog/metodo-cerne-srs-com-ia), removido o que devia continuar lá ou piorado o uso. ## O tamanho de 448 commits e a queda de retorno após a rodada 50 Somando todas as frentes do repositório, os 448 commits mexeram em centenas de arquivos e em dezenas de milhares de linhas. O levantamento por área mostra onde as alterações se concentraram: - Código da API: 107 arquivos, com 7.661 linhas a mais e 2.313 a menos. - Código do painel: 93 arquivos, com 5.667 linhas a mais e 1.908 a menos. - Testes do painel e da API: 144 arquivos, com 27.355 linhas a mais e 378 a menos. - SRS: 23 arquivos, com 160 linhas a mais e 140 a menos. - Site, admin, extensão, CLI e pacotes: 132 arquivos, com 6.338 linhas a mais e 841 a menos. Fora dessa lista, as migrações somaram 53.575 linhas, quase tudo snapshot gerado pelo Drizzle. O ganho por rodada, no entanto, caiu bastante no terço final. Da rodada 50 à 71, a maior parte tratou corridas de tempo raras no painel: resposta que chega depois de a pessoa sair da tela, duplo clique, duas gravações do mesmo registro e foco dos diálogos. Esse trecho teve retorno baixo perto do volume mexido. ## Como auditar um produto revisado por IA contra o estado anterior Quem roda revisões automatizadas em sequência precisa auditar o resultado com a mesma disciplina aplicada a código inédito. O roteiro prático compara o produto com o estado anterior às rodadas em cinco frentes: 1. Preços e textos legais, que exigem estabilidade total. 2. Texto dos prompts e esquemas de saída da IA. 3. Migrações de banco, conferindo se todas são aditivas. 4. Arquivos, procedimentos, rotas e escopo do produto, procurando remoções ou criações indevidas. 5. Mensagens da interface, separando o que saiu, o que mudou e o que entrou. No Currículo para Vaga, a auditoria encontrou essa estrutura íntegra. Preços e textos legais continuaram sem mudança, e o texto dos prompts também ficou igual, mudando apenas um esquema de saída. As migrações foram todas aditivas, nenhum procedimento ou rota saiu do ar, nenhum produto novo apareceu fora do escopo e o único arquivo removido foi trocado por outro com o mesmo comportamento. Nas mensagens em português, 5 saíram, 24 entraram e 1 mudou. As 24 mensagens novas são de erro ou de estado para casos que antes falhavam sem explicação para quem usava o painel. ## Os dois estragos reais que entraram durante as rodadas A auditoria também pegou dois defeitos criados pelas próprias rodadas. O mais grave mexeu na reserva de descontos: uma tentativa de compra não paga passou a reservar o uso do cupom e o desconto de indicação. Quem gerava um PIX, voltava e tentava comprar com outro currículo ou outra vaga perdia o desconto por até 7 dias, prazo em que o pedido abandonado expira. Na correção, as tentativas não pagas da própria pessoa deixaram de contar contra ela, enquanto a tentativa aberta de outra pessoa ainda segura o último uso de um cupom. A reserva da indicação foi desfeita e o SRS voltou ao que dizia antes das revisões. O segundo estrago entrou na rodada 71, a última da sequência. Restaurar uma versão anterior do currículo perdia as edições que a gravação automática tinha salvado desde a última versão. Com a correção, essas edições automáticas viram uma versão própria antes da restauração. ## A ordem de decisão após a auditoria e o ponto de parada Para arbitrar cada achado depois da auditoria, segui uma prioridade explícita quando dois objetivos batiam de frente: segurança, usabilidade ou venda, sempre nesta ordem. Essa hierarquia separa proteção real de ajuste cosmético. A compra em lote e o reajuste mostram essa escolha na prática: os dois continuam reservando no início do pagamento porque isso impede que a mesma cobertura pague duas tentativas, evitando perda direta na cobrança. O atrito de usabilidade aparece só numa combinação rara, e mexer outra vez nas travas do pagamento traria mais risco que ganho. A regra que ficou encerra o ciclo antes do desgaste: todas as rodadas de revisão passam por triagem, e a rodada em que nada passa pela triagem é a última. Decidir onde a automação para continua entre [as decisões que continuo tomando](/blog/desenvolver-com-ia-alem-do-codigo). --- ## Depois de 20 anos de carreira, publiquei meu primeiro pacote no npm. URL: https://luisjunior.ai/blog/primeiro-pacote-npm-cli Publicado em 8 de novembro de 2026 · Lançamento · Construindo o Currículo para Vaga, parte 1 Como coloquei a CLI do Currículo para Vaga no npm com GitHub Actions, teste no Node 22.13, empacotamento em monorepo e a correção do ./ no npm publish. Em mais de 20 anos de carreira, eu nunca tinha publicado um pacote no npm até as 10h15 de 8 de novembro de 2026. Saiu na organização `luis-junior` que tenho no npm, sob licença MIT, a versão 1.0.0 de [`@luis-junior/curriculo-para-vaga`](https://www.npmjs.com/package/@luis-junior/curriculo-para-vaga). Esse pacote entrega a CLI do Currículo para Vaga, meu SaaS em produção desde 2 de novembro em curriculoparavaga.com.br, citado antes sem nome em [um dev sozinho com IA](/blog/um-dev-com-ia-apps-saas-mcp-cli). A proposta cabe na descrição do pacote: nota ATS, análise de vaga e ajuste de currículo para vagas no Brasil, do terminal ou do seu agente de IA. Enquanto a extensão de navegador do produto espera a aprovação da Chrome Web Store, qualquer pessoa ou agente de IA já usa o serviço por uma linha no terminal. ## Uma linha no terminal roda o produto com ou sem conta Quem quiser usar sem instalar roda `npx @luis-junior/curriculo-para-vaga ats curriculo.pdf --job ` ou executa pelo `bunx`. Para instalar na máquina, o comando é `npm i -g @luis-junior/curriculo-para-vaga`, que habilita os atalhos `cpv` e `curriculo-para-vaga`. O ambiente precisa de Node.js 22.13 ou mais novo na linha 22, ou 23.5 em diante. Dois comandos funcionam grátis e sem conta, com limite de 3 análises ATS e 2 planos por dia. O `cpv ats` calcula a nota de 0 a 100 na triagem automática e mostra o que corrigir primeiro. O `cpv plan` informa a compatibilidade com a vaga, até onde a nota pode subir e o plano de melhoria. Três comandos cobrem os recursos pagos do produto. O `cpv improve` reescreve o currículo para a vaga, aceitando de 1 a 10 vagas de uma vez, e a reescrita nunca inventa cargo, empresa, data, diploma nem número. Completam a lista o `cpv letter`, que escreve a carta de apresentação, e o `cpv linkedin`, que ajusta o perfil do LinkedIn. ## Agentes e humanos passam pela mesma API sem pagamento automático A CLI e o servidor MCP do Currículo para Vaga seguem uma mesma decisão de arquitetura: nenhum dos dois tem regra própria. Os dois chamam a mesma API pública, que por sua vez chama os mesmos procedimentos usados pelo painel. Assim o comportamento continua único tanto no navegador quanto no terminal. Para agentes de código, `cpv install-skill --agent all` instala uma skill para o Claude Code e o Codex, apresentada na [página para agentes](https://curriculoparavaga.com.br/para-agentes). Quando a execução acontece fora de um terminal, a opção `--json` liga sozinha e imprime um objeto por linha, com o resultado final na última, enquanto os erros saem em JSON no `stderr`. O comando `cpv login` conecta a CLI à conta da pessoa. A chave salva fica vinculada ao endereço da API que a emitiu e nunca vai para outro endereço. Além disso, a CLI nunca paga sozinha: uma compra mostra o QR e o código do PIX junto com o link da página do pedido, e espera a pessoa pagar. ## O caminho seguro da tag ao pacote fechado no monorepo Para publicar a CLI com segurança, empurro uma tag `cli-v` e um workflow do GitHub Actions executa todas as travas antes de enviar ao registro. Quem mantém uma CLI em monorepo pode repetir exatamente esta sequência: 1. Conferir se a tag bate com a versão declarada no `package.json`. 2. Rodar os testes e fazer o build. 3. Confirmar que a CLI abre na versão mínima suportada do Node com `npx node@22.13.0 ... --version`. 4. Empacotar com `bun pm pack`, que escreve no pacote as versões reais das dependências internas do monorepo. 5. Publicar o arquivo `.tgz` gerado no npm. Validar a abertura no Node 22.13 evita publicar um binário que exige recursos presentes apenas numa versão mais nova instalada no runner. Essa conferência garante que a versão mínima prometida seja de fato respeitada antes do envio ao registro. ## Um ponto e uma barra separaram a falha das 10h01 da saída às 10h15 A primeira tentativa de publicar falhou no último comando. Sem prefixo de caminho relativo, `npm publish dist-cli/.tgz` foi lido pelo npm como um atalho de repositório do GitHub no formato `usuário/repositório`, e o comando tentou clonar um repositório em vez de ler o pacote local. A correção foi colocar `./` na frente do arquivo: `npm publish ./dist-cli/.tgz`. Esse ajuste entrou às 10h01, e o pacote saiu publicado às 10h15. O provenance do npm ficou desligado porque exige repositório público, e o repositório do produto é privado. Quando o repositório abrir, entram juntos `--provenance`, a permissão `id-token: write` e o campo `repository`. Enquanto minhas aplicações web seguem o modelo de [publicar da minha máquina](/blog/publicar-da-minha-maquina-ci-cd), distribuir um pacote público pede tag conferida e teste na versão mínima prometida. --- ## Sozinho com IA: iPhone, Android, SaaS com MCP e CLI, e já faturando. URL: https://luisjunior.ai/blog/um-dev-com-ia-apps-saas-mcp-cli Publicado em 7 de novembro de 2026 · Bastidores · Como trabalho com IA, parte 8 Um app nativo em Swift, um app iOS e Android em React Native, um SaaS com API, CLI e MCP e um desktop a caminho, feitos por um dev só com IA. Há poucos anos, cada item desta lista pedia um time próprio: um app nativo de iPhone, um app para iPhone e Android, um SaaS com API, CLI e servidor MCP. Coloquei os três no ar sozinho, com IA, e os primeiros pagamentos já entraram. O próximo formato, um aplicativo desktop, está a caminho. Quem desenvolve sozinho precisa saber que esse tamanho de operação ficou ao alcance de uma pessoa com experiência e IA. Abaixo vai cada item, com o link de quando ele foi ao ar. ## A IA multiplicou 20 anos de experiência Tenho mais de 20 anos de experiência em tecnologia, sistemas, operações e negócios. Hoje uso esse repertório para construir meus próprios produtos com IA, e conto as decisões aqui no blog. A IA multiplicou o que esses anos conseguem entregar. Decidir o produto, a arquitetura e o que vai ao ar continua comigo. Expliquei essa divisão em [as decisões que continuo tomando ao desenvolver com IA](/blog/desenvolver-com-ia-alem-do-codigo). ## Swift no ClipLeve e React Native no Garfim O ClipLeve é um app nativo de iPhone, escrito em Swift, para criar versões menores de vídeos. Está na App Store desde outubro, e contei o caminho até a aprovação em [o ClipLeve chegou à App Store](/blog/clipleve-aprovado-lancado-app-store). O Garfim é um app de iOS e Android feito em React Native com Expo, com uma base de código só para as duas plataformas. Foi aprovado na [App Store](/blog/garfim-aprovado-lancado-app-store) em 16 de outubro e chegou ao [Google Play](/blog/garfim-lancado-google-play) em 22 de outubro. A diferença entre os dois foi uma escolha ligada às plataformas que cada app precisava atender. O ClipLeve é só de iPhone, então fui de Swift. O Garfim precisava estar no iPhone e no Android, então fui de React Native. Ele desenha os componentes nativos de cada sistema, e o que chega ao celular é um app nativo. ## Um SaaS que conversa com o Claude e o ChatGPT O terceiro item é um SaaS que ainda não apresentei aqui pelo nome. Ele está em produção desde 2 de novembro e vai muito além do painel na web. Tem uma API pública, uma CLI para usar pelo terminal, uma extensão de navegador e um servidor MCP, que liga o produto direto ao Claude e ao ChatGPT como conector, com autorização OAuth 2.1. A decisão que segura tudo isso é simples. A CLI e o MCP não têm regra própria: os dois chamam a mesma API pública, e ela chama os mesmos procedimentos do painel. Preço, cota e propriedade dos dados ficam num lugar só, e nenhum caminho de agente conclui um pagamento. Quem abrir um produto para agentes pode usar a mesma API pública e os mesmos procedimentos do painel. A IA desse SaaS escreve com uma auditora que confere cada frase. Contei sobre ela em [a auditora que confere cada frase](/blog/ia-auditora-confere-cada-frase). ## Uma base para todos e a publicação na minha máquina Outro produto web, também sem nome por aqui, está em produção desde 1º de novembro. Os produtos web usam a mesma base: Cloudflare Workers, Hyperdrive, Postgres e Better Auth. Um defeito achado num deles vira correção para todos. Desde 7 de novembro, todo produto novo nasce de um clone de uma base própria, como contei em [meus produtos novos começam de um clone](/blog/base-de-produto-clone). E a publicação roda da minha máquina, como mostrei em [publicar da minha máquina](/blog/publicar-da-minha-maquina-ci-cd). ## No ar, faturando, e o desktop vem aí Os produtos lançados estão à disposição de quem quiser usar, e começaram a faturar. É o começo, e é o começo que importa: produto próprio, feito por mim, recebendo pagamento. Um aplicativo desktop está a caminho. Ele ainda não foi lançado. Um desenvolvedor com experiência e IA ocupa hoje o espaço que antes era de um time inteiro. Se você quer acompanhar como isso funciona por dentro, comece por [como uma foto do almoço vira um produto](/blog/da-ideia-ao-produto-na-era-da-ia). --- ## Copiei a mecânica dos líderes e recusei a mentira deles. URL: https://luisjunior.ai/blog/anuncio-copiar-mecanica-recusar-mentira Publicado em 7 de novembro de 2026 · Bastidores · Vender pelo anúncio, parte 3 Garimpei anúncios, funis e avaliações da categoria para separar a mecânica que funciona da mentira que vende. Seis conceitos saíram dessa leitura. Em 4 de novembro, fiz um garimpo do zero para anunciar na Meta um produto que ainda não apresentei aqui, um produto digital vendido por anúncio nos Estados Unidos. Ignorei de propósito as campanhas e os rascunhos anteriores. As fontes foram a biblioteca de anúncios da Meta, os funis públicos de quem anuncia na mesma categoria, sites de avaliação, Reddit e YouTube, e o próprio produto visto de fora. ## A categoria roda em vídeo curto e promessa direta A escala que encontrei nos Estados Unidos ajuda a entender o jogo. Havia cerca de 3.200 anúncios ativos na categoria, com cerca de 1.100 em vídeo e só cerca de 31 estáticos puros. Os vídeos que vencem duram de 21 a 47 segundos, tempo curto para mostrar o produto funcionando e pedir o clique. Quem lidera usa a mesma fórmula de entrada. O anúncio leva para uma página com uma persona descartável, traz uma promessa direta no criativo, usa botão de saiba mais e mantém o preço fora do anúncio. Aprender essa fórmula interessa porque ela se repete em quem ocupa o topo da categoria. A cobrança aparece só depois do clique, no fim da página, numa oferta inicial que vira assinatura com renovação automática. A prova social também entra no roteiro de convencimento, e ela pode ser fabricada dentro da própria página. Um dos casos que li mostra a nota filtrando só as avaliações de 3 a 5 estrelas, recorte que esconde o descontentamento de quem avaliou. ## A raiva de quem comprou desenha o posicionamento Nos sites de avaliação, a voz de quem comprou aparece dividida em dois polos. A raiva número 1 é a assinatura escondida, a 2 é o paywall depois do tempo gasto, a 3 é o resultado lisonjeiro feito para vender um extra e a 4 é o entregável genérico. Ler essa ordem muda a leitura do anúncio vencedor, porque mostra também as reclamações de quem comprou. O clique nasce de curiosidade, de tédio e de dúvida sobre si. Quando o elogio aparece, ele fala da experiência e da rapidez de uso. A cobrança nunca entra no elogio, e esse silêncio diz onde a categoria machuca quem paga. Essa leitura virou um mapa prático para o meu anúncio. Cada raiva registrada nas avaliações marca um ponto em que dá para prometer o contrário com verdade e ganhar a comparação. Posso apresentar as condições de pagamento de forma aberta no anúncio. ## Copio formato e duração e recuso preço escondido A decisão que saiu do garimpo separa duas colunas com clareza. Na coluna do que copiar entram um elemento interativo dentro do próprio criativo, vídeo curto mostrando o produto funcionando na tela, volume de variações e o nome da categoria que a pessoa já procura. Essa mecânica organiza a atenção e facilita o clique sem prometer nada além do produto. Na coluna do que recusar entram esconder o preço, oferecer algo que vira assinatura, anunciar estatística de usuários sem lastro e sustentar página com persona falsa. Essas escolhas apareceram na leitura dos anúncios e das avaliações. O que eu posso dizer com verdade coube em poucas linhas. O pagamento é único, nada renova sozinho, o reembolso vale por 14 dias e uma amostra completa fica pública para quem quiser conferir antes. O preço vai no texto do anúncio ou numa cartela, e ele fica fora do gancho falado no vídeo. O limite honesto também entrou no registro do garimpo. Hoje eu não tenho prova social que possa alegar nos criativos. Essa frase fica de fora até existir uma base real para sustentá-la. ## Seis conceitos nasceram da separação e aguardam campanha O garimpo terminou com seis conceitos de anúncio, em formato estático e em vídeo. Entre eles estão "o preço primeiro" e "resolva comigo", além de um conceito contra a renovação automática. Cada conceito puxa um ponto da leitura, da recusa da assinatura disfarçada até o convite para fazer junto com o produto. Em 6 de novembro, pausei todas as campanhas pagas desse produto, em todos os canais. Os anúncios não tinham gerado vendas até aquela data. Os seis conceitos novos ainda não foram testados. A biblioteca de anúncios mostra o que funciona na categoria, inclusive o que funciona porque engana quem clica. Separar a mecânica da mentira deixou o caminho do próximo criativo mais curto e mais defensável. Antes de voltar a anunciar, o canal também passa pelo crivo que contei em [por que pausei anúncios depois de ignorar o resultado anterior](/blog/pausar-canal-de-anuncio). --- ## A pergunta de LGPD que trava a venda: e o backup? URL: https://luisjunior.ai/blog/lgpd-perguntas-de-produto Publicado em 7 de novembro de 2026 · Produto · Arrumando a casa, parte 21 A pergunta que trava vendas é o destino do dado no backup. Veja as respostas sobre retenção, restauração e exclusão em até 90 dias que adotei. Em 5 de novembro de 2026, criei uma base para responder a perguntas sobre dados pessoais e transferência internacional que um produto ouve de quem o contrata. Este texto descreve o padrão que adotei. Ele não substitui um parecer jurídico. Essa base vale para qualquer produto meu que trate dados de pessoas no Brasil. Só entra regra que a lei exige ou que alguém pergunta. A pergunta que mais trava uma venda é: e o backup? ## O papel de operador e o limite do que é guardado O cliente é o controlador dos dados dos contatos dele, e o meu produto é o operador. O produto trata os dados só para prestar o serviço e conforme as instruções da empresa que contrata o produto (LGPD, art. 39). O produto guarda só o que o serviço precisa. Não compra, enriquece, cruza nem vende bases, e não usa o conteúdo dos clientes para outra finalidade. Os dados ficam pelo tempo que o cliente quiser. Ele pode apagá-los quando quiser, pelo painel ou com um pedido ao suporte. Quando o contrato termina, os dados são apagados em até 30 dias, salvo se o cliente pedir uma exportação antes (art. 16). ## O backup esquece sozinho em até 90 dias Quem pergunta sobre backup quer saber se o dado apagado continua guardado em algum lugar. A resposta honesta é que continua por um tempo, e esse tempo tem fim. O backup é rotativo: cada cópia expira sozinha, e o que o cliente apaga hoje some das cópias quando elas vencem. A promessa externa é de até 90 dias, com folga sobre o prazo real de cada produto. Prometer a exclusão imediata das cópias soaria melhor numa reunião, mas seria uma frase que eu não conseguiria sustentar. Um prazo com folga é uma promessa que se cumpre sempre. A outra metade da resposta cobre o dia em que for preciso restaurar uma cópia. Os pedidos de exclusão ficam registrados com data. Se um backup for restaurado, as exclusões feitas depois da data da cópia são aplicadas de novo antes de o sistema voltar ao ar, e assim a restauração não ressuscita dado apagado. ## Transferência internacional e segurança técnica com base legal A transferência internacional é permitida com garantias (art. 33). A garantia padrão são as cláusulas-padrão da ANPD (Resolução CD/ANPD nº 19/2024), incluídas no contrato ou nos termos de uso com o cliente, e o acordo de tratamento de dados (DPA) de cada fornecedor. Quando o canal do cliente já trata os dados no exterior, como WhatsApp e Instagram na Meta, isso entra na resposta. A segurança segue esta base: tráfego sempre em HTTPS, acesso administrativo com 2FA, segredos fora do código e isolamento entre clientes (art. 46). Só afirmo o que está conferido: backup criptografado só se afirma quando a criptografia em repouso estiver ligada e conferida. ## Prazos para atendimento a titulares e notificação de incidentes Quando um contato pede acesso, correção ou exclusão, o pedido é encaminhado a quem contratou o produto, na condição de controlador. O produto executa o que ele decidir, no prazo de referência de 15 dias (art. 18 e 19). Quando um incidente com dados é confirmado, o cliente é avisado em até 2 dias úteis, para que ele consiga comunicar a ANPD no prazo de 3 dias úteis (Resolução CD/ANPD nº 15/2024). Cada produto tem um e-mail de privacidade publicado nos termos. Agente de pequeno porte não precisa indicar encarregado, mas precisa ter o canal (Resolução CD/ANPD nº 2/2022). Com as respostas escritas antes da pergunta, nenhuma conversa de venda depende de improviso, e nada do que eu digo vai além do que o produto faz. Para ver como essa preocupação se traduz na interface de uso dos aplicativos, leia sobre a [confirmação de exclusão de conta](/blog/garfim-confirmacao-exclusao-conta). --- ## A IA calibrou minha câmera pelos números. Ficou cara de lanterna. URL: https://luisjunior.ai/blog/estudio-calibrar-camera-a-olho Publicado em 7 de novembro de 2026 · Bastidores · Como trabalho com IA, parte 7 A IA calibrou a Logitech Brio pelos números e a cena parecia uma lanterna no escuro. Veja como ajustei OBS, luz e foco manual comparando quadros. Em 6 de novembro de 2026, pedi a um agente de inteligência artificial que realizasse testes de calibração no meu estúdio de gravação. O agente operou diretamente na minha máquina, alterando parâmetros no aplicativo Logi Options+, no OBS Studio e na iluminação, extraindo quadros estáticos para comparar resultados. A estrutura de captura utiliza a webcam Logitech Brio 4K conectada por cabo, um iluminador Ulanzi VL-200Bi com octabox de 120 centímetros e o OBS com o plugin Vertical Canvas. A ficha de varejo da luminária aponta uma faixa de temperatura entre 2700 K e 6500 K, dado que ainda vou conferir na embalagem. O objetivo era achar a menor potência de luz compatível com um vídeo limpo. A primeira tentativa automatizada, porém, mostrou os limites de calibrar um cenário visual apenas com cálculos matemáticos. ## A calibração por números deixou a imagem com aspecto artificial Durante a tarde, o agente ajustou a imagem pelos números. Ele deixou o contraste em 45%, a saturação em 33% e 4800 K, aplicou vinheta nas bordas e escureceu o fundo para separar o rosto da parede. O efeito prático dessa combinação foi ruim. A cena ficou com cara de quarto escuro com uma lanterna. Ao avaliar a tela, decidi reverter as alterações e voltar ao estado do começo da sessão, que tinha magia. A regra para o estúdio passou a ser esta: o resultado visual se julga a olho, comparando o antes e o depois lado a lado na tela, uma mudança de cada vez. ## O foco manual e a redução de ruído medidos na prática Orientado pela avaliação visual, passei a usar as métricas como confirmação dos testes que funcionavam. O primeiro ajuste relevante foi a troca do foco automático da Logitech Brio pelo controle manual no Logi Options+. O foco manual em 4% gerou uma nitidez de bordas superior à do foco automático, registrando 538 contra 505 na medição de contornos. Nos testes com valores a partir de 15%, a imagem borrava. O segundo ponto foi o filtro de redução de ruído no OBS. A Logitech Brio entrega sinal em resolução 4K a 30 quadros por segundo, convertido para gravação em 1080p a 30 quadros. Com a sensibilidade em ISO 200 e a imagem 4K reduzida para 1080p, o ruído já é baixo. Ao medir a granulação na parede, o filtro reduziu a variação apenas de 2,4 para 2,05. A diferença não aparecia nem com ampliação de duas vezes no monitor. Como o processamento extra não trazia ganho visual, desliguei a redução de ruído no aplicativo. Testei também perfis LUT no OBS, avaliando variações de 25% a 100% dos pacotes Filme Quente e Aspen. Entre os testados, os melhores eram o Filme Quente a 75%, que tira o lilás da camiseta, e o Aspen a 50%. Decidi ficar sem nenhum LUT ativo. ## O ajuste da temperatura de cor entre a luz e o vestuário O alinhamento térmico entre a fonte de luz e a câmera foi a etapa mais sensível. Mantendo a Logitech Brio configurada manualmente em 5200 K, variei o iluminador Ulanzi de 6500 K até 3200 K. A resposta da cena foi nítida: 1. Em 6500 K, a luz fria deixava a camiseta azulada (R−B de −26). 2. Em 5500 K, a iluminação ficou neutra (R−B de −2). 3. Em 5000 K, a imagem atingiu um tom levemente aquecido (R−B de +11) e a pele natural. 4. Em 4500 K e abaixo, o quadro ficava laranja. Com a potência fixada em 10% a 5000 K, as medições indicaram mediana de 133 no rosto e p99 de 199, e a camiseta com p99 de 228 sem estourar. Para complementar a cena, posicionei um tubo de LED vertical na cor laranja em uma prateleira, aquecendo a parede direita. ## A configuração noturna que ainda aguarda aprovação visual Às 23h13 de 6 de novembro, uma nova configuração foi aplicada no estúdio. Ela ainda não recebeu a minha aprovação estética final. Nessa calibração provisória, a luminária Ulanzi ficou em 5000 K com 10% de intensidade. A Logitech Brio foi programada com obturador em 1/60 de segundo, ISO 100, temperatura de branco em 5000 K, brilho em 50%, contraste em 30%, saturação em 35%, nitidez em 10%, foco manual em 4% e HDR desligado. No OBS, o sinal 4K é gravado em 1080p a 30 quadros pelo codificador de hardware da Apple, com espaço de cores Rec.709 parcial. O LUT Aspen Standard ficou ativado em 25%, com os filtros de vinheta, cor e ruído desativados. As gravações de teste mantiveram a taxa estável de 30 quadros. A IA mede rápido e mede bem, e foi ela que achou o foco em 4% e a temperatura certa da luz. Quem decide se a imagem ficou bonita sou eu, com o antes e o depois lado a lado. Para conhecer outro exemplo prático em que o controle sobre modelos exige supervisão direta, leia sobre [como uma IA auditora confere cada frase](/blog/ia-auditora-confere-cada-frase). --- ## Um usuário não via o dia de ontem. Abri todo o passado do Garfim. URL: https://luisjunior.ai/blog/garfim-historico-dias-passados Publicado em 7 de novembro de 2026 · Produto · Construindo o Garfim, parte 19 A decisão de liberar a edição de qualquer dia passado no Garfim, sem limite de tempo e sem cobrar pelo que não consome IA. Veja as regras definidas. Em 6 de novembro de 2026, tomei uma decisão de produto a partir do feedback de um usuário que não conseguia ver o dia anterior. O aplicativo só mostrava o consumo de hoje. A especificação do projeto já contemplava a edição retroativa e a cópia de refeições antigas. As fotos guardadas também nunca eram lidas de volta. O feedback evidenciou uma promessa no planejamento que a tela não entregava. Defini então um registro de decisão técnica para reorganizar essa navegação. Deixo claro que se trata de uma decisão de arquitetura: em 7 de novembro, nada disso está no aplicativo no ar. Minha regra de trabalho exige que toda implementação seja a menor necessária, testada localmente e validada em ambiente de testes antes de subir para a produção. ## Qualquer dia anterior funciona exatamente como o dia atual A premissa da mudança é direta: qualquer dia passado precisa funcionar como o dia de hoje. A tela principal ganha uma faixa com os dias da semana para permitir a troca de data no mesmo espaço. Ao tocar numa data anterior, a pessoa vê as refeições registradas, o consumo de água e os totais nutricionais daquele dia. O dia selecionado fica salvo apenas na memória do aparelho. Se o usuário fechar o aplicativo ou se o dia virar, a visualização retorna para a data corrente. Também desenhei uma tela de histórico mensal com calendário, total de dias registrados, média calórica e lista em ordem decrescente, com busca pelo nome do alimento. A regra temporal estabelece limites claros. O sistema recusa registros com data futura, aceitando no máximo 15 minutos de folga em relação ao servidor para celulares com relógio adiantado. Para o passado, não há limite: os dados são da pessoa e ela preenche o histórico quando quiser. Refeições em dias anteriores recebem o horário usual do turno naquela data (08:00, 12:30, 16:00 e 20:00 no fuso horário da conta). A tela permite alterar o horário exato ou mover o prato de dia. A água também passa a ser editável no passado, com os copos adicionados no meio-dia da data escolhida. ## O que consome inteligência artificial mantém a cota diária Um ponto central foi separar o que consome processamento de inteligência artificial das consultas de dados. Tudo o que não gera custo computacional segue gratuito. Visualizar o passado, editar porções, mover refeições, copiar pratos antigos, excluir registros e cadastrar alimentos por busca de texto ou código de barras permanecem liberados no plano gratuito. O consumo das cotas gratuitas ocorre quando o aplicativo chama os modelos de visão ou de áudio. Uma análise fotográfica de um prato de ontem consome o limite diário da data em que a chamada é realizada, não da data da refeição. No mesmo dia 6, removi das fichas das lojas a promessa de escolher fotos da galeria, pois o aplicativo não tinha esse recurso. A decisão do histórico agora inclui a importação de fotos da galeria para refeições fotografadas antes e não registradas na hora. Por exigir código nativo no celular, essa função chegará aos usuários numa versão nova das lojas, aplicando a mesma miniatura de 512 pixels das fotos comuns. Para a remoção de várias refeições, o aplicativo processa as exclusões em lote após uma única confirmação, informando o total de calorias antes e depois da limpeza. ## As fotos voltam a ser exibidas sem criar novos caminhos no sistema Até agora, as fotos enviadas não eram lidas de volta pela interface. A nova regra determina que a foto da refeição volta a ser exibida para quem a tirou, permanecendo disponível enquanto o registro existir na conta. A leitura dessas imagens aproveita a mesma sessão e checagem de propriedade das refeições, sem criar rotas paralelas ou novas estruturas de segurança. A antiga regra que apagava fotos após 30 dias foi revogada. Excluir a refeição ou a conta remove as imagens, e a limpeza automática continua descartando rascunhos após 24 horas. A opção de salvar imagens segue como escolha em Privacidade, mas passa a vir ativada por padrão no consentimento do cadastro. Contas existentes preservam a opção já definida. Se a foto de uma refeição não foi guardada ou expirou na regra antiga, a tela mostra uma ilustração de prato com aviso de foto indisponível, mantendo a lista de alimentos. A numeração da política de privacidade fica igual para não invalidar consentimentos já concedidos. ## O que foi recusado para manter a estrutura enxuta Durante a proposta, avaliei e recusei três alternativas que trariam complexidade ao código: 1. A criação de telas separadas para rotas de datas específicas, o que duplicaria a interface já existente na tela principal. 2. A criação de caminhos paralelos no servidor para servir imagens, o que exigiria um segundo fluxo de autenticação para arquivos pequenos. 3. A adição de uma nova biblioteca externa para seleção de calendário, visto que a base nativa do aplicativo já oferece esse componente. Uma frase de um usuário bastou para mostrar que a especificação prometia o que a tela não entregava. A entrega vem em partes pequenas, cada uma testada localmente e em staging antes de chegar ao aplicativo. No mesmo dia, a ficha das lojas também precisou alinhar promessa e produto, como contei em [62% baixavam o Garfim, e o problema estava antes da página](/blog/garfim-ficha-das-lojas). --- ## 62% baixavam o Garfim. O problema estava antes da página. URL: https://luisjunior.ai/blog/garfim-ficha-das-lojas Publicado em 7 de novembro de 2026 · Lançamento · Construindo o Garfim, parte 18 Cerca de 62% de quem via a página baixava o Garfim, mas a busca não trazia visitas. Veja como mudei palavras-chave, capturas e textos nas lojas. Em 6 de novembro de 2026, pedi uma auditoria das fichas do Garfim na App Store e no Google Play. O levantamento revelou um contraste no comportamento do público. Cerca de 62% de quem abria a página do Garfim na App Store baixava o aplicativo. Por outro lado, só cerca de 4% das impressões na loja viravam visita à página. ## A busca era o gargalo para quem ainda não conhecia o aplicativo Quando a pessoa chegava a ver a página inteira, a proposta do diário convencia. A barreira acontecia antes, quando o aplicativo disputava espaço na lista de resultados. O gargalo estava na exibição inicial: ícone, nome, subtítulo, as primeiras capturas de tela e a própria posição nas buscas. A API pública de busca da Apple ajudou a medir esse alcance. O Garfim aparecia em 9º lugar para "calorias por foto", em 24º para "contador de calorias por foto" e em 54º para "calorias ia". Nas buscas genéricas, como "contador de calorias", "calorias", "dieta", "diário alimentar", "macros", "emagrecer", "marmita" e "tabela taco", o aplicativo ficava fora dos cerca de 190 primeiros resultados. Autorizei a execução imediata de todas as melhorias possíveis para subir nas duas lojas. ## Subtítulo novo e termos em português na ficha em inglês Na App Store brasileira, o subtítulo anterior era "Dieta, proteína, macros e água". Troquei a frase por "Contador, dieta, macros e água". A alteração fez a palavra "contador" se combinar com "Calorias", que já estava no nome do aplicativo, cobrindo buscas relevantes sem desperdiçar espaço. O campo de palavras-chave da versão em português continha termos sem resultado. Retirei a palavra "contador", transferida para o subtítulo, e apaguei termos como "código", "barras", "voz" e "taco", que não geravam posições na busca. A lista em português ficou com 97 bytes ocupados: `proteína,diário,alimentar,nutrição,emagrecer,peso,refeição,comida,prato,marmita,hipertrofia`. A loja brasileira da Apple indexa os campos da localização em inglês dos Estados Unidos. Aproveitei esse mecanismo para cadastrar a ficha americana com o título "Garfim: AI Calorie Counter", subtítulo "Food diary, macros & protein" e termos em português que não couberam na ficha brasileira: `alimentação,saudável,emagrecimento,carboidratos,tabela,nutricional,fit,brazilian,meal,tracker`. Quando a versão nova for aprovada, esses termos passam a contar nas buscas feitas no Brasil por esse cadastro secundário. No Google Play, a ficha não tinha categorias secundárias cadastradas. Incluí as tags "Dieta", "Perda de peso" e "Saúde e fitness". Deixei a opção "Treino" de fora porque o Garfim não é um aplicativo de treinos. Criei também a ficha em inglês americano na loja do Google, com título e descrições próprias, mantendo os mesmos materiais visuais da versão em português. ## Correção de promessa na descrição e capturas feitas no simulador A auditoria apontou um erro que precisava ser corrigido. As descrições nas duas lojas diziam que o usuário podia escolher fotos da galeria. O aplicativo real não conta com essa importação: a tela apenas abre a câmera para até 3 fotos da mesma refeição. Atualizei o texto em todas as fichas para evitar expectativas erradas. Na App Store brasileira, o texto passou a instruir o usuário a fotografar o prato pelo aplicativo, com até 3 fotos. No Google Play, a descrição completa recebeu a mesma redação direta. O texto promocional da App Store foi renovado para reforçar medidas caseiras e destacar o plano grátis sem prazo e sem cartão, com uma análise por foto ou voz por dia. As capturas de tela foram refeitas para mostrar a interface exata do aplicativo. Subi 9 capturas na App Store para o formato de 6,9 polegadas e um vídeo de prévia de 21,6 segundos a 30 quadros por segundo. Todas as imagens vieram da versão de Release rodando no simulador de iPhone 18 Pro, conectada a uma API de testes com dados na memória. Como o simulador não tem câmera, o aplicativo usou uma foto estática de prato feito no visor. O reconhecedor de testes retornou exatamente os alimentos da foto: 3 colheres de servir de arroz branco, 1 concha de feijão carioca, 1 filé e meio de peito de frango grelhado e salada de alface e tomate, mapeados para a tabela TACO. A captura do registro por voz exibiu texto digitado na tela, sem simular fala. Durante a revisão das diretrizes de acessibilidade, testei a tela com tamanho de texto ampliado. A interface se reorganiza, mas os detalhes das porções na busca são cortados com reticências. Esse corte impede o atendimento ao critério da Apple de manter o conteúdo legível sem perdas, e por isso deixei a declaração de texto grande desmarcada. ## O que entrou em análise e os passos seguintes A publicação dos novos materiais seguiu processos distintos. Na Apple, a troca de imagens e do vídeo exigia uma nova versão. Enviei a versão 0.1.3, cujo código traz apenas a atualização do número de versão, sem alteração interna no aplicativo. Marquei a liberação automática para quando a equipe da Apple concluir a análise. No Google Play, as mudanças de texto e as tags entraram em análise em 6 de novembro. O vídeo de prévia no Google Play ficou pendente porque a plataforma requer um endereço do YouTube, canal que a conta ainda não possui. As capturas de tela no Android seguiram em 6 de 8, porque não se usa recorte de iPhone no Play. Uma página que converte não serve de nada se ninguém chega até ela. Mexi no que aparece antes do clique e tirei da ficha uma promessa que o app não cumpria; o efeito nas visitas ainda vai ser medido depois das análises. Esse mesmo cuidado orientou a definição do [histórico de dias passados no Garfim](/blog/garfim-historico-dias-passados). --- ## O idioma certo na tela pode virar o errado no servidor. URL: https://luisjunior.ai/blog/padrao-de-idiomas-paraglide Publicado em 7 de novembro de 2026 · Desenvolvimento · Arrumando a casa, parte 20 Veja como organizo URLs e mensagens com Paraglide JS e guardo o idioma escolhido para respostas e comunicações posteriores. Uma tela no idioma certo não garante que o e-mail enviado depois saia no mesmo idioma. O idioma precisa acompanhar o pedido e continuar gravado quando o processamento sai do navegador. Defini esse padrão em 5 de novembro, quando um produto que ainda não apresentei aqui ganhou a versão brasileira. Ele vale para todo produto com mais de um idioma, inclusive os novos. A regra cobre desde a URL pública até o texto produzido no servidor. ## As mensagens curtas ficam juntas no pacote Nos produtos web em TypeScript, uso Paraglide JS 2 num pacote `packages/i18n`. A regra vale para Astro, SPA React e API Hono em Workers. As mensagens ficam em JSON por idioma e são compiladas no build com chaves tipadas. Cada build do navegador leva um idioma só. Essa organização define com clareza onde mora o texto curto de interface: telas, moldura do site, botões e erros entram no catálogo de mensagens. Cada chave tipada representa o texto exato que a interface deve renderizar. Para documentos longos ou com estrutura, o tratamento é diferente. Textos de jurídico, blog, metodologia, e-mails com blocos e prompts de IA ficam em arquivos de conteúdo por idioma. Essa separação respeita o ciclo de vida de cada documento sem sobrecarregar o catálogo de interface. Essa divisão também orienta a manutenção contínua do código. Ajustar um botão exige alterar apenas o arquivo JSON do catálogo; atualizar termos de uso mexe apenas nos arquivos de conteúdo. A separação mantém os arquivos de tradução limpos e fáceis de auditar. ## A URL mostra o idioma da página pública As páginas públicas levam prefixo do idioma, slug traduzido, `hreflang` e link de troca de idioma. O visitante encontra um caminho claro e previsível para a versão que deseja abrir. Não adoto redirecionamento automático por país ou navegador. O português do Brasil usa `pt-BR` como código e `/pt-br` como prefixo de URL quando não é o idioma base. A base de onde nascem os produtos novos já vem configurada com `en-US` na raiz e `pt-BR` em `/pt-br`. A estrutura da URL faz parte da arquitetura de conteúdo público. O slug traduzido mantém a semântica da página em cada língua, e o link de troca dá acesso imediato à outra opção. As tags `hreflang` informam aos buscadores a relação direta entre as versões equivalentes. A revisão de uma página pública confere a rota completa junto com o conteúdo visível. Uma tradução correta no corpo da página perde utilidade se faltar o cabeçalho de idioma ou o link alternativo. O padrão reúne esses elementos para validar a experiência inteira do visitante. ## O servidor recebe o idioma em cada chamada No servidor, passo sempre `{ locale }` explícito em cada mensagem, nunca um idioma global. O isolate do Worker atende pedidos simultâneos de origens diferentes. O app manda o idioma num cabeçalho em toda chamada para garantir o contexto certo na resposta. Usar variáveis globais de idioma causaria vazamento de contexto entre requisições concorrentes. No modelo de execução dos Workers, um pedido em inglês e outro em português podem compartilhar a mesma instância. O parâmetro explícito em cada função elimina qualquer risco de contaminação cruzada. O trabalho com idiomas não termina quando a resposta chega ao navegador. O idioma fica gravado no registro (tentativa, lead, usuário) para tudo o que sai depois: e-mail, PDF, lembrete. Essa informação precisa continuar persistida para acompanhar o ciclo de vida da conta. Uma tela traduzida não encerra a localização do produto. Se a verificação parar na interface web, comunicações disparadas horas depois podem sair no idioma padrão errado. O padrão exige persistir a preferência no banco desde o primeiro contato. ## A revisão alcança os produtos existentes No gate, `bun i18n:check` falha com chave ausente ou variável perdida. Tradução feita por modelo é revisada antes de publicar. A validação automatizada impede que chaves esquecidas quebrem a interface em produção. Apps nativos usam o catálogo da plataforma: `Localizable.xcstrings` no iOS e i18next no React Native, como no Garfim. O padrão respeita os ecossistemas nativos onde eles já possuem convenções estabelecidas. A situação em 5 de novembro mostra o estado da transição: dois produtos que ainda não apresentei aqui já seguem o padrão. O site do ClipLeve tem páginas duplicadas em `/en/`, sem mensagens compiladas. O app do Garfim segue o item dos nativos, e o site dele ainda vai ser conferido. A padronização dos que divergem fica para outra sessão. O erro mais custoso de idioma aparece horas depois no servidor ou na caixa de entrada do usuário. Guardar a escolha no registro e exigir `{ locale }` explícito em cada chamada resolve o problema na raiz. Para outra decisão técnica compartilhada, veja como organizei o [roteamento de IA pelo OpenRouter](/blog/openrouter-velocidade-primeiro). --- ## O limite de 10 por minuto que deixou passar muito mais. URL: https://luisjunior.ai/blog/rate-limit-cloudflare-aproximado Publicado em 7 de novembro de 2026 · Desenvolvimento · Arrumando a casa, parte 19 Entenda quando o Rate Limiting dos Workers é aproximado e como testei em produção um contador exato com rajadas em IPv4 e IPv6. Configurei um limite de 10 pedidos por minuto e vi passar bem mais que 10. A configuração parecia certa no código. Sob uma rajada rápida, o comportamento foi diferente do esperado. O caso aconteceu num produto que ainda não apresentei aqui. O binding de Rate Limiting dos Cloudflare Workers conta por local, e essa forma de contar deixou passar rajadas acima do limite configurado. Para organizar a arquitetura, precisei separar o limite aproximado do limite que precisa ser exato. ## O número configurado precisa de um teste Um limite escrito na configuração comunica uma intenção, mas não prova a retenção real. Para saber o que acontece sob rajadas, é preciso disparar requisições em sequência e contar o retorno. Foi nesse teste prático que o limite de 10 por minuto aceitou bem mais que 10. A contagem por local explica esse comportamento do binding em borda. Como os pedidos chegam a instâncias diferentes da rede, cada nó mantém sua própria fatia da contagem. Quando a regra de negócio exige precisão absoluta, esse modelo distribuído deixa passar picos indesejados. O binding continua bom para limites folgados, como 60 por minuto na API geral. Nesse cenário, pequenas variações temporárias não afetam a segurança da aplicação. A contagem aproximada atende perfeitamente quando o objetivo é apenas conter abusos grosseiros. Para um limite que precisa ser exato, como login e envio de código, a exigência é diferente. Nessas rotas sensíveis, qualquer brecha em rajada compromete a regra de segurança. Ali a contagem precisa de um único ponto centralizado de verdade. ## O contador exato usa um Durable Object Para os limites que precisam ser exatos, troquei o binding por um Durable Object com SQLite. Ele conta por IP com hash e libera a passagem se o objeto falhar. Um IPv6 conta pelo seu /64. Essa regra garante que uma eventual falha no objeto libere a passagem sem travar a navegação. O contador exato opera enquanto o Durable Object responde normalmente. Se houver falha de infraestrutura, a requisição passa sem gerar um erro inesperado. A identificação precisa tratar cada protocolo de forma adequada. O hash do IP isola a origem sem armazenar o endereço original no banco local. No IPv6, agrupar pelo bloco /64 evita que um mesmo remetente contorne o limite apenas rotacionando endereços da mesma faixa. Esse desenho centraliza a contagem de forma consistente. Cada tentativa de autenticação consulta o mesmo estado compartilhado no Durable Object. O controle deixa de depender de replicações assíncronas entre pontos da rede. ## A rajada precisa passar pelos dois protocolos A prova está em produção: 10 aceitos e 30 recusados, tanto em IPv4 quanto em IPv6. O teste confirma que a regra atua nos dois caminhos em vez de assumir que o resultado de um representa o outro. Essa checagem direta afasta qualquer suposição sobre a borda. Num teste, uma máquina com IPv4 e IPv6 conta como dois clientes. Use `curl -4` e `curl -6`. Testar apenas um dos protocolos deixaria metade das rotas sem validação real. A verificação separada impede falsos positivos no diagnóstico. Se o teste alternar entre protocolos durante os disparos, o contador enxerga duas origens distintas e aceita o dobro de requisições. Rodar cada bateria de testes de forma isolada garante a medição correta. Essa separação comprova o funcionamento exato da proteção. Os dois mecanismos têm papéis bem definidos na infraestrutura de borda. O teste com rajadas confirma que a regra de bloqueio atua exatamente no limite configurado. ## A conferência continua nos outros produtos Registrei o caso numa lista de alertas da stack comum, com onde foi provado e o que conferir nos outros produtos. Um usa o mesmo binding com o limite do Better Auth desligado. O Garfim ainda não foi conferido. Os dois ficaram anotados na lista de alertas da stack comum para acompanhamento. Essa documentação define qual operação está protegida, qual mecanismo conta e se aquele limite precisa ser exato. Uma regra que protege a API geral não deve ser assumida como suficiente para rotas de login. A conclusão técnica é sempre medir a passagem real sob rajada nos dois protocolos. O número na configuração só ganha valor prático quando o teste confirma o comportamento esperado. Outro problema compartilhado que registrei na mesma stack está no relato sobre [conexões presas atrás do Hyperdrive](/blog/dependabot-postgres-4-hyperdrive). --- ## Um PR do Dependabot travou meu banco e as rotas voltaram 500. URL: https://luisjunior.ai/blog/dependabot-postgres-4-hyperdrive Publicado em 7 de novembro de 2026 · Desenvolvimento · Arrumando a casa, parte 18 Veja como identifiquei conexões presas atrás do Hyperdrive e provei a correção antes de liberar uma atualização do driver. Uma atualização automática do driver de banco deixou conexões presas e fez rotas responderem 500. O pull request chegou pelo Dependabot, mas o teste que resolveu o caso precisou passar pelo Hyperdrive. Meus produtos web usam a mesma base: Cloudflare Workers, Hyperdrive, PlanetScale Postgres e Better Auth. Um defeito num vale para os outros. Por isso, cada dependência compartilhada pede atenção redobrada. ## A atualização chegou antes do sintoma Em 4 de novembro, a versão 4.0.0 do driver `postgres` chegou a um produto que ainda não apresentei aqui por um pull request do Dependabot. A alteração envolvia uma mudança de versão maior do pacote usado para acessar o banco de dados. Ela deixou conexões em `active / ClientRead` com transação aberta atrás do Hyperdrive e esgotou o pool. As rotas com banco passaram a responder 500 depois de uns 15 s, e as chamadas tRPC agrupadas travavam. O pool cheio impedia qualquer nova consulta de concluir. A sequência dá um caminho claro de diagnóstico: conferir a alteração do driver e observar o estado das conexões no banco enquanto as requisições falham. Uma resposta 500 aponta para uma falha geral, mas não revela o estado interno do pool. Olhar diretamente para o banco permitiu associar o erro às conexões retidas. Não investiguei a causa exata dentro do driver. O que ficou comprovado para a decisão foi o comportamento observado nessa combinação de ferramentas e o resultado prático após reverter a versão. Isso delimita a conclusão e define o critério para testes futuros. ## O estado das conexões mostra o que procurar Para ver conexões presas, a verificação em `pg_stat_activity` procura por `state = 'active'` com `wait_event = 'ClientRead'` há mais de um minuto. Essa consulta isola as conexões que permanecem ocupadas sem devolver o controle ao pool. Esse estado ajuda a confirmar se o problema está na retenção de processos pelo driver. O detalhe da transação aberta também faz parte do diagnóstico. As conexões ativas permaneciam presas com transação em aberto, o pool se esgotava e as chamadas tRPC agrupadas travavam completamente. Acompanhar esses sinais juntos mostra o gargalo real de execução com precisão. As chamadas tRPC agrupadas serviram para reproduzir o problema e validar a solução. Uma consulta isolada que responde com sucesso não demonstra que o pool suporta requisições simultâneas sem reter conexões. O teste precisava observar a conclusão das chamadas e a liberação imediata do banco. Ao investigar um caso parecido, anote a versão do driver e a presença do Hyperdrive antes de comparar os resultados. A regra que adotei está ligada diretamente a essa combinação de infraestrutura. Alterar múltiplos fatores ao mesmo tempo impede saber qual modificação corrigiu o comportamento. ## A volta de versão teve uma prova em staging A correção foi voltar para `^3.4.9`, a versão que o Garfim e outro produto usam. Também mandei o Dependabot ignorar a versão maior do pacote no arquivo de configuração. Assim, as próximas checagens automáticas não reabrem essa mesma versão maior até que o teste seja refeito. A prova veio em staging: 50 de 50 consultas agrupadas com resposta 200 e nenhuma conexão presa. Nenhuma das consultas travou, e nenhuma conexão ficou presa no banco depois delas. Esse resultado sustenta a decisão de manter a versão anterior estável. Ele não tenta adivinhar o mecanismo interno do driver. Qualquer atualização futura de versão maior precisará passar exatamente pelo mesmo roteiro de validação. O registro mantém a prova completa: o cenário que travava e a confirmação em staging após o ajuste. Ter a contagem de respostas 200 junto com a verificação de conexões no banco dá a certeza de que a falha foi resolvida. O histórico evita repetir suposições em incidentes semelhantes. ## A regra acompanha a stack comum A regra que ficou para todos os meus produtos: não aceitar o `postgres` 4 sem repetir esse teste atrás do Hyperdrive. A atualização automática de dependências continua útil para acompanhar novidades. Uma versão maior de driver, porém, só entra depois de repetir as consultas agrupadas atrás do Hyperdrive e conferir o pool. Registrei o caso numa lista de alertas da stack comum, com onde foi provado e o que conferir nos outros produtos. Compartilhar a mesma base permite antecipar problemas antes que eles cheguem aos usuários. Cada projeto com essa infraestrutura passa a ter o mesmo ponto de checagem documentado. Uma dependência atualizada pode parecer inofensiva no pull request até derrubar as rotas que dependem do banco. O teste que prova a correção termina quando as consultas retornam com sucesso e o pool permanece livre. Também escrevi sobre outra decisão compartilhada entre produtos, a [configuração do OpenRouter](/blog/openrouter-velocidade-primeiro). --- ## Meus produtos novos não começam do zero. Começam de um clone. URL: https://luisjunior.ai/blog/base-de-produto-clone Publicado em 7 de novembro de 2026 · Desenvolvimento · Arrumando a casa, parte 16 Uma base privada marcada como template traz site, app, conta, pagamentos e IA prontos. Cada produto clona, renomeia e apaga o que não usa. Em 7 de novembro, decidi ter uma base própria para os meus produtos, num repositório só, privado e marcado como template no GitHub, sempre na última versão do `main`. Começar um produto apontando para o repositório e o commit de outro pode arrastar decisões que só fazem sentido naquele produto. Começar do zero pode repetir erros de conta, publicação e operação. ## A base traz o que todo produto precisa e nenhum produto A base entrega um site e um app em inglês e português, entrada na conta, a conta com cópia dos dados e exclusão, a área do operador atrás do Cloudflare Access, e-mail, pagamentos e IA atrás de adaptadores com fakes que funcionam. Ela traz também erros e analytics depois do consentimento, retenção, alertas e runbooks, com a publicação rodando da minha máquina. Nenhum produto mora dentro dela, e cada clone apaga o que não usa. O Garfim e dois produtos que ainda não apresentei aqui nasceram antes da base e não são clones dela. Um produto já criado também não recebe a base de novo de forma automática. A regra de volta mantém a base viva sem misturar os produtos. Uma melhoria genérica feita num produto, como uma correção de segurança, um portão ou um padrão de operação, volta para a base num commit e numa linha do changelog. O que pertence ao domínio de um produto fica só naquele produto e nunca entra na base. ## O rename troca slug, nome e domínio em todo o repositório Quem começa um produto clona a última versão do `main` da base para o repositório próprio, com histórico novo. Depois roda `bun install` e `bun rename "" `, informando o slug, o nome de exibição e o domínio do produto novo. O comando troca o slug em cada nome de recurso, como workers, filas, buckets e o banco local, troca o nome de exibição onde o produto é nomeado e troca `example.com` em todo o repositório. O rename também renova a chave do IndexNow e formata o que ele mudou. Depois dele, confiro o `git diff` e preencho o que o comando não tem como saber, como os dados de infraestrutura e a entidade legal do produto novo. A partir daí, escrevo o SRS na pasta de especificação e moldo a base ao produto, removendo telas, procedimentos, tabelas e e-mails que ele não precisa. A prova da troca vem com `bun rename:check`, incluído no gate da base. O comando renomeia uma cópia real do repositório e roda a checagem de tipos e a suíte inteira dela, e o gate da base executa essa prova. Num repositório já renomeado, o comando reconhece o estado, pula a prova e avisa, porque a base já provou a troca na cópia dela. ## Seis rodadas de revisão fecharam a base no mesmo dia O changelog da base registra seis rodadas de revisão em 7 de novembro, além da versão inicial cortada de um produto que ainda não apresentei aqui. Duas dessas rodadas aparecem nos exemplos abaixo, no Postgres do gate e na lista de exceções do gitleaks. Registrar cada rodada no changelog deixa visível o que um produto futuro pode querer trazer da base. Um exemplo está no Postgres que o gate sobe para os testes. Cada execução marca o container com um rótulo aleatório próprio e remove só os containers que carregam aquele rótulo. Com dois gates rodando ao mesmo tempo, uma execução que falha por colisão de nome encerra sem tocar no banco da outra. ## A exceção do gitleaks libera um achado por vez O outro exemplo está na lista de exceções do gitleaks, a ferramenta que procura segredo no código. A lista passou a liberar um achado por regra e pelo valor exato dele, e parou de liberar por linha. Na versão 8.30, uma exceção por linha deixava passar todos os achados de um arquivo inteiro quando qualquer linha dele casava com a exceção, e o teste da base roda o scanner de verdade para provar o comportamento. Clonar a base encurta o começo e mantém cada produto dono do próprio domínio. O próximo passo dessa organização está em [publicar da minha máquina](/blog/publicar-da-minha-maquina-ci-cd), onde conto como a publicação roda daqui. --- ## Tirei uma trava da minha IA e a resposta caiu de 5,5 s para 3,7 s. URL: https://luisjunior.ai/blog/openrouter-velocidade-primeiro Publicado em 7 de novembro de 2026 · Desenvolvimento · Arrumando a casa, parte 17 Veja como comparar provedores no OpenRouter e configurar o roteamento por throughput sem restringir a escolha de endpoints. Uma opção de retenção zero prendia toda a IA de um produto a um provedor que respondeu 1,8 s mais devagar que o melhor no meu teste. A configuração parecia pequena. O efeito aparecia em toda chamada. Todos os meus produtos chamam modelos de IA pelo OpenRouter, que manda cada chamada para um dos provedores que servem aquele modelo. Isso me dá uma escolha a mais para investigar quando a resposta demora: olhar também para o caminho percorrido pela chamada. ## A retenção zero fechou a escolha de provedor Num produto que ainda não apresentei aqui, toda chamada enviava `provider.zdr: true`. Para o modelo da OpenAI que ele usa, só o Azure tinha endpoint com retenção zero, então todo o tráfego ficava preso no Azure, e a IA ficou lenta. A lentidão parecia vir do modelo, mas a causa estava na restrição enviada na chamada. O nome do modelo permanecia igual em cada requisição, mas a exigência sobre o provedor reduzia as opções disponíveis ao roteador. Uma escolha feita na configuração passou a determinar o caminho de todas as respostas. Esse detalhe importa quando se usa um roteador de modelos. Ter vários provedores disponíveis para um modelo não significa que todos estejam disponíveis para a configuração enviada. Cada restrição precisa ser considerada junto da chamada que a contém. A comparação também precisava respeitar as mesmas condições para isolar o impacto da rota. O teste precisa manter o mesmo pedido, o mesmo modelo e o mesmo nível de raciocínio em cada tentativa. Mantive esses elementos iguais para comparar os tempos entre endpoints. ## O mesmo pedido mostrou tempos diferentes Em 6 de novembro, medi a mesma chamada com o GPT-6 Luna e raciocínio `medium`. O Amazon Bedrock respondeu em 3,7 s, o Azure em 5,5 s e a OpenAI direta em 7,0 s. O intervalo entre o Bedrock e o Azure foi de 1,8 s. Ao enviar `provider.sort: "throughput"`, o OpenRouter escolheu o Bedrock sozinho. A escolha acompanhou o objetivo da configuração: ordenar os provedores pela velocidade de processamento. No pedido medido, o caminho escolhido também foi o que teve o menor tempo entre os comparados. O resultado mede aquela chamada específica, sem garantir que o mesmo provedor vença sempre. A utilidade do teste está em manter pedido, modelo e raciocínio iguais e observar o que muda ao trocar o provedor. Assim a comparação responde a uma pergunta direta sobre tempo de resposta. Para repetir a medição em outro produto, comece pela chamada que parece lenta e confira quais restrições ela envia. Depois, compare os provedores disponíveis com a mesma entrada e a mesma configuração de modelo. Por último, teste o roteamento configurado para observar qual caminho o OpenRouter escolhe. ## A configuração passou a priorizar velocidade A decisão de 6 de novembro passou a valer para todos os meus produtos: nenhuma configuração que possa deixar a IA mais lenta. A regra fixa é não pedir retenção zero, não fechar a lista de provedores com `provider.only` e não ligar guardrail que restrinja provedor. Toda chamada de texto envia `provider.sort: "throughput"`. O esforço de raciocínio padrão é `medium`. A chamada prioriza a velocidade de processamento sem impor barreiras desnecessárias ao roteador. Há uma exceção na configuração que pode permanecer: `require_parameters: true`. Ela retira endpoints que não aceitam a saída estruturada solicitada. Esses endpoints dariam erro, então mantê-los na seleção não resolveria o pedido. As políticas de privacidade de cada produto passaram a citar o OpenRouter sem prometer retenção zero. O texto precisa acompanhar a configuração adotada. Uma promessa escrita para uma configuração anterior não deve continuar como descrição do comportamento atual. ## A exceção fica no produto que precisar dela A base de onde nascem os produtos novos já segue essa regra desde 7 de novembro, num registro de decisão chamado "OpenRouter: speed first". Cada projeto que nasce dessa base já começa com a regra escrita. Se um produto um dia precisar de retenção zero, a decisão será daquele produto. O código pede a condição em cada chamada, e as chaves dele recebem um guardrail com o nome do produto como segunda trava. A regra geral de velocidade permanece protegida no restante da operação. O ganho desta investigação foi descobrir qual configuração estava fechando as opções antes de mudar o modelo. O roteador só pode escolher entre os caminhos que a chamada permite. Para entender como organizo as contas que sustentam essa operação, contei o padrão no post sobre [Sentry, PostHog e OpenRouter](/blog/sentry-posthog-openrouter-uma-conta). --- ## Troquei velocidade por uma auditora que confere cada frase. URL: https://luisjunior.ai/blog/ia-auditora-confere-cada-frase Publicado em 7 de novembro de 2026 · Inteligência artificial · Como trabalho com IA, parte 6 Dois recursos que escrevem em nome do usuário ganharam agente, guarda em código e auditora frase a frase. O acerto subiu e a espera também. Num produto que ainda não apresentei aqui, dois recursos escrevem textos curtos em nome do usuário, a partir dos documentos que ele mesmo enviou, e esses textos vão direto para outra pessoa. Um deles produz uma mensagem e o outro produz uma resposta a uma pergunta de formulário. Uma frase inventada ali fala pelo usuário algo que ele não disse, e foi para fechar essa porta que eu refiz os dois recursos. ## Uma chamada única virou agente com ferramentas em 6 de novembro Em 6 de novembro, os dois recursos deixaram de ser uma chamada única ao modelo e viraram agentes com ferramentas. As ferramentas buscam nos documentos, leem um trecho, testam a fidelidade do texto e contam caracteres. O agente usa as ferramentas quando tem dúvida sobre o que pode afirmar. Na avaliação, esse trabalho levou de 2 a 4 passos por texto. A escrita deixou de depender de uma única passada sobre o material enviado. Depois do agente vêm duas travas em sequência. Primeiro entra um guarda em código, determinístico, que reprova o que não tem apoio nas fontes. Depois entra uma auditora, outro modelo em raciocínio alto, que confere o texto contra os documentos. ## A mensagem perde a frase sem apoio e segue verdadeira Na mensagem, o texto é cortado em frases e cada frase vai para uma auditora própria, com todas trabalhando ao mesmo tempo. A frase com um fato sem apoio sai da mensagem. Nada volta para o agente reescrever, porque uma nova escrita pediria outra auditoria com a pessoa esperando do outro lado. A mensagem sem aquela frase continua verdadeira, e por isso ela pode seguir. Se só sobram a saudação e a assinatura, nenhuma mensagem aparece para o usuário. Nesse caso, a cota do mês também fica preservada. Na resposta, a lógica muda porque o texto é uma afirmação só. Se a auditora reprova, a resposta não aparece e o usuário recebe o pedido para completar a informação: "Não consegui responder sem inventar. Me conte mais:". Cortar metade de uma resposta mudaria o sentido do que restou, e por isso esse recurso prefere parar e perguntar. ## A avaliação usa armadilhas antes de qualquer confiança A avaliação roda com casos sintéticos montados para fazer o modelo inventar. As armadilhas pedem algo que os documentos não têm, como uma ferramenta, uma certificação ou um número. Na avaliação, havia uma pessoa esperando por vez. Na mensagem, a chamada única passou em 8 de 16 casos, com tempo típico de 1,7 s e p95 de 2,2 s. O agente com as travas passou em 15 de 16 casos, com p50 de 19,5 s e p95 de 41 s. Ele cortou uma frase em 6 das 16 mensagens avaliadas. Na resposta, a chamada única passou em 15 de 18 casos, com p50 de 1,6 s e p95 de 3,5 s, e entregou duas respostas enfeitadas com detalhe que os documentos não davam. O agente com as travas passou em 17 de 18 casos, com p50 de 2,9 s e p95 de 40 s. A resposta que termina pedindo um dado ao usuário sai em 1,3 a 3 s. ## A espera cresceu junto com o acerto O tempo é quase todo da auditora. O agente leva de 4 a 9 s, e cada auditora leva de 6 a 25 s. Baixar a auditora para raciocínio médio manteve a espera no mesmo nível, com p50 de 24,5 s, e derrubou o resultado para 13 de 16 casos na mensagem. O juiz da avaliação é o mesmo modelo da auditora, e o veredito dele varia entre execuções, de 13 a 16 de 16 na mensagem. Por isso ainda não há linha de base fechada para comparar as próximas mudanças. A linha de base que eu aceito exige todos os casos aprovados, e esse critério continua valendo para as próximas rodadas. O acerto subiu nos dois recursos e a espera subiu junto. Para um texto que fala em nome de alguém, prefiro a pessoa esperando alguns segundos a uma frase que ela nunca disse. O mesmo cuidado com o que a IA afirma aparece em [a IA disse que usou as skills](/blog/ia-disse-que-usou-as-skills). --- ## Escrevi o método CERNE lendo seis especificações reais. URL: https://luisjunior.ai/blog/metodo-cerne-srs-com-ia Publicado em 7 de novembro de 2026 · Inteligência artificial · Como trabalho com IA, parte 5 Como seis especificações reais viraram o método CERNE para escrever um SRS completo com IA, sem deixar dúvida para quem implementa. Em 7 de novembro, montei o manual do meu método para especificar produto com IA. Na mesma manhã, ele passou por quatro rodadas de revisão de outro modelo de IA. Cada rodada virou um commit de correção, e todas aconteceram antes do meio-dia. ## Li seis especificações reais antes de escrever qualquer regra Antes de escrever o método, li seis especificações reais. Li cada uma junto com o histórico do git, com os ADRs e com o código que saiu dela. ADR é o registro curto de uma decisão e do motivo dela. A maior especificação tinha cerca de 325 mil palavras no primeiro commit e chegou a 347 mil palavras. As outras variavam bastante de tamanho, de uma especificação grande até a mais curta do grupo. Essa leitura mostrou o que continuou de pé depois da construção e o que precisou ser reescrito. O manual usa exemplos ilustrativos de domínios variados, como um app de agendamento para barbearias, um emissor de faturas para freelancers e uma loja de assinatura de ração. Os exemplos mostram a forma do documento. Eles não dizem o que construir. ## O tamanho aguentou e a repetição envelheceu Uma especificação escrita por IA em um dia levou um agente a construir 18 módulos em cerca de 11 dias. Na contagem de 7 de novembro, 323 dos 356 IDs de requisito aparecem citados no código. Registro canônico, ID estável, aceite verificável, texto exato de tela e contrato de API foram peças que mais pagaram. O que envelheceu foi a repetição. Um mesmo preço apareceu repetido em 106 lugares de 15 arquivos, e trechos diferentes passaram a dizer coisas diferentes sobre o mesmo fato. Na maior especificação, boa parte dos commits depois do lançamento serviu para recuperar a coerência entre trechos repetidos. O outro problema foi a ordem de entrada no ar. Num dos casos, cerca de 710 requisitos eram obrigatórios antes do primeiro anúncio. Especificar tudo continua necessário, e cada parte precisa ter a marca de quando ela entra no ar. ## As cinco etapas do CERNE organizam a escrita O método se chama CERNE e tem cinco etapas. Caminho escreve a aposta de receita e a ordem em que o produto vai ao ar, com o que entra no lançamento, o que vem depois e o que o produto não faz. Esqueleto herdado marca o que a base já entrega e decide tudo o que o produto muda. Registros escreve por completo, num lugar só, as decisões, as invariantes, as rotas, o catálogo, os eventos, o banco e os erros. Normas escreve cada fluxo por inteiro, com requisitos e aceite, estados, textos, contratos, IA e o lançamento. Evolução prova que não sobra dúvida e mantém o SRS verdadeiro enquanto o produto muda. O SRS é completo e não tem limite de tamanho, de arquivos nem de requisitos. O tamanho é consequência do produto. Nenhuma regra de organização autoriza deixar algo sem especificar, e uma dúvida de quem implementa conta como defeito do SRS. ## Invariantes e hipóteses mudam em ritmos diferentes Todo requisito pertence a uma de duas camadas, e as duas são escritas por completo. Invariantes guardam o que nenhum número justifica quebrar, como linhas vermelhas de marketing, integridade de cobrança e de acesso, lei, privacidade e segurança. Um defeito numa invariante bloqueia o lançamento. Hipóteses cobrem oferta, texto, funil, canal, cadência e limites de plano. Elas entram porque se espera que vendam, e mudam quando o dado mostra outro caminho. A mudança acontece no mesmo commit do código, com um ADR curto que registra o que foi visto. Essa separação evita dois erros comuns. A regra que sustenta a confiança do produto fica protegida de uma oscilação de resultado. A oferta que precisa aprender com o uso continua livre para mudar, desde que a mudança fique registrada. ## Um fato tem um dono e o teste do implementador fecha as lacunas A regra que amarra o documento é simples de enunciar: um fato, um dono. Cada fato fica escrito uma vez, e os outros trechos apontam para ele. Antes do código, o dono é o SRS, e depois do código alguns fatos passam para o código, como mensagens da interface, schema do banco e arquivo do prompt. A melhor verificação de completude disponível sem uma pessoa é o teste do implementador; ele não substitui a construção. Um agente novo, só com o SRS, lista as perguntas que mudariam o produto, e cada uma vira texto no documento. O teste roda em até três rodadas, sempre com um agente novo em cada rodada. Os portões ajudam a achar lacunas e nunca param a entrega. O SRS sai ao fim das rodadas com o relatório do que foi achado e do que sobrou como decisão em aberto com valor padrão. Quem quer aplicar a mesma lógica na construção pode continuar por [desenvolver com IA além do código](/blog/desenvolver-com-ia-alem-do-codigo). --- ## Como anunciar na Meta e vender online no CPF sem abrir empresa. URL: https://luisjunior.ai/blog/anunciar-e-vender-no-cpf Publicado em 5 de novembro de 2026 · Bastidores · Vender pelo anúncio, parte 2 Descubra as regras oficiais para anunciar na Meta e vender produtos digitais como pessoa física no Brasil, evitando que a burocracia atrase o lançamento. Eu achava que precisava de empresa para anunciar na Meta. Essa exigência aparecia nos meus próprios repositórios sem que ninguém a tivesse conferido. Em 30 de outubro de 2026, decidi verificar as regras na Central de Ajuda da Meta e na legislação brasileira. A checagem revelou que a exigência prévia de pessoa jurídica era um mito criado pela rotina. Dá para configurar a conta, publicar campanhas e receber pagamentos usando o próprio CPF. Compartilho aqui o que aprendi nessa experiência direta e nas fontes oficiais, sem intenção de parecer jurídico. Cada modelo de negócio tem suas particularidades, e consultar um contador continua sendo uma etapa recomendada para cada caso. ## A crença de que empresa é obrigatória atrasa o lançamento A crença de que é preciso abrir uma empresa antes de testar uma oferta pode atrasar um lançamento. Nos meus projetos, decidi conferir o requisito antes de tratá-lo como bloqueio. Nos meus projetos, essa trava aparecia como requisito técnico em vários documentos de infraestrutura. Bastou confrontar essa suposição com a realidade para perceber que a conta de anúncios da Meta no Brasil aceita CPF nas informações fiscais. A correção foi simples: atualizei os cadastros com meus dados autênticos de pessoa física. Hoje, iniciativas como o Pagenello, as contas de processamento de pagamentos no Stripe e as contas de desenvolvedor nas lojas de aplicativos já operam associadas ao meu CPF. No Stripe, a conta de pessoa física conta com extrato personalizado e suporte próprio com a marca do produto. Quando o faturamento justificar a transição societária, os dados podem ser alterados nas configurações, acionando uma nova rodada de verificação. ## As regras oficiais da Meta aceitam cadastro com CPF no Brasil Conferi a documentação oficial da Meta em 30 de outubro de 2026. A conta de anúncios aceita CPF, embora contas novas possam ter recursos limitados até a Meta liberar. O primeiro passo é a criação do portfólio empresarial, que parte diretamente do perfil pessoal do Facebook. O procedimento exige informar um nome público para o portfólio, seu nome e sobrenome e um endereço de e-mail comercial. Cada pessoa física tem permissão para criar até dois portfólios no sistema. As instruções completas estão no tutorial oficial sobre [como criar um portfólio](https://www.facebook.com/business/help/1710077379203657). Na sequência, a conta de anúncios no Brasil oferece a escolha explícita entre CNPJ ou CPF na seção de dados tributários. A verificação com CNPJ é a da empresa e não é condição prévia para anunciar. O guia da Meta explica os detalhes fiscais na página sobre [como adicionar o CNPJ ou CPF](https://www.facebook.com/business/help/1551726385075248). Contas e portfólios recém-criados podem ter limites iniciais de operação até que a plataforma estabeleça um histórico de conformidade. Outro cuidado importante é a escolha do país e da moeda no momento da configuração, parâmetros que não podem ser alterados posteriormente. ## Vender como pessoa física é previsto pela legislação brasileira Além da ferramenta de anúncios, a etapa seguinte é viabilizar o recebimento dos valores das vendas. Existe um receio comum de que o comércio eletrônico para pessoas físicas seja irregular no país. A legislação brasileira prevê claramente essa situação. O Decreto 7.962/2013, conhecido como a Lei do E-commerce, regulamenta o Código de Defesa do Consumidor no ambiente digital. O texto determina que o fornecedor deve informar em local de fácil visualização o número de inscrição no Cadastro Nacional de Pessoas Jurídicas ou no Cadastro de Pessoas Físicas. O decreto aceita CPF na identificação do fornecedor. Para aplicar a regra ao seu caso, vale conferir os detalhes com um contador. ## A exceção real aparece nos aplicativos de saúde regulada Encontrei uma restrição ao preparar um modo de saúde do Garfim para as lojas. A exceção envolve produtos que atuam no segmento de saúde regulada. Ao preparar o Garfim, o Google Play exigiu uma conta de desenvolvedor do tipo organizacional para habilitar um modo de saúde do aplicativo. A Apple adota postura semelhante, estabelecendo na diretriz 5.1.1(ix) das diretrizes de revisão da App Store que aplicativos que oferecem serviços de saúde específicos precisam ser publicados por pessoa jurídica. Nesses nichos sensíveis, a exigência de pessoa jurídica não vem do meio de pagamento nem da plataforma de anúncios, mas das regras setoriais das lojas de distribuição. ## O carnê-leão organiza os impostos até a hora de abrir a empresa Operar no CPF não significa ignorar as obrigações tributárias. Na minha operação no CPF, a receita vai para o carnê-leão. A aplicação das obrigações tributárias depende do caso e deve ser conferida com um contador. Quando a receita aparecer, posso comparar a operação no CPF com uma empresa. Até lá, não trato a abertura como bloqueio. Para entender como gerenciei decisões de tráfego pago nos produtos, leia sobre [quando pausar um canal de anúncio](/blog/pausar-canal-de-anuncio). --- ## Pausei anúncios depois de ignorar o resultado anterior. URL: https://luisjunior.ai/blog/pausar-canal-de-anuncio Publicado em 5 de novembro de 2026 · Bastidores · Vender pelo anúncio, parte 1 Por que pausei um canal do Pagenello e como passei a avaliar intenção, histórico e sinais de tráfego antes de manter um canal pago. ## O resultado anterior já pedia uma revisão Em 31 de outubro, pausei as campanhas de busca e Audience do Pagenello na Microsoft Advertising. Elas não trouxeram pedido nem tentativa de envio do formulário. A campanha antiga no mesmo canal também não tinha trazido pedido, e esse histórico deveria ter barrado o aumento. Esse foi meu erro. Olhei para a possibilidade do canal sem dar ao resultado anterior o peso que ele merecia. Deixo os números de fora de propósito: a decisão aqui está no histórico, na intenção e nos sinais observados. Antes de manter um canal pago, agora olho para o que ele já entregou, para a intenção de quem alcança e para o que as skills de marketing recomendam. Gasto anterior sem resultado exige justificativa para continuar. ## A consulta concentra uma parte da história Quase todos os cliques da busca vieram de uma única consulta: “web designer for law firms”. Eles se concentraram numa janela de uma hora de madrugada, e metade desses cliques não carregou a página. O padrão indica clique inválido, mas isso não foi confirmado. Essa distinção importa para a decisão. Posso reconhecer um sinal que merece atenção sem afirmar que já sei sua causa. O que estava confirmado era a concentração e a ausência de carregamento em parte dos cliques, junto da falta de pedidos e de tentativas de envio. Um clique também veio de “uber eats”, termo que virou palavra negativa. A configuração passou a impedir o anúncio de aparecer para essa consulta. Ele, sozinho, não transforma os demais sinais em resultado comercial. ## A intenção muda entre busca e Audience Na busca, a intenção aparece nas consultas. A busca de quem tem um negócio e quer um site é rara nesse canal, e isso pesa quando comparo o que ele alcança com o que o Pagenello oferece. Na Audience, a campanha aparece para leitores do MSN e do Outlook. Esse contexto é diferente de alguém procurar ativamente uma solução. Eu preciso considerar essa diferença antes de interpretar a presença da campanha como sinal de demanda. A revisão de canal, para mim, começa pelo percurso até o formulário e pelo que aconteceu depois. No caso, não houve nem tentativa de envio. Continuar exigiria uma justificativa para esse histórico e uma explicação de como a intenção alcançada se conecta à oferta. ## A pausa virou uma regra de decisão Pausar deu ao resultado anterior o peso que eu deveria ter dado antes do aumento. A regra não depende de dizer que todo clique concentrado é inválido ou que uma consulta isolada explica a campanha inteira. Depende de olhar para a evidência disponível e admitir o que ainda não está confirmado. Também preciso consultar as recomendações das skills de marketing antes de propor ou manter o canal. O trabalho é comparar essas recomendações com o histórico e a intenção observada, e registrar a justificativa quando houver resultado anterior sem retorno. Uma palavra negativa é uma configuração que impede o anúncio de aparecer para uma consulta indesejada. No caso de “uber eats”, ela respondeu a um sinal específico que eu conseguia identificar. A medida não dizia, por si só, que o restante do canal estava alcançando pessoas com a intenção certa. O percurso até o formulário ajuda a organizar a leitura. Uma consulta mostra o que alguém procurou; o carregamento indica se a página chegou a abrir; a tentativa de envio mostra uma ação posterior. Esses sinais ocupam lugares diferentes e não devem ser tratados como se todos demonstrassem interesse pela oferta. Na concentração observada, eu podia registrar a consulta, a janela e a falta de carregamento em parte dos cliques. Podia também apontar a hipótese de atividade inválida. O que eu não podia fazer era transformar essa hipótese em uma conclusão confirmada para explicar todo o resultado. Quem estiver avaliando uma campanha pode copiar a sequência: conferir o histórico do próprio canal, ler as consultas disponíveis e acompanhar o caminho até a ação desejada. Depois, comparar a intenção alcançada com a oferta e escrever o motivo para continuar ou pausar. Uma palavra negativa pode corrigir uma consulta inadequada, enquanto a decisão sobre o canal depende do conjunto de evidências. No meu caso, a informação anterior estava disponível antes do aumento. A regra nova existe para trazer esse histórico para o começo da decisão, junto das recomendações das skills de marketing. Continuar depois de um resultado anterior sem retorno pede uma justificativa concreta. Uma decisão comercial fica melhor quando a pendência aparece junto do fato confirmado. Essa mesma disciplina de separar observação e resultado acompanha o [laboratório de busca do Pagenello](/blog/laboratorio-busca-650-paginas). --- ## Como depurei um erro de API sem log no registro do Garfim. URL: https://luisjunior.ai/blog/garfim-voz-texto-erro-sem-log Publicado em 5 de novembro de 2026 · Desenvolvimento · Construindo o Garfim, parte 17 O caso da API que falhava silenciosamente em voz e texto enquanto a foto funcionava, a mudança súbita no provedor e a lição de nunca esconder a causa no log. A foto funcionava no Garfim, mas voz e texto falhavam e o log não mostrava a causa. O registro por foto retornava resultados, mas tentativas de registrar refeições por áudio ou digitação retornavam erro entre 6 e 9 segundos após o envio. No dia anterior, em 29 de outubro de 2026, uma refeição por voz havia sido salva em produção. Ao abrir o terminal para examinar os registros do servidor, o painel estava limpo. Não havia registro de exceção, rastreamento de pilha ou qualquer aviso de falha. A API respondia com código HTTP 503 e entregava uma mensagem amigável no celular, mas a causa técnica permanecia invisível. A investigação desse caso mostrou na prática como o cuidado excessivo em tratar mensagens de erro pode cegar a engenharia. Quando um sistema esconde a origem técnica de uma falha para proteger a interface, ele impede que você descubra o que realmente quebrou. ## O registro por foto funcionava enquanto voz e texto falhavam O comportamento do sistema parecia contraditório à primeira vista. A análise de imagens depende de modelos visuais complexos e continuava retornando resultados. Já as rotas de texto e voz, que teoricamente executavam tarefas mais leves, falhavam de forma sistemática. O fluxo de voz passa pela rota de processamento de texto. Ambas as entradas precisam extrair os nomes dos alimentos descritos e pesquisar os itens correspondentes na base nutricional por meio de comparação vetorial. Quando a requisição encerrava com erro 503, o aplicativo exibia um código amigável de falha de reconhecimento. Para quem utilizava o produto no celular, a sensação era de uma instabilidade passageira de conexão. Nos bastidores, porém, nenhuma refeição falada ou digitada conseguia ultrapassar a etapa de processamento. ## O erro amigável na tela escondia a falha real nos servidores A ausência de informações no log aconteceu por causa de uma decisão arquitetural da API. As falhas retornadas pelos provedores de inteligência artificial eram capturadas por blocos de tratamento e convertidas diretamente em códigos internos de retorno do aplicativo. Como o framework de rotas só registrava automaticamente falhas graves não tratadas do servidor, respostas tratadas eram consideradas desfechos esperados do negócio. A falha tratada não gerava uma linha que mostrasse sua causa. O primeiro passo para resolver o mistério foi instrumentar a captura da causa real. Adicionei um registro estruturado de falha de reconhecimento que permitiu identificar o erro de embedding e a latência da requisição. Imediatamente após a publicação desse ajuste em homologação, o terminal começou a falar: a chamada ao modelo de embedding da Google falhava após apenas 58 milissegundos. ## O log estruturado revelou a mudança repentina no provedor O registro inicial comprovou que a etapa de extração dos nomes dos alimentos ocorria com sucesso. O problema real acontecia na etapa seguinte, quando a API tentava transformar esses nomes em vetores para buscar alimentos equivalentes no banco. Para aprofundar o diagnóstico, alterei o cliente de integração para reter o status HTTP original devolvido pelo provedor intermediário. Ao enviar uma frase de teste com dois alimentos, o log exibiu com clareza um erro de resposta com código HTTP 404 após 47 milissegundos. Ao testar uma frase com um único alimento, a resposta retornava normal. A causa raiz estava desvendada: em 30 de outubro de 2026, o OpenRouter respondia 404 para requisições de embeddings contendo múltiplos textos sob as restrições de provedor e retenção zero usadas pelo Garfim, sem sequer encaminhar a solicitação para a Google. Como a análise por foto pesquisava cada alimento detectado individualmente, ela permaneceu imune. Já o texto agrupava todos os termos da frase em uma única chamada. Nenhuma linha de código do Garfim havia mudado: tratava-se de uma alteração silenciosa de comportamento no provedor externo. ## A correção em paralelo e o teste de regressão restabeleceram o fluxo Identificada a origem, a correção exigiu mudar a estratégia de envio das requisições. O cliente de embeddings foi reescrito para enviar estritamente um único texto por chamada, disparando até seis requisições simultâneas para respeitar a cota de conexões concorrentes da infraestrutura de Workers. Para detectar a regressão, escrevi um teste na camada de adaptadores. Esse teste reproduz exatamente o comportamento da falha: simula o erro 404 diante de requisições com múltiplos textos e valida a geração do vetor quando os textos descem em chamadas individuais. Se esse teste for executado contra o código anterior, ele falha imediatamente. Após a execução bem-sucedida de todas as suítes de teste de integração e tipagem, o pacote foi publicado em homologação e em produção. O teste real com a frase clássica "comi arroz e feijão" voltou a responder código HTTP 200 de imediato, combinando os dois itens com os alimentos da base sem gerar novas ocorrências de falha. ## Tratar o erro para o usuário exige preservar a causa técnica A grande lição desse incidente reside na separação entre experiência do usuário e visibilidade operacional. Entregar uma mensagem limpa e compreensiva na tela do celular é obrigação de qualquer bom produto, mas proteger a interface não autoriza silenciar a engenharia. Quando uma exceção de terceiro é engolida para gerar uma resposta bonita, o sistema transforma um defeito de infraestrutura em uma incógnita. Sem um log estruturado que preserve a causa original e o código de retorno, a depuração depende de adivinhação. Manter a causa diagnosticável nos registros do servidor dá um ponto de partida para investigar falhas de provedores. Para entender como integro essa governança com o bloqueio seguro de versões em caso de incidentes graves, leia sobre [como forçar atualização no React Native](/blog/garfim-bloquear-versao-antiga). --- ## Como forçar atualização no React Native antes de um defeito grave. URL: https://luisjunior.ai/blog/garfim-bloquear-versao-antiga Publicado em 5 de novembro de 2026 · Desenvolvimento · Construindo o Garfim, parte 16 Como o Garfim usa uma versão mínima para pedir atualização pela loja e evita bloqueios quando falta conexão ou versão conhecida. Em 30 de outubro de 2026, durante uma triagem de monitoramento de erros do Garfim, encontrei um padrão que se repetia: defeitos em versões antigas continuavam em uso por semanas. Quando um aplicativo é publicado no Google Play ou na App Store e não tem atualização pelo ar, uma versão lançada não pode ser retirada das lojas. Sem um mecanismo próprio para forçar a atualização, cada alteração futura no servidor é obrigada a manter compatibilidade com todas as versões já distribuídas. Para resolver esse problema de raiz, criei um portão de versão mínima suportada. A principal lição dessa arquitetura é simples: a trava precisa ser desenvolvida e publicada antes que um defeito grave aconteça. ## Uma versão publicada na loja nunca deixa de existir As lojas oficiais de aplicativos não oferecem um botão de reversão instantânea. Se você publica uma versão com um bug sutil de sincronização ou uma incompatibilidade de banco de dados, quem instalou essa versão continuará com ela aberta até decidir atualizar por conta própria. Sem atualizações pelo ar no projeto, a única forma de fazer o código novo chegar ao aparelho é pela loja. Se o aplicativo não possui uma rotina nativa para verificar se ainda tem autorização para operar, ele pode continuar chamando a API até a pessoa atualizar. Na prática, o desenvolvedor vira refém das próprias decisões passadas. A consequência no servidor é pesada. Sem uma forma de aposentar versões, cada mudança da API precisa considerar as versões já distribuídas. ## A API publica a versão mínima e o app bloqueia a navegação A solução adotada no Garfim funciona em duas pontas coordenadas. No servidor, a API publica variáveis de ambiente que definem a menor compilação aceita para cada sistema operacional: uma para iOS e outra para Android. No aplicativo em React Native, o número da compilação instalada é lido diretamente do sistema nativo. A comparação utiliza os identificadores numéricos que crescem a cada geração do build, evitando ambiguidades entre nomes comerciais de versão. Essa consulta à API é pública, permitindo que a checagem ocorra logo na inicialização, antes mesmo do login do usuário ou do preenchimento de cadastros iniciais. Quando o aplicativo detecta que a compilação atual está abaixo do limite mínimo publicado, o layout raiz entra em ação. Ele intercepta a navegação e substitui todas as rotas internas por uma tela única e intransponível de aviso. Nessa tela, uma mensagem objetiva explica a necessidade de atualizar e exibe um link direto para a respectiva loja de aplicativos. ## O suporte a falhas e modo offline impede bloqueios acidentais Um portão de atualização mal planejado pode criar um problema pior do que o bug que pretende evitar. Se a verificação depender estritamente de uma resposta rápida da rede a cada clique, qualquer oscilação de sinal impedirá o usuário de abrir o aplicativo. Para contornar essa fragilidade, o Garfim adota regras estritas de resiliência: - Se a resposta da API trouxer versão desconhecida ou a variável estiver vazia, o app nunca bloqueia. - A verificação não atrasa as telas, permitindo abrir a interface sem esperar a rede. - A última resposta válida fica salva localmente. Uma compilação já bloqueada continua barrada se abrir sem internet. - A cada abertura e retorno ao primeiro plano com conexão ativa, uma nova checagem é feita. Reduzir o mínimo libera o app na hora. Hoje, nenhuma versão está bloqueada no ambiente de produção. O portão está armado e pronto para agir apenas se uma emergência real exigir a retirada de uma compilação do ar. ## A trava só pode ser exigida depois da distribuição total na loja Subir o número da versão mínima no servidor é uma decisão operacional delicada, pois pode bloquear o acesso de quem ainda usa uma versão abaixo do mínimo. Por essa razão, essa alteração não é feita por cliques improvisados em painéis: ela passa por revisão de código e é publicada por meio de esteira de integração contínua. Existe uma regra de ouro para elevar esse patamar: a versão substituta precisa estar cem por cento disponível para todos os usuários na loja correspondente. Se o Google Play estiver executando um lançamento gradual, ou se a versão da App Store ainda não tiver sido liberada, subir o mínimo na API deixará pessoas barradas diante de uma loja que ainda não oferece o botão de atualizar. Na Apple, a liberação gradual distribui as atualizações automáticas; uma versão já lançada fica disponível para atualização manual. O portão de versão mínima só deve alcançar compilações que já tenham uma alternativa pública e acessível para a base inteira. ## O portão de versão precisa nascer antes do primeiro incidente A maior armadilha desse mecanismo é a ilusão de que ele pode ser construído quando o problema aparecer. O portão só protege as versões que já trazem o código da checagem compilado dentro de si. Se uma compilação antiga não foi programada para consultar a API e substituir a navegação, nenhuma instrução remota fará aquela tela de bloqueio surgir. O servidor até poderia recusar as requisições com erros genéricos, mas a pessoa no celular veria apenas mensagens confusas de falha de conexão, sem entender que precisa abrir a loja e baixar a atualização. Por isso a trava entrou na versão 0.1.2 do Garfim, enviada às duas lojas em 31 de outubro de 2026. As compilações anteriores ainda dependem de cuidados no servidor, mas as versões que incluem a trava obedecem à regra. Criar a trava antes do defeito dá tranquilidade para evoluir o sistema. Para ver os passos anteriores da preparação do aplicativo, confira o relato sobre [conseguir testadores e esperar 14 dias](/blog/garfim-testadores-14-dias-antes-do-lancamento). --- ## Como levei o LCP do ClipLeve de 9,9 s para menos de 1,5 s. URL: https://luisjunior.ai/blog/clipleve-site-novo-lighthouse Publicado em 5 de novembro de 2026 · Desenvolvimento · Construindo o ClipLeve, parte 4 O diagnóstico do PNG pesado no topo, a migração para Astro em Workers e a reconstrução do site com 100 de pontuação e calculadoras úteis. O site antigo do ClipLeve levou 9,9 s para atingir o LCP e recebeu 70 em desempenho no Lighthouse para celular. Para um aplicativo cujo propósito é tornar arquivos leves e rápidos de compartilhar, manter um site lento na primeira dobra contradizia a própria proposta do produto. A solução foi reconstruir o site do zero com Astro e publicá-lo em um Worker da Cloudflare. Com ajustes objetivos de entrega e eliminação de peso desnecessário, o LCP despencou para uma faixa entre 0,9 e 1,3 s na produção, com nota 100 em todas as categorias de medição. ## Um PNG de 1,7 MB sem cache destruía o carregamento no celular O diagnóstico do Lighthouse apontou o culpado imediatamente. O Largest Contentful Paint, que mede o tempo para exibir o maior conteúdo visível na tela, sofria com uma única imagem no topo da página. Era um arquivo PNG de 1,7 MB, servido diretamente pelo provedor antigo sem qualquer política de cache eficiente. O PNG de 1,7 MB servido sem cache foi apontado como a causa do LCP de 9,9 s no teste. A experiência era inaceitável. Quando alguém pesquisa como comprimir um arquivo de vídeo pelo celular, a tolerância para páginas pesadas é nula. Bastava uma imagem mal dimensionada para destruir a percepção técnica do produto. ## A arquitetura em Astro e Worker entrega páginas estáticas sem atrito A reconstrução utilizou Astro gerando apenas arquivos estáticos, servidos diretamente na borda por um Worker da Cloudflare. Como o ClipLeve não possui formulários de contato nem exige banco de dados no site, não havia justificativa técnica para carregar processamento dinâmico em cada visita. O novo título da página passou a destacar o valor central de forma objetiva: "Comprima seus vídeos no iPhone sem arriscar os originais". Ao rodar o Lighthouse na produção após o deploy, a versão em inglês da página inicial, um guia temático e uma das calculadoras alcançaram 100 nas quatro notas avaliadas: desempenho, acessibilidade, boas práticas e SEO. Nessas páginas, o LCP no celular ficou entre 0,9 e 1,3 s. ## O catálogo de conteúdo cresceu com guias e calculadoras úteis A reconstrução também ampliou a quantidade de páginas indexáveis. O site saltou de 8 para 29 páginas indexáveis, divididas entre páginas principais, 17 guias práticos e 2 calculadoras interativas. A principal ferramenta adicionada foi a calculadora de tamanho de vídeo, desenvolvida com o modelo matemático do próprio aplicativo nativo. Ela usa o modelo do próprio app para estimar o tamanho de um vídeo. Para que os guias fossem práticos e confiáveis, os limites de envio das plataformas de mensagem foram conferidos em fontes oficiais em 30 de outubro de 2026: - Discord gratuito: limite máximo de 20 MB por arquivo. - WhatsApp no iPhone: envios de mídia com até 100 MB em resolução 720p ou 64 MB em resolução 480p, além de documentos de até 2 GB. - Outlook.com: limite fixo de 25 MB para anexos de mensagens. Esses limites dão contexto para quem precisa preparar um vídeo para envio. ## As URLs legadas foram preservadas com redirecionamento temporário Uma reformulação estrutural de site nunca pode ignorar os endereços já publicados. No caso do ClipLeve, o aplicativo já disponível na App Store já usava links com terminação `.html`. Se essas páginas retornassem erro após a mudança para rotas amigáveis, usuários reais do aplicativo ficariam desamparados ao buscar os termos legais ou o canal de suporte. O site novo configurou um redirecionamento automático com código HTTP 307 para cada um desses arquivos, direcionando a navegação para os novos endereços sem a extensão. O código 307 indica um redirecionamento temporário e mantém o método da requisição. As URLs antigas continuam respondendo com segurança e sem quebras para o usuário final. ## Um portão de qualidade no build impede que regressões cheguem ao ar Velocidade conquistada precisa ser defendida a cada deploy. Para evitar que alterações futuras introduzam imagens pesadas sem otimização ou quebrem páginas de suporte, integrei um portão automático de qualidade ao processo de compilação. O site ganhou um portão automático de qualidade no build. O portão ajuda a conferir a qualidade a cada build; as notas medidas não garantem o resultado de medições futuras. O roteiro detalhado de como configurei essa publicação na infraestrutura de borda está explicado no post sobre [migrar site para Cloudflare Workers](/blog/migrar-site-astro-cloudflare-workers). --- ## Publiquei 650 páginas contra a regra do meu método. URL: https://luisjunior.ai/blog/laboratorio-busca-650-paginas Publicado em 5 de novembro de 2026 · Inteligência artificial · Laboratório de busca, parte 1 Como publiquei cerca de 650 páginas do Pagenello de uma vez, o que o build encontrou e quando vou medir a indexação delas. ## O experimento contrariou a regra de publicação Publiquei cerca de 650 páginas de uma vez, contra a regra do meu próprio método. O Pagenello passou de 56 para 659 URLs em um dia. A pergunta é se portões fortes no build podem substituir a publicação em ondas. Organizei quatro padrões sobre 162 nichos. A produção foi dividida em 99 lotes de até 5 páginas, com 10 agentes por vez. Essa organização tornou possível distribuir o trabalho, mas a escala também expôs falhas que uma instrução sozinha não resolveu. O experimento ainda não responde se as páginas serão indexadas ou se vão receber visitas a partir das buscas. As leituras estão previstas para 15 de novembro, 29 de novembro e 27 de dezembro. Até a última leitura, a regra de ondas continua no método. ## O agente parou antes de concluir Com esforço baixo, um agente parou depois de três comandos. O trabalho precisou de uma instrução que pedisse a conclusão naquela execução e de esforço adequado à tarefa. Dividir um volume grande em lotes não elimina a necessidade de conferir a entrega de cada lote. A organização por nicho também ajudou na revisão: reunir as páginas de um mesmo nicho permite comparar afirmações e exemplos entre padrões. Uma página pode parecer coerente sozinha e ainda repetir ou contradizer outra página relacionada. Para cada página, a demanda precisa justificar uma resposta própria. Trocar apenas o nome de um nicho em um texto comum não entrega essa diferença. A escala depende da qualidade do material específico, além da quantidade de URLs. ## O build encontrou repetição e campos longos Quando o texto fixo do modelo cresceu, 8 páginas ficaram abaixo de 60% de texto exclusivo. A medição precisa olhar o HTML renderizado e comparar páginas de todos os padrões, porque o texto compartilhado também conta. As revisões alongaram textos e deixaram 143 campos fora do limite. A lição foi colocar o limite no build, em vez de depender apenas de uma instrução. Assim, uma revisão posterior não consegue passar despercebida só porque a primeira versão estava dentro da regra. Os fatos da oferta também precisam sair de uma fonte só. A revisão encontrou afirmações que não estavam sustentadas por essa fonte. Manter a origem dos fatos explícita facilita conferir o que cada página promete. ## Publicar exige conferir o que chegou ao ar Um deploy terminou sem publicar, e isso só apareceu quando conferi a versão no ar. O término do comando não bastou como evidência da publicação. A checagem da versão publicada entrou na lição do experimento. SEO programático usa dados e modelos para criar páginas destinadas a demandas distintas de busca. Para mim, o teste de qualidade começa antes da geração: preciso encontrar uma intenção que mereça uma página e ter material específico para respondê-la. Um dossiê por nicho reúne os termos, as necessidades e as fontes usados naquela página. O modelo organiza esse material, mas não deve acrescentar uma promessa que a fonte da oferta não sustenta. Se uma demonstração aparece na página, a descrição também precisa corresponder ao que ela mostra. A revisão por nicho atende a um risco que uma leitura isolada pode esconder. Ao colocar juntas as páginas relacionadas, fica mais fácil perceber quando uma afirmação muda de uma para outra ou quando a mesma passagem ocupa espaço demais. O portão automático mede repetição; a leitura procura problemas de sentido e de fato. Também preciso rodar o build completo depois de integrar os lotes. Uma página nova altera o conjunto contra o qual as outras são comparadas, então passar na conferência do próprio lote não encerra a revisão. O resultado consolidado é que mostra se as páginas ainda atendem ao limite quando estão juntas. Para quem pretende copiar o processo, eu registraria a demanda, a fonte dos fatos e os campos obrigatórios antes de produzir em escala. Em seguida, colocaria os limites verificáveis no build e reservaria uma conferência da versão publicada. A quantidade de páginas entregues não responde se elas serão encontradas ou úteis. As próximas leituras vão mostrar o que aconteceu com a indexação. Até lá, não trato a quantidade publicada como resultado de busca. O teste e a regra que continua em vigor fazem parte do [método FONTE](/blog/seo-aeo-geo-metodo-fonte). --- ## Uma conta para organizar erros, métricas e IA dos meus produtos. URL: https://luisjunior.ai/blog/sentry-posthog-openrouter-uma-conta Publicado em 5 de novembro de 2026 · Bastidores · Arrumando a casa, parte 15 O padrão para gerenciar erros, métricas de produto e chaves de inteligência artificial em múltiplos projetos usando uma única conta central e regras claras. Uma conta por serviço basta para organizar erros, métricas e chaves de IA dos meus produtos. Quando você constrói vários sistemas sozinho, a tentação inicial é criar contas e organizações isoladas para cada lançamento. Esse caminho parece organizado no primeiro dia, mas gera dispersão de acessos, configurações repetidas e perda de visão global. Como todos os produtos pertencem à mesma operação, uma única conta basta para cada serviço. A separação do que pertence a cada iniciativa não exige cadastros separados: ela fica clara na estrutura dos projetos, nas regras de nomenclatura e nas políticas de proteção. ## Uma organização central simplifica a governança de vários produtos Gerenciar uma conta para cada ideia cria atrito diário. Toda vez que um erro surge ou uma métrica precisa ser conferida, você precisa alternar acessos e verificar permissões diferentes. Além disso, configurações essenciais de segurança acabam esquecidas em ambientes abandonados. Ao centralizar a governança, mantenho uma organização no Sentry, uma no PostHog e um espaço de trabalho no provedor de modelos. Os créditos e os recursos contratados servem a toda a operação. A divisão do trabalho é transferida para identificadores padronizados e convenções seguidas à risca em cada repositório. Com esse padrão, um projeto novo começa com convenções de nome, ambiente e privacidade definidas. ## O padrão no Sentry separa superfícies e centraliza os alertas No Sentry, a estrutura foi padronizada com um projeto dedicado para cada superfície do produto. Adoto a nomenclatura composta pelo identificador do produto e a superfície correspondente, como no Garfim com os projetos garfim-api e garfim-native. Ambientes de teste e produção convivem no mesmo projeto. O SDK do Sentry envia a identificação do ambiente em cada evento, permitindo filtrar as ocorrências nas consultas sem duplicar a estrutura da plataforma. Cada projeto é vinculado ao respectivo repositório de código por meio da integração oficial do GitHub. Os alertas seguem o modelo padrão de problemas de alta prioridade, notificando por e-mail quando um erro inédito surge, quando uma falha antiga volta ou quando a frequência dispara. Para o envio de mapas de código, cada produto recebe um token exclusivo com a data de criação no nome. Esse identificador fica registrado apenas nas ferramentas de automação, nunca em arquivos versionados. Ao renovar a credencial, um novo token datado substitui o anterior, que é revogado. ## O PostHog isola dados de análise respeitando a privacidade A análise de produto no PostHog segue o mesmo princípio de organização única. Em vez de pulverizar cadastros, crio um projeto individual para cada iniciativa comercial. Os testes internos e o uso real também compartilham o mesmo espaço. A distinção entre eles ocorre pela origem da requisição e por filtros de contas de teste ativados por padrão em todos os relatórios. Isso impede que acessos de verificação distorçam os gráficos de retenção e navegação. No quesito privacidade, uma diretriz rigorosa orienta todas as configurações. A opção de descartar o endereço de IP dos visitantes permanece ativada em cada projeto desde a criação. As gravações de sessão só são autorizadas a capturar telas nos domínios oficiais do produto e ficam armazenadas pelo prazo máximo de 30 dias. O fuso horário de cada painel é ajustado conforme o mercado prioritário atendido pelo serviço. ## As chaves de inteligência artificial precisam de limite diário e sem expiração Para chamadas de modelos no OpenRouter, utilizo uma conta única com um saldo centralizado compartilhado. A segregação das credenciais segue um formato rigoroso: cada chave recebe o nome composto pelo produto e o ambiente, em letras minúsculas, diferenciando os contextos de homologação e produção. O desenvolvimento local usa respostas simuladas; scripts e avaliações que precisam do modelo real usam a chave de staging. A primeira regra das chaves é nunca definir prazo de validade. Uma credencial com data de expiração interrompe as funcionalidades inteligentes do aplicativo sem aviso prévio, muitas vezes fora do horário de trabalho. A troca de credenciais deve ser uma decisão manual e controlada, executada caso haja suspeita de vazamento. A segunda regra é o limite diário por chave, que reinicia à meia-noite no horário UTC. Esse teto de gasto fica acima do consumo habitual e funciona como trava de segurança: caso ocorra um laço de repetição acidental ou uma credencial fique exposta, a operação dos outros produtos continua protegida. Se a demanda legítima cresce, o limite daquele produto é ajustado conscientemente. ## A privacidade dos dados fica travada no código e no provedor A proteção das informações dos usuários não depende apenas de uma configuração genérica no painel. A regra de dados de cada produto fica no código, em cada chamada. Os produtos podem ter exigências de privacidade diferentes. Quando o produto promete retenção zero e seus modelos têm endpoints compatíveis, as chaves recebem um guardrail com o nome do produto. Essa configuração exige a mesma regra como segunda trava. A gravação de registros de entrada e saída fica totalmente desligada no espaço de trabalho. Assim, o workspace não grava prompts no OpenRouter. Uma credencial recém-gerada é exibida uma única vez, salva no gerenciador seguro e transferida como segredo da aplicação. Esses critérios transformaram a infraestrutura em um sistema previsível e fácil de manter. Para entender como essa mesma lógica de padronização orienta a infraestrutura de rede, leia sobre o [padrão de domínios na Cloudflare](/blog/padrao-de-dominios-cloudflare). --- ## Separei o painel do site e pus o Access na porta. URL: https://luisjunior.ai/blog/painel-administrativo-cloudflare-access Publicado em 5 de novembro de 2026 · Desenvolvimento · Arrumando a casa, parte 14 Um script injetado no site público alcançava o painel pela sessão do operador. Separei o painel em app e endereço próprios, atrás do Access. A sessão do operador valia em todas as páginas do site público. Um script injetado em qualquer página alcançaria o painel com essa sessão. Eu separei o painel do site e coloquei o Cloudflare Access na frente dele. O risco morava na origem compartilhada. Origem é o endereço que o navegador usa para decidir quais páginas dividem a mesma sessão. Página pública e painel na mesma origem dividem alcance de cookie. ## A origem pública carrega scripts que eu controlo só em parte As páginas públicas carregam pixel, tag e scripts de terceiros. Cada script roda no contexto da página que o visitante abriu. Uma falha de injeção em uma página pública abre caminho para chamadas feitas com a sessão de quem estiver logado. A sessão do operador valia para todas as páginas dessa origem. Um script injetado chamaria as rotas do painel usando a sessão válida. A proteção que impede a leitura do cookie pela página continua permitindo o uso dele nas chamadas. Esse desenho fazia a segurança do painel depender de todas as páginas públicas. Cada página nova e cada script novo aumentavam a superfície de ataque do painel. O painel pagava o risco de um site feito para receber visita e medir campanha. Nada ficava entre a internet e a tela de login do painel além do próprio aplicativo. Qualquer pessoa podia abrir a tela e tentar entrar. A lista de operadores e o código de e-mail carregavam sozinhos a defesa da entrada. ## O painel virou um app próprio em endereço próprio A saída foi tirar o painel de dentro do site. O painel virou um app próprio, com rotas e tratamento de sessão dele. O site público voltou a cuidar das páginas públicas e das tarefas dele. O app do painel roda em endereço próprio, separado do endereço do site. A sessão do operador pertence só a esse endereço. Página pública aberta no mesmo navegador fica fora do alcance dessa sessão. No Garfim, essa separação corrigiu um problema concreto de arquitetura. O painel tinha virado uma ilha dentro do site e repetia, de forma manual, o que o modelo de app já entregava pronto. App próprio resolveu a segurança e a manutenção na mesma mudança. Um script plantado na página pública ainda pode tentar criar um cookie falso com o nome da sessão. Esse cookie chega ao painel como uma sessão inventada. A conferência de identidade barra a tentativa, e o efeito máximo é um painel deslogado. ## O Access fecha a porta antes da tela de login O Cloudflare Access fica na frente de todo o endereço do painel. Ele roda na borda da Cloudflare, antes de o pedido chegar ao app. Quem fica fora da lista de operadores nem enxerga a tela de login. O operador entra em duas etapas separadas. Primeiro ele passa pelo Access com o código enviado a ele. Depois ele entra no painel com o login dele e o segundo fator. O segundo fator amarra a entrada a algo além do código enviado por e-mail. No modelo que adotei, o painel pede código de uso único gerado no aparelho do operador. A API confere tudo de novo a cada chamada do painel. Ela verifica a origem da chamada, a passagem pelo Access e a sessão do operador. Falta de configuração de conferência fecha o painel em vez de liberar a entrada. Três produtos meus usam esse mesmo modelo de painel. O webmail central também fica atrás do Access. A repetição facilita a operação, porque cada painel novo nasce com a mesma porta de entrada. ## O limite do modelo aparece fora do navegador Apps nativos não passam pelo Access. O aplicativo de celular fala direto com a API, sem atravessar a porta que protege o painel no navegador. A proteção do painel cobre a operação no computador e deixa o app com as regras próprias dele. Por isso a API mantém as conferências dela para todas as chamadas. Access fechado no painel e API aberta em outro caminho anulariam a separação. Cada caminho de entrada precisa da própria verificação de identidade e permissão. Também existe um atrito de operação nessa escolha. O operador entra duas vezes, uma no Access e outra no painel. Cada ambiente novo pede a configuração do Access antes da publicação da API, sob risco de painel trancado. Eu aceito esse atrito porque ele aparece uma vez na entrada. O risco anterior aparecia em todas as páginas públicas, todos os dias. Trocar risco permanente por atrito de login foi a conta que fechou a decisão. ## Painel separado virou o padrão dos meus produtos Hoje cada produto novo já nasce com o painel fora do site público. App próprio, endereço próprio e Access na frente formam o ponto de partida. O site público pode mudar de campanha e de script sem arrastar o painel junto. A lição serve para qualquer operação com área restrita. Junte no mesmo endereço só o que pode dividir a mesma sessão com segurança. Página com script de terceiros e painel de operação pedem endereços separados. Quem mantém painel dentro do site pode começar pelo inventário de scripts das páginas públicas. Cada pixel e cada tag listados respondem pela urgência da separação. Depois da separação, o [deploy a partir da minha máquina](/blog/publicar-da-minha-maquina-ci-cd) publica site e painel como peças independentes, cada uma com a própria conferência. --- ## Uma lista de 69 itens encontrou requisitos só no papel. URL: https://luisjunior.ai/blog/padrao-entre-produtos-69-itens Publicado em 5 de novembro de 2026 · Bastidores · Arrumando a casa, parte 13 Como uso estados, evidências e divergências registradas para alinhar 69 itens entre produtos sem apagar o que cada um exige. ## O que se repete merece uma decisão comum Na continuação de [arrumar a casa em 48 horas](/blog/arrumando-a-casa-48-horas), conferi 69 itens de alinhamento e encontrei requisitos que só existiam no papel. Provedores, banco, e-mail, release, observabilidade, backoffice, nomes de recursos e documentação de operação entram nessa conversa. Uma decisão comum reduz a necessidade de redescobrir o mesmo caminho a cada produto. Ela também torna mais fácil comparar o que foi documentado com o que está em operação. O Garfim serve de referência, e onde outro produto já corrigiu a referência, vale a versão corrigida. Isso não obriga produtos diferentes a terem a mesma resposta para tudo. Mercado, lei, meio de pagamento ou plataforma podem exigir outra escolha. Nesses casos, registro a divergência e o motivo, para que ela continue compreensível depois. ## O estado precisa apontar para uma evidência No alinhamento de um produto que ainda não apresentei aqui, a lista tinha 69 itens. Desses, 61 estavam feitos, 2 faltavam e 6 não se aplicavam. A contagem ajuda a enxergar o andamento, mas cada linha precisa dizer por que recebeu aquele estado. Um item feito aponta para o arquivo que demonstra a implementação. Um item que não se aplica traz o motivo. Um item pendente permanece visível até que o trabalho correspondente seja concluído. Essa diferença importa porque um documento pode registrar uma intenção sem mostrar que ela foi implementada. Conferir o arquivo associado aproxima a lista do comportamento real do produto. ## A revisão também encontrou o que não estava na lista A rodada encontrou requisitos que existiam apenas no papel. Uma checagem de segredos exigida no CI não estava presente, e quatro alertas previstos também não existiam. Em outro achado, erros de uma interface de chamadas não chegavam ao Sentry. Esses casos não estavam resolvidos simplesmente por constarem em requisitos. A revisão precisou procurar a evidência e comparar a expectativa com a operação. O resultado foi ampliar o olhar para além dos itens previstos originalmente. Uma lista ajuda a organizar a conferência, mas não define tudo o que a conferência pode descobrir. Os achados alimentam decisões posteriores e dão mais contexto para revisar o padrão usado como referência. ## A divergência registrada conserva o contexto Quando um produto pede uma escolha diferente, eu quero conseguir reencontrar a razão. A plataforma pode impor uma condição própria, ou uma lei pode mudar o que se aplica. O registro evita tratar diferenças necessárias como esquecimentos. O mesmo cuidado vale quando a referência melhora. Se outro produto já corrigiu um ponto do Garfim, reproduzir a versão antiga preservaria o problema. A referência útil é a que incorpora a correção. Observabilidade é a capacidade de acompanhar o comportamento de um sistema por sinais como erros e alertas. Padronizar essa parte ajuda quando preciso investigar um produto: sei onde procurar e posso perceber uma configuração ausente antes de depender dela. A mesma lógica se aplica ao release. Se cada produto tiver um procedimento comum documentado, a conferência começa por uma expectativa conhecida. O arquivo que comprova o item continua necessário, porque uma regra escrita no contexto central não altera por conta própria o repositório de cada produto. Eu separo a decisão comum da situação de cada implementação. A primeira diz qual caminho seguir; a segunda mostra se aquele produto já o percorreu. Essa separação impede que uma lista de padrões pareça um retrato de trabalho concluído em todos os lugares. Para copiar a abordagem, eu começaria pelas categorias que se repetem e criaria uma linha por decisão conferível. Em cada linha, registraria o estado e o local da evidência. Quando uma regra não couber, escreveria o motivo junto dela, de forma que outra revisão consiga distinguir uma exceção deliberada de uma tarefa esquecida. A revisão precisa abrir espaço para descobertas fora da lista. Nos achados de alertas e da checagem de segredos, por exemplo, a pergunta era se o requisito previsto existia na operação. Olhar apenas para a contagem de itens não teria respondido a isso. A lista organiza o exame; a evidência sustenta o estado atribuído. A lista de 69 itens deixou um retrato com pendências explícitas e evidências para conferência. Para outro exemplo de padrão acompanhado de riscos e critérios de revisão, contei como passei a [publicar da minha máquina](/blog/publicar-da-minha-maquina-ci-cd). --- ## O antispam esperou tanto que parou o formulário. URL: https://luisjunior.ai/blog/turnstile-barrando-visitante Publicado em 5 de novembro de 2026 · Desenvolvimento · Arrumando a casa, parte 12 Como defini o que bloquear quando o Turnstile falha, o que deixar passar e o que registrar para manter a captura disponível. ## O desafio também pode impedir a captura Quando o Turnstile demorava para responder, o formulário parava de receber e-mails. Em um produto que ainda não apresentei aqui, a captura esperava até 10 s pelo token, mas não havia prazo para o carregamento do próprio script. Se esse carregamento falhasse, a falha ficava guardada pela sessão inteira. A API tratava o token vazio como uma checagem reprovada. Com `challenges.cloudflare.com` lento ou bloqueado, a captura parava, embora o requisito do produto determinasse que ela deveria deixar passar nessa situação. Isso criou uma diferença entre o comportamento desejado e o que o visitante encontrava. A proteção estava na frente do formulário, mas a indisponibilidade do serviço recebia o mesmo tratamento de uma rejeição. ## Um prazo cobre o script e o token A correção colocou um prazo único de 5 s para o carregamento do script e a obtenção do token. Uma falha deixa de ficar presa pela sessão: na chamada seguinte, o processo pode tentar novamente. O widget só aparece quando a Cloudflare pede interação. No servidor, token vazio passa a significar serviço indisponível. Nesse caso, a API não chama o siteverify e registra `no_token` no log. A passagem consome uma unidade extra do limite por IP como compensação. Token presente e rejeitado segue bloqueado, com mensagem própria. Essa distinção deixa explícito o que eu permito quando a proteção não responde e o que continuo recusando quando ela responde com uma rejeição. ## Os testes precisam de uma resposta prevista Em outro produto, a suíte de navegador no CI não tinha chave do site. O fluxo de visitante esperava pelo Turnstile, três fluxos chegaram ao timeout e a suíte bateu em 30 minutos. A solução foi usar as chaves de teste do Turnstile. O caso mostra que o ambiente de teste precisa contemplar o serviço do qual o fluxo depende. Sem uma resposta prevista para ele, a espera de um componente pode transformar três fluxos em uma suíte parada. Nesse mesmo produto, o limite por IP também deixa passar se o serviço de contagem falha ou demora 2 s. O erro é registrado, porque login e análise precisam continuar disponíveis. ## Cada produto escolhe a proteção que precisa No Pagenello, o formulário combina Turnstile, limite por IP e proteção contra duplicados. Nos dois sites que são apenas estáticos, não há Turnstile porque não há formulário. A escolha acompanha o fluxo que precisa de proteção. O token é a resposta que o formulário recebe para levar a verificação ao servidor. Se ele não chega, o servidor precisa saber distinguir essa ausência de uma resposta que chegou e foi recusada. Essa separação define o comportamento do formulário quando a dependência está indisponível. O prazo único cobre o caminho inteiro até a resposta. Limitar apenas a espera pelo token deixava uma etapa anterior sem limite, de modo que o visitante ainda podia ficar preso antes de chegar à verificação. Ao reunir as duas esperas, a decisão de seguir não depende de descobrir em qual parte o carregamento parou. A nova tentativa na chamada seguinte também evita transformar uma falha temporária em uma condição permanente da sessão. Se o serviço voltar a responder, o próximo envio pode usar a proteção novamente. Enquanto isso, o registro de `no_token` deixa uma pista sobre a passagem sem token. Eu copiaria a decisão como uma pequena tabela de comportamentos: ausência de resposta, resposta rejeitada e resposta aceita. Para cada situação, escreveria o que o visitante vê, se a API continua e qual registro fica disponível. Depois conferiria o fluxo com o serviço lento ou indisponível, além do caminho em que ele responde. A compensação no limite por IP faz parte da escolha de deixar passar. Ela não transforma a ausência do token em uma verificação bem-sucedida; acrescenta uma restrição ao fluxo que continua. A mensagem própria para uma rejeição mantém esse caso separado para quem usa o formulário. O registro de `no_token` permite separar depois as passagens sem token das respostas rejeitadas. Essa lição apareceu em cada produto e ainda não é um padrão escrito entre eles. O critério que uso ao examinar uma falha é definir o que fica barrado, o que pode passar e o que compensa essa passagem. Em [publicar da minha máquina](/blog/publicar-da-minha-maquina-ci-cd), conto outra decisão em que explicitei os riscos aceitos. --- ## Cortei a publicação de 17 minutos para 4 na minha máquina. URL: https://luisjunior.ai/blog/publicar-da-minha-maquina-ci-cd Publicado em 5 de novembro de 2026 · Desenvolvimento · Arrumando a casa, parte 11 Como medi o gargalo do build, passei a publicar da minha máquina com gate e ship e mantive uma rede curta no GitHub Actions. ## A espera revelou o lugar errado para otimizar Em novembro, o GitHub Actions acumulou 2.945 minutos no mês, sendo 2.244 em um único dia. Nas 12 falhas mais recentes de um produto que ainda não apresentei aqui, 7 aconteceram no deploy e 4 em checagens de código. Eu estava esperando uma máquina remota repetir trabalho que a minha podia provar. Antes de mudar o processo, medi as partes do build. Eu suspeitava dos idiomas, que levavam 42 s em paralelo. O gargalo real eram 1.826 imagens refeitas a cada build, em 230 s. A diferença orientou a correção: reaproveitar trabalho quando aquilo que o determina não mudou e executar tarefas independentes em paralelo. Sem essa medição, eu poderia otimizar os idiomas e deixar o trecho mais demorado no mesmo lugar. ## O gate prova e o ship publica O comando `bun gate` executa a suíte em uma cópia limpa do commit. O resultado fica associado à árvore comprovada, e o `pre-push` chama o gate. Assim, a mesma árvore não precisa ser provada novamente. O `bun ship` publica a partir de uma cópia limpa da ponta da `main`, com uma trava para evitar publicações concorrentes. Ele começa por staging, confere o resultado e só então avança para produção. Se uma tentativa falha, outra pode retomar sem repetir o ambiente que já está naquela revisão. Também há recusas explícitas: uma pasta com alterações soltas não publica, um script de release chamado diretamente é recusado e uma revisão mais antiga que a publicada não passa. Essas condições mantêm a velocidade ligada a uma revisão identificável. ## O GitHub continua como rede de proteção No push, o GitHub verifica segredos, formato e lint em cerca de 1 minuto. Trabalhos que precisam rodar com o Mac desligado continuam lá, assim como aqueles que exigem outra arquitetura ou assinatura de loja. O teste de ponta a ponta roda localmente antes da publicação que pode afetá-lo. Na medição de 4 de novembro, a publicação de staging e produção passou de 17m39s, além da fila, para 4m29s na máquina. Quando o teste de ponta a ponta precisa rodar, o processo local leva cerca de 3 minutos a mais. O Garfim ainda falta migrar. A regra é um padrão de trabalho, e cada produto precisa ter sua implementação adequada ao próprio repositório. ## A decisão aceita riscos e tem prazo de revisão Com o Mac desligado ou quebrado, a publicação de código para, e o agendado continua. A recuperação é qualquer máquina com o checkout e as credenciais. Uma sessão de agente nessa máquina consegue publicar em produção; a proteção depende do portão e da regra de publicar quando pedido, sem uma barreira técnica para essa autorização. O build também roda em macOS, enquanto a publicação precisa funcionar no ambiente de destino. O teste de staging e a conferência do resultado publicado ajudam a encontrar diferenças. Quando um segundo desenvolvedor entrar no repositório, vou reabrir a decisão: minha máquina deixa de ser passagem obrigatória para todo commit. CI/CD reúne as verificações e as etapas que levam uma alteração até a publicação. Para escolher onde cada etapa roda, eu primeiro preciso saber o que ela protege e se realmente depende de uma máquina remota. A cópia limpa é parte dessa resposta. Ela impede que um arquivo alterado apenas na pasta de trabalho entre na prova ou na publicação por acidente. Quando o resultado do gate fica ligado à árvore conferida, posso identificar exatamente o que passou pelas verificações. O staging também tem uma função específica: receber a revisão antes de produção para que eu confira o resultado no ambiente publicado. Retomar a partir do ambiente que já recebeu aquela revisão evita repetir trabalho sem perder a identificação do que está no ar. Para aplicar essa ideia em outro projeto, eu começaria anotando o tempo de cada parte, a fila e o destino das falhas recentes. Depois separaria as verificações que a máquina local consegue executar das tarefas que precisam do GitHub ligado quando o computador estiver desligado. A comparação precisa acompanhar a publicação inteira, não só o comando de build. A regra de revisão com outro desenvolvedor também faz parte do desenho. Uma solução adequada para uma pessoa pode concentrar demais o processo quando há mais gente trabalhando. Registrar essa condição agora evita confundir a decisão atual com uma regra permanente. A economia de espera veio de medir o caminho inteiro e assumir com clareza o que mudou. A conferência depois da publicação também fez parte da [migração do meu site](/blog/migrar-site-astro-cloudflare-workers). --- ## Eu gravo. A IA corta, legenda e entrega o vídeo curto. URL: https://luisjunior.ai/blog/edicao-de-video-com-ia Publicado em 5 de novembro de 2026 · Inteligência artificial · Como trabalho com IA, parte 4 Eu gravo uma vez e a IA corta pausas, acerta legendas e normaliza a voz com regras fixas. Veja o passo a passo que uso nos vídeos curtos. Eu gravo uma vez e entrego a gravação bruta para a IA editar. Ela corta, legenda, exporta e confere o vídeo antes de me devolver. Dois vídeos saíram assim, em 1 e 3 de novembro. A divisão de trabalho aproveita o que cada lado faz melhor. Eu falo para a câmera com a minha voz e o meu ritmo. A IA repete a parte mecânica com a mesma regra em todos os cortes. ## O corte começa na primeira palavra e tira o ar morto O vídeo começa na primeira palavra da frase que prende. Respiração inicial e palavras de aquecimento ficam fora da versão final. Quando a melhor frase está no meio da gravação, ela abre o vídeo, desde que o sentido continue claro. Pausas acima de 0,35 s saem do vídeo. A transcrição marca onde cada palavra começa e termina, e os cortes deixam 0,12 s de folga antes e depois da fala. O resultado mantém o ritmo de conversa sem buracos entre as frases. Erros e recomeços também saem na edição. Fica a última versão completa de cada frase, porque eu costumo acertar a frase na última tentativa. O corte acontece no fim da palavra, nunca no meio dela. O corte seco é o padrão do vídeo curto. Os pulos de enquadramento entre um trecho e outro fazem parte do estilo. A atenção fica na fala, e cada segundo entrega uma ideia nova. ## O enquadramento mantém o rosto inteiro em todos os trechos Os olhos ficam perto de um terço da altura, contando a partir do topo. O rosto fica inteiro no quadro em todos os trechos do vídeo. Quando eu me movo durante a gravação, o recorte acompanha a posição em cada trecho. A gravação horizontal vira vídeo vertical em 9:16 com recorte definido por trecho. Um zoom de 1,15 a 1,3 em trechos alternados quebra a monotonia de uma câmera só. A variação aparece sem efeito chamativo e sem distrair da fala. Antes da entrega, uma folha de quadros confere o enquadramento. Cada quadro precisa mostrar o rosto inteiro e bem posicionado. Legenda cobrindo a boca ou rosto cortado devolve o vídeo para ajuste. ## A legenda acompanha a palavra falada em blocos curtos A legenda aparece palavra a palavra, com a palavra falada em destaque. Cada bloco tem até 3 palavras e no máximo 2 linhas. Bloco curto acompanha o ritmo da fala e cabe na tela do celular. O centro da legenda fica a 70% da altura do quadro. Essa posição fica acima da área de descrição e dos botões das plataformas. A leitura acontece sem disputa com os elementos da tela. O texto da legenda confere com a fala antes da entrega. Nomes próprios, marcas e termos técnicos passam por correção dedicada. Palavra trocada na transcrição automática entra na lista de correções do vídeo. A voz fica em -14 LUFS, com pico de -1,5 dB. Essa é a referência das plataformas de vídeo curto. Música, quando ajuda, entra de 0,08 a 0,15 de volume sob a voz e sem letra competindo com a fala. ## O texto de publicação vende o vídeo antes do play O trabalho de marketing continua depois da edição. O texto de cada post existe para ganhar audiência e vender. Ele nunca reporta o conteúdo do vídeo em tom de notícia. A frase "Neste vídeo eu falo sobre..." é proibida nos meus textos. A primeira linha precisa parar a rolagem de quem ainda não deu o play. Curiosidade, contraste, promessa e provocação cumprem esse papel. Cada texto traz um motivo para ficar até o fim do vídeo. A promessa que o vídeo cumpre e um número concreto seguram a atenção. O texto fecha com uma chamada só, ligada ao objetivo de cada publicação. O mesmo arquivo 9:16 vai para YouTube, Instagram, TikTok, LinkedIn, X e Facebook. As hashtags são do assunto, de 3 a 5 por post. Termo genérico de alcance fica fora da lista. ## A conferência final reprova o vídeo antes de publicar A entrega passa por uma conferência em cinco frentes. A folha de quadros confere rosto e legenda. A transcrição confere cortes, ordem das palavras e pausas restantes. A legenda passa por comparação com a fala, incluindo nomes e números. Duração e formatos conferem com o pedido de cada vídeo. O conteúdo passa pela regra de privacidade que separa assunto público de assunto interno. O que reprova em qualquer frente volta para a edição antes da entrega. Só depois dessa volta o vídeo segue para publicação. A regra vale igual para vídeo gravado por mim e para roteiro escrito pela IA e gravado por mim. Ainda não há métrica por vídeo para dizer qual regra entrega mais resultado. Dois vídeos publicados contam pouco para separar acerto de acaso. Eu mantenho as regras pela clareza do processo e confiro cada entrega pelo mesmo roteiro. Quem grava vídeo curto pode copiar a divisão hoje mesmo. Grave com tomada numerada, repita a frase inteira quando errar e entregue o bruto com as seis regras de corte e legenda. O princípio é o mesmo de [quando a IA disse que usou as skills](/blog/ia-disse-que-usou-as-skills): ter uma regra objetiva para cada conferência em vez de aprovar no olho. --- ## Como criar anúncios UGC com IA usando o método PROVA. URL: https://luisjunior.ai/blog/metodo-prova-ugc-por-ia Publicado em 5 de novembro de 2026 · Inteligência artificial · Como trabalho com IA, parte 3 As cinco batidas do método PROVA, o teste do corte e os dados que favorecem demonstrar o produto em anúncios curtos com IA. A maioria das pessoas assiste a apenas 3 a 5 segundos de um anúncio. Pesquisei esse comportamento para organizar roteiros UGC para TikTok, Reels, Shorts e o feed da Meta. Para resolver esse abandono, criei o método PROVA. Ele distribui os 30 segundos do vídeo em cinco batidas objetivas e estabelece um limite claro para o que pode ser gerado. ## A retenção média impõe mostrar o produto nos primeiros segundos A maioria das pessoas não assiste a um anúncio até o fim. Numa amostra de 421 vídeos da Meta analisada pela Biddy Co em 5 de outubro de 2026, com dados de julho a outubro de 2026, o tempo médio de exibição ficou entre 3 e 5 segundos em qualquer duração total. Apenas cerca de 2% das impressões chegaram ao encerramento de um vídeo de 16 a 30 segundos. Guardar o produto para os segundos finais significa falar sozinho. Um estudo da Vidmob com o TikTok em 2023, cobrindo 1.678 anúncios, apontou que falar para a câmera rendeu 14% mais visualizações de 2 segundos, enquanto abrir só com o logotipo reduziu as visualizações de 6 segundos em 14%. A documentação do TikTok de 2020 indicou que mais de 63% dos vídeos com maior taxa de clique mostravam a mensagem ou o produto logo nos 3 primeiros segundos. Quem espera o momento ideal para exibir o que vende perde quem decide rolar a tela no quarto segundo. O primeiro quadro precisa segurar a atenção e situar o comprador de imediato. ## O método PROVA organiza o roteiro em cinco batidas O roteiro de 30 segundos divide o tempo em cinco etapas: 1. Pare (0 a 1 s): primeiro quadro com movimento imediato, com pessoas ou o produto em ação, e texto na tela para quem assiste sem som. 2. Reconhecimento (1 a 3 s): gancho falado e escrito que conecta com a dor do comprador em uma única frase. 3. Objeto (3 a 6 s): o produto entra em cena cumprindo o que promete, associado ao benefício principal. 4. Ver funcionando (6 a 25 s): demonstração prática com resultado concreto, resposta a uma objeção comum e repetição do produto em uso. 5. Ação (últimos 3 a 5 s): oferta explícita e chamada direta, faladas e escritas. Num exemplo de aplicativo de faturas para freelancers, a abertura pode mostrar a situação de cobrar o mesmo cliente outra vez. No terceiro segundo, entra a tela real do aplicativo gerando a fatura em dois toques. Em seguida, a gravação exibe o envio do lembrete automático e a personalização da mensagem. O encerramento apresenta a oferta e indica o link. O fluxo serve também para itens físicos, como um peitoral para cães que puxam a guia. O vídeo abre na guia esticada, mostra o produto real na mão na batida seguinte, demonstra o giro suave do animal ao puxar e conclui com a chamada. ## Demonstrar na prática traz mais resultado do que agitar a dor Modelos tradicionais de redação costumam gastar metade do tempo ampliando o problema do cliente. Os dados favorecem a demonstração em relação à agitação da dor, embora não provem o resultado de cada anúncio. No estudo da Motion e Runneth de 2026, com 578.750 criativos da Meta entre setembro de 2025 e janeiro de 2026, a abertura de caixa teve taxa de acerto de 9,8% e a demonstração alcançou 8,1%. Nesse estudo, acerto significa gastar 10 vezes a mediana da conta. Já os anúncios focados em agitação da dor ficaram perto de 5%. Em aplicativos sociais, um levantamento da AppsFlyer de 29 de abril de 2025, com 1,1 milhão de criativos, mostrou que tutoriais e resenhas geraram 45% mais instalações por mil impressões que depoimentos. A pesquisa da Meta com a Toluna em 2 de dezembro de 2025 reforçou esse padrão em cerca de 100 anúncios. Explicar um diferencial funcional aumentou em 5,3 vezes a chance de ficar no topo em intenção de compra. Mostrar o produto mais de uma vez elevou essa chance em 2,7 vezes, enquanto aliar fala e música gerou um ganho de 2,1 vezes. A dor cabe na frase do gancho. O tempo restante trabalha a favor da prova prática. ## O teste do corte verifica o que cada trecho comunica Como poucos espectadores chegam ao desfecho, cada trecho precisa vender por conta própria. Antes da produção, avalio o roteiro cortado em três momentos: - Aos 3 segundos: quem para aqui precisa saber para quem o anúncio foi feito e qual problema ele aborda. - Aos 6 segundos: quem abandona o vídeo já deve ter visto o produto e compreendido sua função. - Aos 15 segundos: quem assiste até a metade precisa ter acompanhado o funcionamento real com resultado claro. Se o vídeo for interrompido em qualquer um desses pontos sem passar essa clareza, o roteiro deve ser reescrito. Esse critério impede que a compreensão dependa da boa vontade do usuário. ## A regra de ouro separa o elenco sintético da prova real Ao produzir anúncios com inteligência artificial, mantenho uma fronteira rigorosa: a pessoa em cena pode ser sintética, mas o produto, a tela e a prova são sempre reais. O personagem gerado atua como apresentador, encena a situação ou introduz o problema. Ele nunca finge ser um cliente autêntico relatando uma experiência que não viveu. A interface do aplicativo deve ser capturada do sistema em funcionamento, e a demonstração de um produto físico precisa partir de imagens autênticas do item. Essa regra mantém a demonstração apoiada em produto e prova reais. Para ver como organizo a revisão de imagens geradas, confira [como a IA me apresenta mídias para aprovação](/blog/como-a-ia-me-apresenta-midias-para-aprovacao). --- ## A IA disse que usou as skills. A página provou o contrário. URL: https://luisjunior.ai/blog/ia-disse-que-usou-as-skills Publicado em 5 de novembro de 2026 · Inteligência artificial · Como trabalho com IA, parte 2 A IA afirmou que aplicou as skills e entregou uma página reprovada. Aprenda a conferir o que foi aberto, executado e deixado de fora. A IA escreveu que tinha usado as skills a fundo e entregou uma página reprovada como "slop". Ela tinha carregado as skills na conversa. Na hora de aplicar o método de cada uma, as instruções foram deixadas de lado. Eu trabalho com arquivos de instrução que guardam um método já testado. Cada skill tem um arquivo principal e referências para casos concretos. Abrir só o começo e seguir por conta própria produz um texto confiante sobre um trabalho que nunca aconteceu. ## A página reprovada mostrou que o relatório estava errado Numa rodada de páginas para um produto que ainda não apresentei aqui, pedi o uso de skills nomeadas. A resposta veio completa, com a afirmação de uso profundo de cada uma. A página entregue foi reprovada como "slop", palavra que uso para página genérica e sem identidade. Diante da reprovação, fiz uma pergunta curta: "das skills que citei, quais delas você usou?" A resposta revelou o que tinha acontecido. As skills tinham sido carregadas e citadas, mas o método delas não tinha guiado as decisões da página. Esse episódio deixou uma lição simples para quem delega trabalho à IA. O relatório descreve uma intenção e apresenta essa intenção como fato. A conferência precisa sair do relatório e ir para a evidência de abertura de arquivos. Minha resposta na hora foi direta: "ou usa a skill e me diz que deu algum problema, ou se negue a fazer, mas não faça algo do qual eu não pedi, dizendo que foi o que eu pedi." A frase continua valendo como regra de trabalho. Problema declarado permite correção, e recusa declarada permite outro caminho. ## O mesmo erro já tinha aparecido nos anúncios do Pagenello Antes dessa rodada de páginas, a primeira rodada de anúncios do Pagenello seguiu o mesmo roteiro. As skills foram citadas no trabalho. Na prática, só os arquivos principais de `ads`, `ad-creative` e `video` foram lidos. As referências ligadas a esses arquivos ficaram fechadas. O resultado foi um criativo que só descrevia a oferta. Faltava o trabalho que as referências mandavam fazer antes da peça final. Verifiquei isso nas transcrições em 31 de outubro. A transcrição guarda a sequência real de aberturas e comandos da sessão. Ela mostra a diferença entre citar uma skill e percorrer o material que ela aponta. Quem lê só o arquivo principal recebe o resumo do método. As decisões que mudam o resultado costumam morar nas referências. Uma oferta descrita em linguagem correta continua fraca quando a etapa anterior de pesquisa e escolha ficou sem leitura. ## Usar uma skill significa abrir o arquivo e as referências A regra que ficou depois dos dois episódios tem três partes ligadas. Usar a skill é abrir o arquivo dela. Usar a skill também é abrir as referências do caso concreto. Depois das duas aberturas, o método precisa aparecer nas escolhas do trabalho entregue. Registros e commits passaram a citar só as skills de fato abertas. Citação virou registro de leitura, com lastro na transcrição. Skill fechada fica fora do registro, mesmo quando o tema dela combina com a tarefa. O relatório final separa o que foi lido, o que foi executado e o que não foi aberto, com contagem. Essa separação está no critério de relatório fiel do meu manual de sites. O mesmo manual lembra que dizer que usou uma skill ou conferiu uma tela exige ter feito as duas coisas. Os meus manuais também têm portões automáticos para conferir o resultado, como o manual de UGC. Portão automático confere arquivo entregue e aponta defeito visível. A prova de leitura continua na lista de aberturas e na transcrição da sessão. ## Três conferências pegam o relatório inventado A primeira conferência é a pergunta direta sobre os arquivos abertos. Peça nome de arquivo, referência lida e ponto do método aplicado. Resposta vaga sobre uso profundo indica leitura rasa. A segunda conferência é a leitura da transcrição. Compare a lista declarada com as aberturas registradas na sessão. Arquivo ausente da transcrição ficou fechado, por mais que o relatório afirme o contrário. A terceira conferência é a contagem no relatório. Lidos, executados e não abertos aparecem em grupos separados, cada grupo com o seu total. A contagem obriga a declarar o tamanho da parte que faltou. Essas conferências custam poucos minutos e poupam uma rodada inteira de retrabalho. Página reprovada e anúncio fraco cobram mais tempo do que a pergunta sobre arquivos. A pergunta entra antes da aprovação e muda a conversa de confiança para prova. ## Eu passei a aprovar o trabalho pela evidência de leitura Hoje eu peço a lista de aberturas junto com a entrega. A entrega vem com o método visível no resultado e com as ausências declaradas. Ausência declarada vira tarefa seguinte ou recusa clara. Esse cuidado vale para qualquer tarefa com instrução arquivada. Site, anúncio, vídeo e código seguem a mesma lógica de conferência. O nome da skill no relatório perdeu valor, e a abertura registrada ganhou o lugar dele. O ganho aparece na qualidade da rodada seguinte. Quem abriu as referências discute escolhas concretas e aponta trechos do método. Quem só citou arquivos repete a afirmação inicial com outras palavras. Se você trabalha com IA todos os dias, copie a pergunta que destravou o meu caso. Pergunte quais arquivos foram abertos e peça a contagem de lidos, executados e não abertos. Depois leia o método aplicado no resultado, como fiz ao separar a [página com identidade](/blog/metodo-mundo-site-com-identidade) das páginas reprovadas. --- ## Nove páginas reprovadas antes de encontrar uma identidade. URL: https://luisjunior.ai/blog/metodo-mundo-site-com-identidade Publicado em 5 de novembro de 2026 · Inteligência artificial · Como trabalho com IA, parte 1 Como usei uma régua, regras e arte própria para criar uma identidade de site com IA e o que a medição ainda não consegue provar. ## A régua veio antes da página aprovada Em um redesenho, fiz quatro rodadas em cerca de 1h30 e reprovei nove páginas. A primeira rodada aprovada foi também a primeira em que medi a régua e escrevi as regras antes de montar a página. Nas anteriores, eu tinha partido de conceitos e referências sem fazer esse trabalho. Isso não prova que uma etapa isolada causou a aprovação. Também corrigi o rumo durante as rodadas. A lição que o caso sustenta é a ordem: medir a régua e escrever as regras antes de pedir a página. A régua começa com sites reais que definem o nível desejado. Eu abro, meço e observo o que dá identidade a cada um. Essa leitura deixa explícito o que estou tentando alcançar antes de pedir à IA uma página. ## Uma ideia precisa virar regras Chamei o processo de MUNDO. A primeira etapa, Medir a régua, transforma referências em diagnóstico. A segunda, Uma ideia, procura uma direção ligada ao conflito de quem compra e a resume em uma frase. A terceira etapa é Normas: escrevo uma folha com decisões verificáveis para a identidade. A quarta é Desenho, quando encomendo a arte e monto uma página inteira. A quinta é Olhar: comparo a página com a régua, passo os portões e corrijo o que encontrei. A ordem protege a ideia de se perder no meio da execução. A folha de regras dá à IA e a mim um critério para julgar uma escolha, em vez de decidir cada trecho como se fosse um projeto separado. ## O título acendeu um alarme mensurável Medi 14 páginas. Nas 5 aprovadas, o título tinha peso de 600 ou mais e espaçamento de -3,5% ou mais apertado. Nenhuma das 9 reprovadas tinha essa combinação. A amostra é pequena, e ajustei a regra depois de ver os dados. Por isso, uso o resultado como alarme: ele chama atenção para uma possível fraqueza, mas passar no teste não torna uma página boa. Também ainda não medi conversão. A conferência visual continua necessária. Uma página pode passar por uma checagem mecânica e ser reprovada na comparação com a régua. As duas leituras respondem a coisas diferentes e ajudam a corrigir problemas diferentes. ## A arte tem uma fronteira com os fatos O cenário pode ser gerado. O produto, o número e a prova são reais. Essa é a regra que uso para que uma imagem criada para a identidade não invente o que a oferta entrega. A arte é encomendada para a ideia, com espaço para o título. Ela precisa participar da página, não apenas preencher um espaço depois que o layout já foi decidido. Ainda assim, uma rodada com arte gerada também foi reprovada: a imagem sozinha não resolveu a ausência de regras e de nível. A régua precisa ser observável. Quando abro uma referência, procuro entender onde o olhar chega primeiro, como a arte participa da composição e se a ação principal é fácil de encontrar. Anotar essas decisões permite voltar à comparação quando uma proposta parece correta, mas ainda perde força ao lado do nível desejado. Na folha de regras, uma escolha precisa dizer onde se aplica e como será reconhecida. Uma regra para o botão, por exemplo, pode definir uma aparência constante para a ação principal. Uma regra de imagem pode definir enquadramento e tratamento, para que a próxima página pertença à mesma identidade. Eu também separo o julgamento de venda do julgamento visual. A primeira tela precisa deixar claro o que é oferecido e o que fazer; depois, a sequência de títulos precisa sustentar a oferta durante a rolagem. Uma composição bonita que esconde a ação ainda precisa de trabalho. Quem quiser copiar o processo pode começar com uma folha curta: referências medidas, frase da ideia, regras verificáveis e o que não deve aparecer. Depois, vale montar a página inteira e compará-la lado a lado com a régua, incluindo a versão de celular. Esse registro torna a revisão uma conversa sobre escolhas visíveis. O portão automático procura defeitos como imagens quebradas e controles cobertos. Ele ajuda a localizar falhas, mas não decide sozinho se a identidade tem força. Eu preciso olhar a página renderizada e verificar se as regras e a oferta continuam claras. Minha conclusão prática é começar pelo que torna a marca reconhecível e só então pedir a página. A mesma disciplina de conferir o resultado publicado aparece no relato de como [migrei o site para Astro e Cloudflare Workers](/blog/migrar-site-astro-cloudflare-workers). --- ## Em 48 horas, juntei domínios, e‑mail, sites e medição num padrão só. URL: https://luisjunior.ai/blog/arrumando-a-casa-48-horas Publicado em 30 de outubro de 2026 · Bastidores · Arrumando a casa, parte 1 Por que juntei domínios, e-mail, sites, busca e medição de todos os meus produtos num padrão só, e a regra que guiou cada escolha. Quem constrói vários produtos sozinho acumula contas, provedores e exceções. Cada produto novo traz outro painel e outra exceção que só quem configurou conhece. Entre 29 e 30 de outubro de 2026, juntei tudo num padrão só: domínios, e-mail, sites, busca e medição dos meus produtos. Fiz isso com agentes de IA, o Claude Code e o Codex, operando terminal e painéis, com o meu OK em cada passo sem volta. ## Antes, cada produto tinha um arranjo próprio Nos dias 28 e 29 de outubro, a infraestrutura estava assim: - Domínios em duas contas da Cloudflare, com registros na Cloudflare Registrar, na GoDaddy e no Registro.br. - E-mail das caixas humanas num VPS com CyberPanel. O IMAP usava um certificado de staging do Let's Encrypt, que os aplicativos de e-mail não aceitam. O domínio do Garfim não tinha SPF nem DMARC, registros DNS que informam quem pode enviar e-mail em nome do domínio. - E-mail transacional do Garfim no Resend, com registros do Brevo sobrando num domínio que já não usava o Brevo. - Os três sites, luisjunior.ai, pagenello.com e clipleve.com, no GPT Sites, com o código publicado fora dos repositórios. - Painéis de busca e de análise divididos entre uma conta pessoal e a conta da marca. ## Uma regra só virou o padrão de tudo A regra nasceu nas chaves de IA e depois virou a regra de tudo. Como tudo é meu, uma conta por ferramenta basta, e a separação entre os produtos fica no nome de cada recurso e nas regras que cada um segue. Cada padrão também virou um documento curto. Os agentes de IA leem esses documentos no começo de toda sessão, e por isso um produto novo já nasce no padrão, sem que alguém precise lembrar as regras. Para as decisões técnicas, sigo um critério só: a mudança ajuda a vender, a reter, a evitar venda perdida ou a manter o negócio apto a vender, com pagamento, conformidade e operação? Se ajuda, entra. ## A série conta cada pedaço em uma parte própria As outras nove partes, em ordem: - Partes 2 e 3: os [três sites saíram do GPT Sites](/blog/por-que-sai-do-gpt-sites) e passaram a rodar em Astro, em Workers da Cloudflare. No ClipLeve, o LCP, que é o tempo até o maior conteúdo aparecer na tela, caiu de 9,9 s para 0,9 a 1,3 s no celular. O luisjunior.ai ficou cerca de 10 segundos fora do ar na [migração](/blog/migrar-site-astro-cloudflare-workers). - Parte 4: o [luisjunior.ai foi refeito do zero](/blog/novo-luisjunior-ai) e entrou no ar em 30 de outubro, às 17:46 UTC. - Parte 5: [todos os domínios](/blog/padrao-de-dominios-cloudflare) estão na mesma conta da Cloudflare, com o mesmo padrão de SSL/TLS, HSTS, DNSSEC e DMARC. - Parte 6: as [caixas de e-mail](/blog/email-dos-produtos-na-cloudflare) de todos os domínios estão no Mailflare, um webmail de código aberto que roda na própria Cloudflare. - Parte 7: o [último envio transacional que ainda sai do Resend](/blog/resend-para-cloudflare-email-sending), o do Garfim, vai para o Cloudflare Email Sending. A decisão foi tomada em 30 de outubro, e a migração ainda está sendo planejada. - Partes 8 e 9: um [método próprio de SEO, AEO e GEO](/blog/seo-aeo-geo-metodo-fonte), escrito em 30 de outubro, e a [primeira rodada dele nos três sites](/blog/seo-aeo-geo-na-pratica). - Parte 10: todos os sites no [mesmo Google Analytics](/blog/google-analytics-varios-sites-um-painel), com consentimento, e um painel único. ## Três controles não ganharam parte própria e seguem a mesma regra Os erros ficam numa única organização no Sentry, no plano gratuito. Cada superfície de cada produto tem um projeto, com nome no formato produto-superfície, como garfim-api e garfim-native. Staging e produção ficam no mesmo projeto, separados pelo ambiente, e o alerta padrão de “high priority issues” chega por e-mail. A medição de produto segue o mesmo desenho no PostHog, com uma organização e um projeto por produto. O plano gratuito libera só 1 projeto por organização; o pago, até 6. No plano pago por uso, o limite de gasto está em US$ 0 em todos os produtos. Passada a cota grátis do mês, o PostHog para de registrar até o ciclo seguinte, e nada é cobrado. Em todos os projetos, a opção “Discard client IP data” está ligada. As chaves de IA ficam num workspace só do OpenRouter. Cada chave tem o nome produto-ambiente e não expira, porque uma chave vencida derruba a IA do produto sem aviso. Cada uma tem limite diário de US$ 25 em produção e US$ 5 em staging, para que uma chave vazada ou um laço não esvazie o saldo dos outros produtos. O registro de prompts e respostas fica desligado. ## Um produto novo já começa com a casa arrumada Com a casa arrumada, o próximo produto nasce com domínio, e-mail, medição e chaves no padrão. O próximo passo é a [parte 2](/blog/por-que-sai-do-gpt-sites), sobre por que tirei os três sites do GPT Sites. --- ## Por que tirei os três sites do GPT Sites. URL: https://luisjunior.ai/blog/por-que-sai-do-gpt-sites Publicado em 30 de outubro de 2026 · Desenvolvimento · Arrumando a casa, parte 2 O GPT Sites colocou meus três sites no ar, mas não dava HSTS na raiz, código no repositório nem controle sobre o que cada página carrega. Meus três sites entraram no ar pelo GPT Sites, da OpenAI, e isso teve valor. Para vender, porém, eles precisavam de velocidade, de cabeçalhos de segurança na raiz do domínio, de código no repositório de cada produto e de controle sobre o que cada página carrega. O arranjo atrapalhava cada uma dessas coisas. Foi um bom começo, que ficou pequeno. Uso os modelos da OpenAI todos os dias, a ponto de ter o reconhecimento pelo uso de mais de 10 bilhões de tokens. A saída foi uma decisão técnica. Os números abaixo mostram o que pesou. ## O domínio raiz não seguia as configurações da minha zona A raiz do domínio apontava, por registros A, para o Cloudflare for SaaS da OpenAI. Nesse arranjo, as configurações da zona do dono do domínio não valem para a raiz, porque o encadeamento com o provedor só funciona por CNAME. Na prática, o que eu configurava na zona não chegava ao domínio raiz. Medi o efeito em 29 de outubro de 2026. O HTTP da raiz ia para o HTTPS com um redirecionamento 302 da OpenAI, que é temporário, e não com 301, que é permanente. A raiz também não recebia HSTS, o cabeçalho que manda o navegador usar sempre HTTPS. O `www`, que passava pela minha zona, seguia o padrão. Além disso, a página recebia um script de desafio da Cloudflare injetado pela OpenAI. ## O ClipLeve mostrou o custo do arranjo O ClipLeve foi o caso mais claro. No Lighthouse para celular do site antigo, rodado em 30 de outubro, a nota foi 70 de desempenho, 100 de acessibilidade, 82 de boas práticas e 100 de SEO. Os 82 de boas práticas vinham do script de desafio injetado. O desempenho sofria por outro motivo: o LCP, que mede quando a parte principal da página aparece, era de 9,9 s, porque a imagem do topo era um PNG de 1,7 MB servido sem cache. Faltavam dados estruturados, `llms.txt` (o arquivo que orienta modelos de linguagem sobre o site) e um modelo de página, então cabeçalho e rodapé se repetiam nas 8 páginas. Pior ainda, o código no ar tinha saído de um checkout temporário, que não existia no repositório do ClipLeve. O repositório guardava uma cópia dos arquivos publicados, atualizada à mão. O site novo do ClipLeve, em Astro, foi ao ar em 30 de outubro. No Lighthouse de celular, a home em inglês, um guia e a calculadora tiveram 100 nas quatro notas, com LCP de 0,9 a 1,3 s. ## Os sites novos mostraram a diferença na produção O Pagenello é um site novo em Astro, com Worker da Cloudflare, no ar desde 30 de outubro, às 00:15 UTC. A primeira versão deu 83 de desempenho no PageSpeed do celular, com LCP de 4,5 s por causa das imagens do topo, e 97 de acessibilidade, por causa do contraste. Na manhã de 30 de outubro, depois de duas correções, a produção chegou a 100 nas quatro categorias, no celular (LCP de 1,8 s e CLS 0) e no computador (LCP de 0,5 s). O último ponto a resolver era um pequeno deslocamento de layout, CLS 0,041, quando a fonte da marca chegava. O Pagenello também precisa de formulário. O Worker grava cada pedido num banco D1, envia por e-mail um aviso e uma confirmação para quem pediu, e tem Turnstile, limite por IP e proteção contra pedidos duplicados. O luisjunior.ai foi refeito do zero em Astro e está no ar desde 30 de outubro, às 17:46 UTC (os detalhes estão na [parte 4](/blog/novo-luisjunior-ai)). Em produção, no celular, marca de 98 a 99 de desempenho e 100 nas demais categorias. No computador, tem 100 em tudo, com LCP de 0,5 s. ## Os três domínios passaram a seguir o mesmo padrão Com a saída, o HTTP passa para HTTPS com 301 e a raiz recebe HSTS, nos três domínios. Cada site tem o código no repositório do próprio produto, e o deploy é um comando, `npm run deploy`, que publica e avisa os buscadores pelo IndexNow. Cada site também carrega só o que o próprio código manda. Para colocar um site no ar rápido, o GPT Sites serve bem. Quando o site vira canal de venda, cada segundo de carregamento e cada cabeçalho passam a contar. A troca em si, feita sem sair do ar, é o assunto da [parte 3](/blog/migrar-site-astro-cloudflare-workers). --- ## Como troquei o luisjunior.ai com cerca de 10 segundos fora do ar. URL: https://luisjunior.ai/blog/migrar-site-astro-cloudflare-workers Publicado em 30 de outubro de 2026 · Desenvolvimento · Arrumando a casa, parte 3 O roteiro para levar três sites no ar para Astro em Workers da Cloudflare sem mudar URLs: o inventário, a ordem da troca e a conferência depois. Em 29 e 30 de outubro de 2026, troquei a hospedagem dos sites do ClipLeve, do Pagenello e do luisjunior.ai. Cada um virou um projeto Astro servido por um Worker da Cloudflare, e os três já estavam no ar. O objetivo era manter cada URL, o link do app e a posição nas buscas, com a menor parada possível. ## O inventário de URLs veio antes de qualquer registro de DNS Antes de mexer no DNS, listei os endereços que não podiam quebrar. No luisjunior.ai, eram as 23 URLs do sitemap antigo. Os 19 textos do blog foram importados sem mudança de texto, nas mesmas URLs e com as mesmas âncoras. O ClipLeve tinha um caso diferente. O app publicado e a ficha da App Store usam `/suporte.html`, `/privacidade.html` e `/termos.html`, além das versões em inglês. Como o app e a loja apontam para esses endereços, eles precisavam continuar funcionando. No site novo, cada um redireciona com 307, um redirecionamento temporário, para a URL sem `.html`. O `/sitemap.xml`, que o Search Console já conhecia, passou a redirecionar com 301, o redirecionamento permanente, para `/sitemap-index.xml`. Por isso, o sitemap não precisou ser reenviado. O teste local era igual à produção: `npm run preview` faz o build e roda o Worker local, com os mesmos arquivos `_headers` e `_redirects` e a mesma página 404. Com isso, o que eu via no computador era o que iria para a produção. O Pagenello tinha mais peças que os outros dois. Ele também usa o D1, banco de dados da Cloudflare, o envio de e-mail e o Turnstile no formulário. O ClipLeve e o luisjunior.ai têm só arquivos estáticos. ## A troca tem três passos e cerca de 10 segundos fora do ar A troca do luisjunior.ai aconteceu em 30 de outubro, em três passos: 1. Publiquei o Worker antes de mexer no DNS. 2. Apaguei os registros que ligavam a raiz ao site antigo: dois registros A e os TXT de verificação do provedor antigo. 3. Liguei o domínio ao Worker como domínio personalizado. Os TXT de verificação são registros que o provedor usa para confirmar que o domínio é seu. Publicar primeiro significa que, quando o domínio muda de destino, o site novo já responde. O tempo fora do ar foi de cerca de 10 segundos, entre a saída do último registro A e a ligação ao Worker, às 17:46 UTC. No ClipLeve, os TXT de verificação do provedor antigo ficam por cerca de uma semana. Assim, dá para voltar ao site antigo se for preciso. ## Depois da troca, conferi a produção com as mesmas URLs As 23 URLs do sitemap antigo do luisjunior.ai respondem 200. HTTP e www redirecionam com 301 para a raiz, que agora recebe HSTS, o cabeçalho que manda o navegador usar sempre HTTPS. Essas conferências foram feitas na produção, logo depois da troca, e não só no teste local. A análise do site só roda depois do consentimento. Antes do aceite, nenhuma requisição sai para o Google. Depois dele, os eventos são enviados e recebem resposta 204. O luisjunior.ai enviou 23 URLs ao IndexNow, protocolo que avisa buscadores participantes sobre URLs novas ou alteradas, e o ClipLeve enviou 29. O Lighthouse da produção do luisjunior.ai deu 98 a 99 de desempenho no celular, com LCP perto de 2 s, e 100 nas demais categorias. No computador, deu 100 em tudo, com LCP de 0,5 s. ## Dois tropeços do Astro que valem para quem usa o framework No Pagenello, o Astro juntava palavras em 17 quebras de linha do código, algumas já no ar. Entre os casos estavam “onLinkedIn” e “within2”. Uma quebra de linha nem sempre vira espaço na página, e por isso a correção foi colocar `{" "}` explícito nas 17 quebras. A regra também foi escrita nas instruções do projeto. Ao fotografar a home do luisjunior.ai para a capa da parte 4, achei o mesmo tropeço no aviso de cookies, que mostrava “conteúdo.Como uso cookies”. A correção entrou junto com esta série. O segundo tropeço também foi do Pagenello: um deslocamento de layout de 0,041 aparecia quando a fonte da marca chegava. Corrigido, o CLS ficou em 0 e o PageSpeed deu 100 nas quatro categorias. ## Cada deploy envia ao IndexNow só as URLs que mudaram Depois da troca, `npm run deploy` faz o build, calcula quais URLs mudaram, publica o Worker e envia só essas URLs ao IndexNow. Assim, uma correção em um texto não reenvia o site inteiro. Cada página tem uma data, que alimenta o `lastmod` do sitemap. O lastmod é a data de última modificação que o sitemap informa para cada URL. O CI do GitHub roda checagem de tipos e build a cada push. O roteiro coube numa lista curta porque o trabalho pesado veio antes: o inventário de URLs, o teste local igual à produção e a conferência logo depois. Na parte 4, conto como ficou o [site novo do luisjunior.ai](/blog/novo-luisjunior-ai). --- ## Refiz o luisjunior.ai do zero: cada afirmação com prova. URL: https://luisjunior.ai/blog/novo-luisjunior-ai Publicado em 30 de outubro de 2026 · Lançamento · Arrumando a casa, parte 4 Como o site novo do luisjunior.ai ganhou prova para cada afirmação, por que a grade de tokens saiu e quais números medidos ele entregou. Desde 30 de outubro de 2026, às 17:46 UTC (14:46 no horário de Brasília), meu site pessoal, o luisjunior.ai, está no ar numa versão refeita do zero. Ele roda em Astro, num Worker da Cloudflare que só entrega arquivos estáticos, e a home abre com o título “Do prompt ao produto no ar”. Pedi um site fora do normal, que mostrasse bom gosto, domínio de IA, execução e velocidade. Este texto conta as escolhas que fiz e o que descartei no caminho. ## Cada afirmação do site precisa de prova O conceito ficou em uma frase: cada afirmação com prova. A home traz um registro de lançamentos, em que cada item leva a data do texto do blog que o conta. Ela apresenta também os três produtos: o [Pagenello](https://pagenello.com), o [ClipLeve](https://clipleve.com) e o Garfim. As decisões de produto aparecem como diff, e o problema fica riscado quando a solução entra. Bastidores, sobre e contato completam a página. Os 19 textos do blog e as páginas legais foram importados sem mudança de texto, nas mesmas URLs e com as mesmas âncoras. A página [sobre](/sobre) é nova. Ela tem a frase que me descreve, fatos datados e fotos para imprensa. ## A grade de tokens saiu antes de ir ao ar A primeira versão da home tinha uma grade em que cada ponto valia 10 milhões de tokens. Recusei a grade. Achei clichê, e disse sobre ela: “se você tem que explicar o que significa, é porque não ficou legal”. Pedi, no lugar dela, movimento e peças que se encaixassem conforme a pessoa rola a página. A ideia nova precisava se explicar sozinha, sem legenda. ## Uma sequência ao rolar tomou o lugar da grade No lugar da grade entrou uma sequência fixa, ligada à rolagem. Um prompt é digitado e vira tokens. Os tokens se encaixam na tela do Garfim, com o conteúdo real da tela de porções, e Pagenello e ClipLeve chegam ao lado. O contador termina em 10 bilhões de tokens. Esse número chega com a prova ao lado: a placa da OpenAI, que reconhece o uso de mais de 10 bilhões de tokens. Cada seção entra por cima da anterior, com cantos arredondados. O verde-limão da marca continua como sinal, sobre uma tinta mais quente. Há uma seção creme para produtos e lançamentos, e o contato fica em verde-limão. As fontes são Geist, Geist Mono e Instrument Serif, e o símbolo com o ponto verde-limão foi mantido. Todo o movimento está ligado à rolagem e respeita a preferência de movimento reduzido do sistema. ## Os recursos servem a quem visita e a agentes Além da sequência, o site tem recursos que aparecem na navegação, pensados tanto para quem visita quanto para agentes: - Menu ⌘K, que no celular é o menu principal, com busca em seções, produtos, textos e ações. - Botão “Ver como IA”, que mostra o llms.txt do site como uma resposta de modelo. - Quatro ferramentas WebMCP somente leitura, com perfil, produtos, busca nos textos e contato. Elas são registradas quando o navegador oferece essa interface para agentes. - O tempo de carregamento medido no navegador de quem visita aparece no cabeçalho e no rodapé. - Links internos pré-renderizados ao passar o mouse, e troca de página com View Transitions. Dá para testar cada item na própria página. O llms.txt é um arquivo de texto que descreve o site para modelos de IA, e o WebMCP é a forma de um site oferecer ferramentas a agentes que usam o navegador. ## Cada número de velocidade tem medição e fonte Medi a velocidade localmente com o Lighthouse 13.6, e a home teve 100 nas cinco categorias: desempenho, acessibilidade, boas práticas, SEO e navegação por agentes, no celular e no computador. No celular, a home ficou com 180 KB; na versão com a grade, eram 262 KB. Na produção, a nota de desempenho no celular fica entre 98 e 99, e as demais categorias ficam em 100. No computador, a produção marca 100 em tudo, com LCP de 0,5 s, que é o tempo até o maior elemento da tela aparecer. Deixo as duas medições registradas porque, no celular, a produção não repete a nota local. O tempo que aparece no cabeçalho e no rodapé é medido no navegador de quem visita, então ele muda de visita para visita. A análise só começa depois do consentimento: antes do aceite, nenhuma requisição vai ao Google. Aprovei a versão visual e funcional antes da publicação. O site foi feito com agentes de IA no mesmo dia: versão de teste, segunda versão e publicação. O site é a prova de execução em si. A velocidade aparece medida ao vivo, e cada número tem fonte. O próximo texto da série trata dos domínios, e o padrão que uso para todos eles está na [parte 5](/blog/padrao-de-dominios-cloudflare). --- ## Um padrão para todos os domínios, inclusive os de produtos futuros. URL: https://luisjunior.ai/blog/padrao-de-dominios-cloudflare Publicado em 30 de outubro de 2026 · Bastidores · Arrumando a casa, parte 5 Os oito pontos do padrão de domínio que defini, como os domínios estavam, o que apliquei em 29 e 30 de outubro e o que ficou pendente. Em 29 de outubro de 2026, meus domínios ainda não seguiam um padrão comum. Havia domínios em duas contas da Cloudflare, o TLS mínimo aceito era 1.0 e não havia HSTS nem DNSSEC. Naquele mesmo dia escrevi o padrão que vale para todo domínio, inclusive os de produtos que ainda vão nascer. Apliquei o padrão nas zonas em 29 e 30 de outubro. O que ficou pendente aparece numa seção própria, com a data de conferência. ## Os domínios estavam em contas e configurações diferentes Os domínios luisjunior.ai e pagenello.com estavam na conta pessoal antiga da Cloudflare. O clipleve.com era registrado na GoDaddy, e o clipleve.com.br estava no Registro.br com uma página de estacionamento da GoDaddy. Um domínio .com.br ainda tinha o DNS fora da Cloudflare. Nas zonas, o TLS mínimo era 1.0, não havia HSTS nem DNSSEC, e o DMARC estava em none. O domínio do Garfim aceitava TLS 1.0 e 1.1 e não tinha SPF nem DMARC. ## O padrão tem oito pontos para qualquer domínio Dois termos aparecem na lista. HSTS é o cabeçalho que manda o navegador usar sempre HTTPS no domínio. DMARC é a regra que diz a quem recebe o que fazer com mensagens que dizem vir do seu domínio e não passam na checagem. O padrão, como ficou definido em 29 de outubro: 1. A zona fica em uma única conta da Cloudflare. O registro fica na Cloudflare Registrar, com renovação automática e bloqueio de transferência. A exceção é o `.com.br`, que a Cloudflare não registra: ele fica no Registro.br, com os nameservers da Cloudflare. 2. O DNSSEC fica ligado. Ele só é desligado durante uma mudança de conta ou de registrador. 3. A raiz é o endereço principal. O `www` vai para a raiz com 301, preservando caminho e query, e o HTTP vai para HTTPS também com 301. 4. SSL/TLS em modo Full (strict), com TLS mínimo 1.2, TLS 1.3 ligado e Automatic HTTPS Rewrites ligado. 5. HSTS de 6 meses (`max-age=15552000`), com `includeSubDomains` e sem `preload`. 6. Recebimento pelo Email Routing, um único SPF na raiz, DKIM do envio da Cloudflare e DMARC `p=reject` quando todo envio estiver alinhado, com relatórios no DMARC Management da Cloudflare. 7. Domínio que não manda nem recebe e-mail tem MX nulo, que avisa que ele não recebe mensagens, além de `v=spf1 -all` e DMARC `p=reject`. Assim ninguém usa o domínio para falsificar remetente. 8. Domínio secundário da marca, como o `.com.br` de um produto `.com`, redireciona com 301 para o principal e não tem e-mail. ## Em dois dias, o padrão foi aplicado nas zonas Em 29 de outubro, luisjunior.ai e pagenello.com foram para a conta principal. O DNS foi recriado a partir da exportação, com 10 e 17 registros. O proxy só voltou na raiz e no `www` depois que o certificado universal ficou ativo, e as duas zonas ativaram às 19:37 UTC. No mesmo dia, o padrão de SSL/TLS e HSTS foi aplicado em 8 zonas. Os sites seguiram respondendo 200, e TLS 1.0 e 1.1 passaram a ser recusados também no Garfim. O DNSSEC ficou ligado em cinco zonas, e no `.com.br` o registro DS foi publicado no Registro.br. O clipleve.com.br também ganhou uma zona com 301 para clipleve.com e com o e-mail bloqueado. Em 30 de outubro veio a limpeza: saíram os registros de verificação do GPT Sites, três registros do Brevo que o site não usava mais e os registros do antigo servidor de e-mail. Também saíram 15 regras do Email Routing que apontavam para endereços sem caixa, já que o catch-all levava tudo ao destino certo. Ainda em 30 de outubro, o DMARC Management foi ligado nos 6 domínios que têm e-mail, e as regras de `www` ganharam um nome único: o do produto, seguido de www para HTTPS principal. Depois de cada mudança, eram conferidos três pontos: os sites respondendo 200, o `www` e o HTTP com 301, e os resolvedores públicos já sem os registros apagados. ## Nem tudo fechou no mesmo dia O DNSSEC de quatro domínios registrados na Cloudflare Registrar ficou `pending` por quase 24 horas, porque o registro DS não foi publicado. Em 30 de outubro, por volta das 17:20 UTC, o DNSSEC desses domínios foi desligado e religado. A conferência começa em 31 de outubro. Se o DS continuar sem aparecer, o caso vira chamado no suporte da Cloudflare. O clipleve.com também segue pendente. Ele sai da GoDaddy para a Cloudflare Registrar a partir de 7 de novembro de 2026, por causa da trava de 60 dias de transferência. Só darei o DNSSEC por resolvido quando o DS aparecer nesses quatro domínios. ## O próximo domínio já nasce no padrão Um padrão escrito vale mais que uma configuração lembrada. Por isso, o próximo domínio entra na lista e já nasce certo. Na [parte 6 da série](/blog/email-dos-produtos-na-cloudflare), conto como ficou o e-mail dos produtos, que é o ponto 6 do padrão. --- ## Todo o e‑mail dos meus domínios saiu do VPS num só dia. URL: https://luisjunior.ai/blog/email-dos-produtos-na-cloudflare Publicado em 30 de outubro de 2026 · Desenvolvimento · Arrumando a casa, parte 6 Como levei as caixas de todos os meus domínios do VPS para a Cloudflare, com Email Routing, Email Sending e um webmail que atende a todos. As caixas de luisjunior.ai, pagenello.com, clipleve.com e garfim.com.br estavam num VPS com CyberPanel. O certificado do IMAP era de staging do Let's Encrypt, que os aplicativos de e-mail não aceitam, e o garfim.com.br não tinha SPF nem DMARC. Em 29 de outubro de 2026, todas as caixas saíram desse VPS e foram para a Cloudflare, num só dia. A Cloudflare cobre só uma parte do problema, porque recebe e envia mensagens, mas não tem caixa postal. Para ter uma caixa de entrada de verdade, faltava uma peça que rodasse na minha própria conta, e foi essa peça que escolhi. ## Email Routing e Email Sending cuidam do trajeto da mensagem O Email Routing recebe e-mail e é gratuito. O Email Sending envia, em beta, no plano Workers Paid, com 3.000 envios por mês incluídos e US$ 0,35 por mil adicionais, por Worker, API REST ou SMTP. A Cloudflare não oferece caixa postal, IMAP nem webmail. Esse papel precisava de um webmail que rodasse na própria conta Cloudflare. ## Um webmail aberto preencheu a parte que faltava O app de referência da Cloudflare para isso, o Agentic Inbox, não recebia commits desde abril de 2026. Escolhi o [Mailflare](https://github.com/hieunc229/mailflare), que é de código aberto, sob AGPL, está ativo e tinha 37 contribuidores em 29 de outubro de 2026. Ele recebe pelo Email Routing e guarda as mensagens em D1 e R2. Mantém a mensagem bruta no R2 antes de processá-la e faz backup diário. Envia pela Cloudflare, mas também aceita Resend ou SES. Aceita domínios ilimitados e funciona como PWA, um app instalado a partir do navegador, sem IMAP. ## Uma instalação atende todos os domínios, atuais e futuros Uma instalação só, no domínio luisjunior.ai, atende todos os domínios. O e-mail é meu, e cada produto entra nele com a sua caixa. Cada caixa de produto tem a opção “Usar todos os domínios” desligada, e a minha caixa pessoal vale em todos. Em cada domínio, a migração mexeu nos mesmos pontos: - o MX saiu do VPS e foi para o Email Routing; - o catch-all aponta para o Mailflare; - o envio usa o DKIM da Cloudflare; - o DMARC está em `p=reject`. O MX diz para onde o e-mail do domínio deve ir. O catch-all recebe qualquer endereço do domínio que não tenha caixa própria, e o DMARC em `p=reject` pede que os servidores rejeitem mensagens que falhem na verificação. Cada domínio enviou um teste com o DKIM do próprio domínio e DMARC aprovado. As mensagens chegaram na caixa certa, inclusive pelos catch-alls. ## Decidi migrar tudo no mesmo dia, depois do piloto O piloto começou com o domínio de um produto que ainda não lancei. A recomendação inicial era uma semana de piloto, e decidi migrar todos os domínios no mesmo dia. Os testes do piloto deram estes resultados. Um envio interno chegou em 16 segundos, com DKIM e SPF alinhados. Um e-mail vindo do Gmail chegou em 23 segundos, com DMARC e DKIM válidos e nota 0 de spam. A resposta enviada pelo Mailflare caiu na caixa de entrada do Gmail, e a réplica seguinte também chegou. As mensagens antigas ficam no VPS até o próprio Mailflare importá-las por IMAP, o protocolo que os aplicativos de e-mail usam para ler mensagens guardadas num servidor. Só depois dessa importação o e-mail do VPS é desligado. ## A visão unificada ficou protegida, e algumas partes seguem abertas O Mailflare original não tem a visão “Todas as caixas”. Ela foi escrita para este uso e publicada em 29 de outubro, depois de checagem de tipos, build e testes. Junta numa lista só o que chega a todos os domínios, mostra a caixa de origem de cada mensagem, e a resposta sai da caixa certa. O webmail inteiro fica atrás do Cloudflare Access, com login por código de uso único enviado por e-mail e sessão de uma semana. Uma das entradas autorizadas do Access fica fora do próprio webmail, porque o código não pode chegar só dentro da caixa que ele protege. Algumas partes ficaram de fora. A cópia automática para outro endereço exige a licença Pro do Mailflare (US$ 19, pagamento único), e ela não foi comprada. No iPhone não há app do Mailflare, então o caminho é o PWA, pelo Safari, com a opção Adicionar à Tela de Início. No Mac, o autor do Mailflare publica um app oficial. Também há uma cota diária de envio pela Cloudflare, que começa em 200 e é dividida entre tudo o que a conta envia. Com isso, as caixas dos domínios saíram do VPS e passaram a ficar numa única instalação na Cloudflare. Quando o próximo produto chegar, basta adicionar o domínio e criar a caixa. O último envio que ainda sai pelo Resend fica para a [parte 7 da série](/blog/resend-para-cloudflare-email-sending). --- ## Decidi mover o envio do Garfim do Resend para a Cloudflare. URL: https://luisjunior.ai/blog/resend-para-cloudflare-email-sending Publicado em 30 de outubro de 2026 · Desenvolvimento · Arrumando a casa, parte 7 O Garfim ainda envia pelo Resend. Explico por que vou mover esse envio para o Cloudflare Email Sending, o que se perde e o que falta resolver. Quando um cliente responde a um e-mail do Garfim, a resposta volta com erro. Os e-mails transacionais saem pelo Resend, do endereço noreply@updates.garfim.com.br, no plano gratuito, e não há Reply-To na mensagem. O subdomínio updates não recebe e-mail porque não tem registro MX, que é o registro que indica onde um domínio recebe mensagens. O envio transacional do Garfim é o último que ainda fica fora da Cloudflare. Domínio e recebimento de e-mail já estão lá, como contei nos textos sobre [domínios](/blog/padrao-de-dominios-cloudflare) e [e-mail dos produtos](/blog/email-dos-produtos-na-cloudflare). Em 30 de outubro decidi migrar esse envio para o Cloudflare Email Sending. A migração ainda está em planejamento, e este texto explica o motivo, o que se ganha, o que se perde e o que falta resolver antes da troca. Uma resposta que volta com erro é uma falha que o cliente percebe. Antes de decidir, pesei o custo, as peças que saem e o que se perde com a troca. ## Sair do Resend tira peças do caminho e evita um recurso pago No Resend, o plano gratuito atende um time, e esse time é o do Garfim. Cada produto a mais pediria um segundo time, recurso do plano Pro, que custa US$ 20 por mês. O Email Sending está dentro do Workers Paid, plano que eu já pago, e inclui 3.000 envios por mês. Cada mil envios adicionais custa US$ 0,35. Ou seja, todos os produtos enviam por um plano que já existe, e nenhum produto novo abre uma conta paga. A troca também deixa um provedor a menos no caminho do e-mail. Saem uma conta externa, com os segredos que ela exige, e o webhook público de eventos. Menos peças são um dos motivos da decisão, porque cada peça a mais precisa ser configurada e mantida. ## O Pagenello já envia pelo Email Sending, e outro produto nasceu assim O Pagenello já envia pelo Email Sending, a partir de mail.pagenello.com. Quando alguém pede um first look no site, o Worker manda um aviso para a caixa do Pagenello e uma confirmação para o cliente. No teste de lançamento, em 30 de outubro, os dois e-mails chegaram. Um produto que ainda não lancei também teve o envio trocado do Resend para o Email Sending no código, em 29 de outubro. Os dois usam o mesmo caminho que o Garfim vai usar depois da troca. O padrão tem regras fixas. O transacional sai de `mail.` e o de marketing de `news.`, cada um com DKIM, SPF e DMARC com `p=reject` publicados pela Cloudflare. DKIM e SPF autenticam quem envia pelo domínio. O DMARC com `p=reject` pede ao destinatário que rejeite a mensagem que falhar nessa checagem. O Reply-To aponta para a caixa humana do produto, e o envio usa o binding `send_email` do Worker. Com a troca, o Garfim seguiria essas mesmas regras de remetente, autenticação e resposta. ## O Email Sending não mostra aberturas e não evita repetições sozinho Aceito duas perdas. Não há evento de abertura no Email Sending, então não há como saber se a pessoa abriu o aviso. Também não há chave de idempotência no envio. Uma chave de idempotência é o identificador que permite ao sistema reconhecer que um pedido é repetição de outro. Sem ela, se uma tentativa for repetida, o próprio sistema precisa evitar o e-mail duplicado. Isso fica sob responsabilidade do código do Garfim. Mesmo assim, aceito as perdas porque o ganho em custo e em peças justifica a troca. Registro as duas aqui para que nenhuma apareça depois como surpresa. ## Antes da troca, a cota e o Reply-To precisam estar resolvidos Dois itens precisam estar prontos antes da troca, e um terceiro vem depois dela: 1. A cota diária da conta começa em 200 envios e é dividida entre todos os produtos que enviam por ela, inclusive o webmail. 2. O envio novo passa a ter `Reply-To: contato@garfim.com.br`, para que a resposta do cliente chegue a uma pessoa. 3. Depois da troca, saem do DNS os registros do Resend no subdomínio updates. A cota exige mais atenção, porque a conta é compartilhada. Os 200 envios diários precisam ser planejados para o conjunto de produtos e para o webmail. O Reply-To é a correção mais simples. Ele é o endereço para onde vai a resposta quando alguém clica em responder, e pode ser diferente do remetente. Hoje a resposta volta com erro. Com o endereço de contato, ela chega a uma pessoa. A ordem importa: os registros do Resend saem do DNS só depois da troca. ## A decisão de 30 de outubro ainda espera a troca A decisão de migrar foi tomada em 30 de outubro. A troca, porém, ainda não aconteceu. Até lá, o Garfim segue enviando pelo Resend, do mesmo endereço e sem Reply-To. Registrar a decisão antes da execução tem uma utilidade. Quando a troca acontecer, dá para comparar o que foi planejado com o que de fato saiu, incluindo a cota e as perdas listadas acima. Quando todos os produtos enviam do mesmo lugar, o padrão de remetente, autenticação e resposta é um só. O Garfim é o último caso que falta para isso. Na [parte 8](/blog/seo-aeo-geo-metodo-fonte), a série passa ao método de busca para Google e IAs. --- ## O método FONTE para aparecer no Google e nas respostas de IA. URL: https://luisjunior.ai/blog/seo-aeo-geo-metodo-fonte Publicado em 30 de outubro de 2026 · Inteligência artificial · Arrumando a casa, parte 8 SEO, AEO e GEO explicados, os números de 2026 sobre AI Overviews e citações, a escada de visibilidade e as cinco camadas do método FONTE. Em 30 de outubro de 2026, montei um manual próprio de busca. Ele se chama método FONTE e serve para aparecer em três lugares: nos resultados do Google, nas respostas de IA do próprio buscador e nas recomendações dos assistentes. ## Os três nomes descrevem um sistema só SEO é aparecer nos resultados orgânicos do Google e do Bing. AEO é ser a resposta ou a fonte citada nos recursos de IA do próprio buscador: AI Overviews e AI Mode do Google, trecho em destaque, Copilot do Bing e assistentes de voz. GEO é ser mencionado, citado e recomendado pelos assistentes, como ChatGPT, Claude, Perplexity, o app Gemini, Meta AI e Grok. Os nomes separam onde a marca aparece, mas formam um sistema só. O próprio Google diz que AEO “ainda é SEO” no guia oficial atualizado em 10 de julho de 2026, e os assistentes buscam em índices de buscadores. ## Os números de 2026 mudaram a conta da busca Em setembro de 2026, o AI Overviews apareceu em 78% das buscas não de marca no desktop dos EUA (Ahrefs, 232,8 milhões de SERPs, 2 de outubro de 2026). Na posição 1, o CTR cai 58% quando há AI Overview (Ahrefs, 300 mil palavras, 4 de fevereiro de 2026). Estar citado no AI Overview também muda o clique. Com a marca citada, o CTR orgânico informacional é 2,07%; sem citação, 0,94% (Seer, 5,47 milhões de consultas, 24 de abril de 2026). Só 37,9% das citações do AI Overviews vêm do top 10 (Ahrefs, 4 milhões de URLs, 2 de março de 2026). Por isso, o que decide é cobrir as subconsultas que a IA dispara. Menções à marca na web têm correlação de 0,664 com a visibilidade no AI Overviews. Backlinks têm 0,218 (Ahrefs, 75 mil marcas). Há ainda dois avisos. Desde 15 de maio de 2026, as políticas de spam do Google valem para as respostas de IA, e criar uma página por variação de consulta é “abuso de conteúdo em escala”. Desde 15 de setembro de 2026, na Cloudflare, a categoria Training em “Block” bloqueia também Googlebot, Bingbot e Applebot. Um clique pode tirar o site da busca. Schema e `llms.txt` têm pouca força. Um teste controlado não achou ganho de citação com JSON-LD (Ahrefs, 1.885 páginas, 11 de maio de 2026), e 97% dos `llms.txt` nunca foram lidos (Ahrefs, 137 mil domínios). Ficam no método como higiene barata. Os números desses estudos são fotos de um sistema que muda rápido, e por isso cada um é conferido de novo antes de virar meta. ## Seis degraus separam ser lido de ser escolhido A escada de visibilidade tem seis degraus, e cada um decide algo diferente. | Degrau | O que acontece | O que decide | | --- | --- | --- | | 1. Lido | O robô acessa e indexa a página. | Acesso, indexação, HTML legível. | | 2. Recuperado | A página entra na busca que alimenta a resposta. | Ranking na consulta e nas subconsultas. | | 3. Citado | A página aparece como fonte. | Resposta direta, fato próprio, data recente. | | 4. Mencionado | A marca é nomeada no texto. | Entidade clara e consistente. | | 5. Recomendado | A marca entra na lista curta. | Consenso de terceiros: avaliações, listas, imprensa, comunidades, vídeo. | | 6. Escolhido | A pessoa clica, compra ou assina. | Motivo para clicar e página que converte. | Subir um degrau não garante o próximo. Por isso, a camada E pede medir cada degrau todo mês. ## As cinco camadas do FONTE começam pela fundação O método organiza o trabalho em cinco camadas, nesta ordem. A primeira vem antes de tudo: se a fundação falha, nada do resto conta. - F, Fundação técnica: robôs liberados na Cloudflare e no `robots.txt`, indexação no Google, no Bing e no Brave, site rápido em HTML do servidor, entidade e dados estruturados corretos. - O, Páginas oficiais: páginas que dizem o que só o produto pode afirmar, como o que é, para quem, preço, planos, limites, comparação e perguntas frequentes. Cada uma responde primeiro, traz fatos em texto e tabela e mostra a data. - N, Não commodity: o que uma IA não produziria sozinha, como ferramentas que fazem o trabalho na página, dados e testes próprios, exemplos reais e opinião assinada por quem fez. Uma IA descreve uma ferramenta. Ela não a executa. - T, Terceiros: a recomendação vem do que a web diz sobre a marca, como listas que as IAs já citam, avaliações reais, vídeos, respostas identificadas em comunidades, imprensa com dado próprio e perfis consistentes. - E, Escala e evidência: uma página própria para cada demanda real do mercado, com conteúdo e forma próprios, publicada em ondas e podada pelo que indexa. Cada degrau é medido todo mês, e a decisão segue o que gera receita. Dois critérios orientam o trabalho dentro das camadas. O primeiro é receita: priorizo as consultas que levam a compra ou cadastro. O segundo é volatilidade: ela exige carteira, e o site próprio é a única superfície que nenhuma plataforma tira do ar. ## A skill aplica uma rodada nova a cada mês Montei o método a partir de cinco pesquisas, sobre SEO, AEO, GEO, guerrilha e técnica, e as fontes de 2025 e 2026 foram conferidas em 30 de outubro de 2026. Ele virou uma skill que roda no Claude Code e no Codex. A IA a aplica sozinha num site: diagnóstico, as cinco camadas, a onda de páginas e a medição, com os registros no repositório. Pedir de novo roda a próxima rodada, que é o ciclo mensal. A medição segue o que gera receita, e essa regra decide o que entra em cada rodada. A primeira rodada nos três sites está na [parte 9 da série](/blog/seo-aeo-geo-na-pratica). --- ## Três sites, três decisões de busca, e uma delas é não gerar páginas. URL: https://luisjunior.ai/blog/seo-aeo-geo-na-pratica Publicado em 30 de outubro de 2026 · Inteligência artificial · Arrumando a casa, parte 9 Na primeira rodada do método FONTE, cada um dos meus três sites recebeu uma decisão de busca. No site pessoal, a decisão foi não gerar páginas em escala. Em 30 de outubro de 2026, apliquei a primeira rodada do método FONTE, que está na [parte 8](/blog/seo-aeo-geo-metodo-fonte), nos três sites. Cada um recebeu uma decisão diferente, e uma delas foi não gerar páginas em escala no site pessoal. Ainda não há resultado de tráfego para mostrar. O que existe são diagnósticos, mudanças feitas e duas datas marcadas para conferir. ## No site pessoal, a escala ficou para depois dos casos reais No luisjunior.ai, a busca por “Luis Junior” mostrava jogadores de futebol e outras pessoas com o mesmo nome. O Search Console e o Bing não tinham o domínio na conta da marca. Os degraus que travavam eram o 1 (lido) e o 4 (entidade). No código, os favicons passaram a existir em ICO e PNG, porque o Google não aceita SVG como favicon. Os sitemaps ficaram separados, e a página /sobre passou a trazer a frase que me descreve do mesmo jeito em todo lugar: “Luis Junior é desenvolvedor e empreendedor brasileiro que constrói produtos com inteligência artificial, como o estúdio de sites Pagenello e os apps ClipLeve e Garfim.” Vieram também bios, fatos datados, fotos para imprensa e uma resposta curta no topo de três textos com demanda de busca: o teste fechado do Google Play, a diretriz 2.1 e a diretriz 5.2.5 da App Store. Nas contas, o Search Console passou a ter o domínio inteiro como propriedade, o Bing ficou verificado com sitemap, o Brave tem três URLs, o Early Hints está ligado na Cloudflare e o GA4 ganhou um canal para assistentes de IA. Quanto à escala, a decisão veio do que o site tinha: três casos vividos com demanda, todos já publicados como texto. Uma página por diretriz da App Store, ou por modelo de IA, sem experiência própria por trás, seria abuso de conteúdo em escala. A próxima onda depende de cada caso real novo virar texto. Com 8 a 10 casos do mesmo eixo, eles ganham uma página que os reúne. ## No Pagenello, a base técnica veio antes de qualquer página O Google tinha a versão antiga do pagenello.com, o Bing não tinha nenhuma página e o Brave mostrava só a home antiga. A busca por “pagenello” trazia apenas um torneio de nome parecido. Pior, o ChatGPT repetia uma informação do site antigo e, nos prompts de quem procura o serviço, recomendava concorrentes com página oficial de preço. A base técnica entrou no ar às 09:52 (horário de Brasília) de 30 de outubro, com: - `robots.txt` com `Content-Signal` - favicon em ICO e PNG - uma data por página, que alimenta o sitemap, o schema e a data visível - uma página de preço em Markdown (`/pricing.md`) - IndexNow no deploy Também vieram as páginas oficiais e uma página com os dados de preço. O FAQ ganhou “How do I pay?”, porque o ChatGPT manda quem vai comprar conferir se o pagamento tem proteção ao comprador. O formulário passou a perguntar como a pessoa conheceu o estúdio, para medir o que os painéis não veem. ## As 48 páginas de nicho passaram por testes antes do ar Pedi de 200 a 300 páginas, escritas por subagentes Haiku. O teste de demanda no autocompletar avaliou 190 tipos de negócio e aprovou 157, e o teto honesto ficou em 162 páginas. Para cada tipo, um subagente leu a página de resultados da busca e escreveu um dossiê. No ar, há 48 páginas de nicho, com 768 a 1.084 palavras cada e pelo menos 60% de texto próprio (mediana de 67%). Portões automáticos no build checam as páginas, e a revisão corrigiu três coisas. Duas respostas diziam que a página não podia ter avaliações, quando a regra é só não inventar depoimento. Nomes fictícios repetidos, como “Lantern”, que aparecia 10 vezes, foram trocados em 21 exemplos. Dois tipos foram rebaixados para a próxima onda. ## No ClipLeve, o conteúdo ficou pronto antes do site novo Antes de o site novo ir ao ar, o ClipLeve ganhou uma calculadora de tamanho de vídeo, em inglês e português, com o mesmo modelo de cálculo do app. Foram 17 guias, sendo 10 em inglês e 7 em português, com fontes datadas. Um portão automático de qualidade roda no build, e os sitemaps são separados. Os limites usados nos guias foram conferidos nas fontes oficiais em 30 de outubro: WhatsApp no iPhone, 100 MB a 720p ou 64 MB a 480p, e documentos até 2 GB; Outlook.com, 25 MB. Depois do go-live, no mesmo dia, vieram o Search Console de domínio com sitemap, o Bing e quatro URLs no Brave. No GA4, um grupo de canais com “Assistentes de IA” ficou acima dos orgânicos, porque o canal nativo de IA do GA4 vem por último e deixa Perplexity e Claude de fora. ## Os resultados só serão conferidos em novembro A indexação será conferida em 13 de novembro de 2026, e a segunda rodada está marcada para 30 de novembro de 2026. Só então haverá dados para avaliar cada uma das três decisões. Uma escala sem caso real vira spam com data marcada. Com demanda testada e texto próprio, a mesma escala vira distribuição. Medir isso nos três sites, num painel só, é o assunto da [parte 10](/blog/google-analytics-varios-sites-um-painel). --- ## Medição de vários sites num painel só, com consentimento. URL: https://luisjunior.ai/blog/google-analytics-varios-sites-um-painel Publicado em 30 de outubro de 2026 · Bastidores · Arrumando a casa, parte 10 Como medi todos os sites dos meus produtos no mesmo GA4, com consentimento, e juntei os dados num painel só. Também conto o site que não coletava visitas. Todos os sites dos meus produtos passaram a medir do mesmo jeito: na mesma conta do Google Analytics, com consentimento e aparecendo num painel só. Esta parte fecha a série “Arrumando a casa”, que conta as 48 horas de 29 e 30 de outubro de 2026. ## Um padrão de medição para todos os sites Defini o padrão em 29 de outubro. Há uma conta da marca no Google Analytics, com uma propriedade por produto, no fuso de São Paulo e na moeda em que o produto cobra. A retenção de dados fica em 14 meses, e o Google Signals está desligado. Cada produto tem um fluxo Web no domínio canônico. A medição otimizada fica desligada (só o luisjunior.ai nasceu com ela ligada). Cada evento sai explicitamente do código, para que nenhuma URL ou campo de formulário chegue ao Google sem ter sido escolhido. Uso o gtag.js direto, sem Google Tag Manager. Ele só carrega na origem de produção e depois do consentimento de análise. ## O que vai para o Google e o que fica no site Antes de qualquer escolha do visitante, o Consent Mode v2 está com tudo negado. O Consent Mode é o mecanismo que ajusta o comportamento das tags à escolha de cada visitante. O consentimento de análise libera só o `analytics_storage`, e o armazenamento de anúncios só é liberado com o consentimento de anúncios. O que vai para o Google não traz nenhum dado pessoal. O endereço da página segue sem query e sem fragmento, mantendo só as UTMs e os identificadores de clique autorizados, e o referenciador vai só com a origem. Além do `page_view`, os eventos de conversão usam os nomes recomendados pelo GA4: - `generate_lead`, no Pagenello, disparado quando o pedido é salvo no banco - `store_click`, o clique para a loja de apps - `purchase`, que vem do estado confirmado no servidor e não do clique No Pagenello, a origem do anúncio, com UTMs e o identificador de clique, fica guardada só no banco do próprio site. Por fim, a política de privacidade e o aviso de cookies de cada site citam o Google Analytics como análise opcional. O Search Console de cada domínio fica na mesma conta, vinculado ao fluxo do produto. ## Um site que não coletava visitas Um site pode estar no ar e não medir nada, e foi o que aconteceu com o Garfim. O ID de medição é o que liga o site à propriedade do Google Analytics. O CI publicava o site sem esse ID, e nenhuma visita chegava ao Google. Corrigi em 29 de outubro, passando o ID ao build. Depois, conferi o padrão no luisjunior.ai, num Chrome isolado. Antes do consentimento, nenhuma requisição ao Google saiu. Depois do aceite, saíram `page_view` e `product_click`, este com o produto e a posição em que foi clicado, e ambos responderam com 204. ## Um painel só, com uma junção que precisou de ajuste Em 30 de outubro, o painel ficou pronto como um relatório privado no Data Studio (nome que o Looker Studio voltou a usar em outubro de 2026), chamado “Luis Junior — Sites”. O Data Studio lê os dados do Google Analytics e os organiza em tabelas e gráficos numa tela só. O relatório se ajusta ao celular, e o seletor de período fica no topo, com os últimos 28 dias, sem hoje, como padrão. O resumo tem uma tabela por site, com usuários ativos, sessões, eventos principais e taxa de engajamento, além da variação em relação ao período anterior. Os gráficos mostram as sessões por dia, com uma linha por site, e as sessões por canal, com uma coluna por site. O ajuste foi técnico. Os gráficos usam combinações de dados, que aceitam no máximo 5 tabelas. Com junção simples, os dias e canais que o primeiro site não tinha desapareciam. A solução foi uma junção externa completa e um campo calculado com `COALESCE` das chaves das 5 tabelas, para os campos Dia e Canal. ## Assistentes de IA ganharam um canal próprio No ClipLeve, desde 30 de outubro, o grupo de canais copiado do padrão ganhou o canal “Assistentes de IA”, na posição 9, acima dos orgânicos e do Referral. Ele reconhece a origem da sessão por uma expressão regular ou pelo meio `ai-assistant`. Canal, no GA4, é o agrupamento que o Google faz da origem de cada sessão, como busca orgânica e redes sociais. O canal de IA que já vem no GA4 fica por último e deixa Perplexity e Claude de fora. Por isso criei o meu. O que foi feito em 48 horas agora está medido, e cada produto novo entra neste painel no dia em que vai ao ar. O porquê de tudo isso está na [parte 1](/blog/arrumando-a-casa-48-horas). --- ## Como a IA me apresenta mídias para aprovação URL: https://luisjunior.ai/blog/como-a-ia-me-apresenta-midias-para-aprovacao Publicado em 29 de outubro de 2026 · Inteligência artificial · Construindo o Garfim, parte 15 Nos bastidores do Garfim: uma galeria com 13 peças, filtros por loja e imagens ampliáveis transforma a entrega da IA em algo que posso revisar e aprovar. Na preparação de novas imagens para as lojas do Garfim, a IA me entregou uma página para revisar o material. Nela, posso comparar as peças, separar as versões de iPhone e Android, ampliar cada imagem e indicar exatamente o que precisa mudar. São **13 mídias: seis para a App Store, seis para a Google Play e um banner**. A página organiza esse conjunto e informa, logo no início, a situação da entrega: aguardando minha aprovação, sem envio às lojas naquela etapa. Esse detalhe da apresentação faz diferença no meu trabalho com IA. Para decidir, preciso enxergar o resultado, entender de onde ele veio e conseguir pedir uma correção sem ambiguidade. ## Uma entrega que consigo examinar As imagens foram preparadas a partir de um documento com os textos e a direção das peças. A galeria reúne o resultado em uma sequência numerada, com a loja e as dimensões de cada arquivo. Posso olhar todas as versões juntas ou filtrar apenas uma plataforma. Um clique abre a imagem maior; as setas permitem avançar entre as peças. Na entrega original, também há acesso aos arquivos individuais e ao pacote completo para download. Isso permite fazer duas leituras diferentes. Primeiro, vejo se o conjunto conta uma história coerente sobre o aplicativo. Depois, examino os detalhes de cada composição: tamanho do texto, recortes, contraste e o que aparece da interface. **[Explore a demonstração da galeria](/demos/aprovacao-midias-garfim/)** para experimentar os filtros e a ampliação. Ela reproduz as 13 peças apresentadas nesta etapa; a navegação não registra uma aprovação nem envia arquivos às lojas. ## Como um pedido de ajuste fica mais preciso A primeira peça apresenta a proposta de fotografar o prato e ver calorias e proteína. A segunda aproxima a mensagem da rotina brasileira, com PF e marmita. A terceira mostra que a pessoa pode ajustar a sugestão da IA. Essa ordem ajuda a avaliar a comunicação: a pessoa entende o benefício? Reconhece uma situação do cotidiano? Percebe que pode conferir e corrigir o resultado? Com cada imagem identificada, um pedido de revisão pode ser específico. Por exemplo: “Na peça 03 da Google Play, aumente o destaque dos controles de porção e mantenha o título.” É uma instrução sobre uma versão determinada, com uma mudança delimitada. Depois da alteração, consigo voltar à mesma peça e conferir o que mudou. **A forma de entregar o trabalho também determina a qualidade da próxima instrução.** ## O que é imagem gerada e o que vem do aplicativo Nesse material, a foto ilustrativa da refeição foi gerada com IA. Os painéis de interface vêm de capturas do Garfim funcionando em iPhone e Android, com dados de demonstração. Os recortes dessas telas foram organizados junto aos títulos e elementos visuais da marca. Assim, a composição pode destacar uma função sem precisar mostrar a tela inteira em tamanho pequeno. Essa distinção importa porque uma imagem de divulgação faz uma promessa sobre o produto. Um botão, uma informação ou um fluxo mostrado ali precisa corresponder ao que o aplicativo oferece. Usar a interface real dá uma base concreta para essa conferência. Os dados de demonstração também têm um papel: permitem apresentar uma rotina de uso sem expor o histórico alimentar de alguém. Os números visíveis nas peças ilustram o funcionamento do app; não são um teste de precisão do reconhecimento de alimentos. ## O que confiro antes de aprovar O pacote inclui verificações técnicas dos arquivos, como dimensões, formato e tamanho. Elas ajudam a evitar uma entrega com problemas de exportação. A revisão visual responde a outras perguntas: - **A mensagem é compreensível?** O título explica o benefício sem exigir que a pessoa já conheça o Garfim? - **A tela sustenta a promessa?** O trecho do aplicativo mostrado corresponde ao que o texto anuncia? - **A peça funciona pequena?** O benefício principal continua legível quando a imagem aparece como miniatura? - **A sequência tem propósito?** Cada imagem acrescenta uma informação útil à anterior? - **A versão está correta?** A peça da App Store usa a interface de iPhone, e a da Google Play usa a de Android? Esses critérios ligam a produção visual ao objetivo comercial: ajudar quem chega à página da loja a entender o aplicativo e decidir se quer experimentá-lo. O efeito dessas imagens sobre os downloads precisa ser medido depois da publicação; a galeria, por si só, não comprova aumento de conversão. ## Produzir, revisar e autorizar a próxima etapa O aviso de aprovação pendente deixa claro onde o trabalho está. As peças estão prontas para exame. O envio às lojas é uma etapa posterior, sobre o conjunto que eu aprovar. Nesse fluxo, a IA prepara o material e organiza as condições para que eu tome a decisão. Meu trabalho fica concentrado na mensagem, na fidelidade ao produto e nos ajustes necessários antes da publicação. Já escrevi sobre [as decisões que continuo tomando ao desenvolver com IA](/blog/desenvolver-com-ia-alem-do-codigo). A mesma lógica aparece aqui, na comunicação do produto: quanto mais concreta e fácil de inspecionar é a entrega, melhor consigo orientar o próximo passo. Uma galeria simples resolve uma parte importante dessa colaboração. Ela coloca o trabalho diante de mim, com referências claras para comparar, corrigir e aprovar. É esse tipo de entrega que torna a velocidade da IA útil na operação dos meus produtos. --- ## O Garfim chegou ao Google Play. Agora tem Android e iPhone. URL: https://luisjunior.ai/blog/garfim-lancado-google-play Publicado em 22 de outubro de 2026 · Lançamento · Construindo o Garfim, parte 14 O Garfim está disponível para Android. Depois dos testes e da espera, os links de download, o que dá para fazer no app e os aprendizados de chegar às duas lojas. Agora posso mandar o link para quem usa Android: **o Garfim está disponível no Google Play**. Parece uma frase pequena para o tanto de coisa que aconteceu até aqui. Teve construção, revisão, assinatura para acertar, comportamento para corrigir, gente para convidar para o teste e uma espera de 14 dias que mereceu [um texto próprio](/blog/garfim-testadores-14-dias-antes-do-lancamento). Agora existe uma página pública com o aplicativo e o botão de instalar. Na loja, o nome é **Garfim: Calorias por Foto**. Dá para começar com o plano gratuito. - [Baixar o Garfim no Google Play, para Android](https://play.google.com/store/apps/details?id=br.com.garfim). - [Baixar o Garfim na App Store, para iPhone](https://apps.apple.com/br/app/garfim-calorias-por-foto/id6819910416). A versão para iPhone já tinha sido [aprovada e lançada](/blog/garfim-aprovado-lancado-app-store). Com a chegada ao Android, consigo oferecer os dois caminhos para quem acompanhou a construção e quer experimentar. ## O que eu queria facilitar desde o começo Registrar a alimentação dá trabalho. Você come um prato com arroz, feijão, frango e salada, mas precisa transformar aquela refeição em nomes, quantidades e porções. Quando esse esforço se repete várias vezes por dia, ele passa a fazer parte da decisão de continuar ou abandonar o registro. A ideia do Garfim é diminuir o trabalho para começar. A pessoa fotografa a refeição, recebe uma estimativa de calorias e macronutrientes, confere o resultado e ajusta o que for necessário antes de salvar. Essa possibilidade de conferir é central. Uma foto mostra parte do prato. Ela pode esconder ingredientes, dificultar a leitura de uma quantidade ou não deixar evidente como o alimento foi preparado. Eu queria que a análise ajudasse a preencher o registro e que a pessoa tivesse espaço para corrigir a estimativa. O foco em alimentos brasileiros e nas porções do dia a dia vem dessa mesma preocupação. O aplicativo precisa fazer sentido diante da comida que está na mesa. É ali que uma ideia sobre IA vira uma ajuda concreta ou mais uma etapa para resolver. O Garfim também permite registrar por voz, buscar alimentos e usar código de barras. Há acompanhamento de água, peso, metas e histórico. São caminhos para continuar usando o diário em situações diferentes, inclusive quando tirar uma foto não é a opção mais conveniente. ## Dá para conhecer o aplicativo antes de assinar O plano gratuito faz parte do lançamento. Ele permite manter o diário e oferece uma cota compartilhada de um uso de foto ou voz por dia. Depois de usar essa cota, continuam disponíveis outros caminhos de registro, como a busca de alimentos e o código de barras. O Pro amplia o uso de IA. Os planos, os valores e as condições aparecem no aplicativo antes da compra, para a pessoa decidir com o contexto da própria rotina. Essa escolha tem relação com o tempo necessário para conhecer um produto assim. Um diário alimentar pode parecer interessante numa demonstração, mas seu valor aparece quando a pessoa tenta registrar uma refeição comum e voltar depois. Eu queria dar espaço para essa experiência. Expliquei essa decisão quando escrevi sobre [o plano gratuito do Garfim](/blog/garfim-plano-gratuito). Agora ela pode ser experimentada nas duas plataformas. Quem usa iPhone precisa de iOS 16.4 ou posterior; quem usa Android já encontra a disponibilidade para o seu aparelho na página do Google Play. ## Chegar às duas lojas exigiu trabalhos diferentes Parte do aprendizado foi entender que o mesmo produto atravessa processos distintos para chegar a cada plataforma. Na Apple, a revisão trouxe perguntas e correções. Na última rodada antes da aprovação, precisei trabalhar na apresentação da permissão da câmera e no carregamento das assinaturas. Também houve conferência do caminho de restauração de uma compra existente. Esses detalhes estão no [relato sobre a última negativa](/blog/garfim-ultima-negativa-camera-assinaturas). No Android, o teste fechado trouxe outra responsabilidade: organizar a participação de pessoas e atravessar o período exigido antes de solicitar acesso à produção. Isso precisava entrar no planejamento junto com as correções do aplicativo. As duas experiências me fizeram olhar com mais atenção para as passagens entre o produto e a loja. O aplicativo apresenta uma oferta, a loja conduz a compra e o resultado precisa voltar de um jeito compreensível. A pessoa pode desistir, a conexão pode falhar, uma assinatura pode precisar ser restaurada. Cada situação tem consequências para quem está tentando usar o serviço. Enquanto eu construía, esses caminhos podiam parecer detalhes ao lado da análise de uma refeição por IA. Perto do lançamento, ficou muito claro o peso de cada um. Quem não consegue entrar, entender uma permissão ou recuperar uma compra encontra um problema antes mesmo de chegar ao recurso principal. ## A IA acelerou a construção. Eu precisei aprender o restante também. Construir o Garfim com IA me permitiu avançar em muitas frentes. Também me colocou diante de decisões que continuavam precisando de entendimento: o que o aplicativo promete, como uma pessoa corrige uma estimativa, quais dados são necessários e como explicar o acesso gratuito e a assinatura. Uma implementação que parece correta ainda precisa ser conferida no percurso de uso. Um texto curto numa tela precisa dizer o suficiente para a pessoa decidir. Uma integração com a loja precisa lidar com mais situações do que uma compra que deu certo na primeira tentativa. Foi um aprendizado denso justamente porque essas partes se encontram. Uma decisão sobre o plano gratuito muda o que acontece depois que a cota de IA termina. Uma decisão sobre câmera muda o primeiro registro. A forma de apresentar uma falha de login muda a chance de alguém conseguir continuar. Aprendi bastante ao acompanhar essas consequências. A velocidade de produzir código ajuda, mas eu preciso compreender o produto que estou colocando no mundo. Se alguém tiver dificuldade, a responsabilidade de entender e resolver continua comigo. É por isso que venho registrando os bastidores. Quando a gente só vê o lançamento, pode imaginar um caminho mais direto do que ele foi. Escrever sobre as dúvidas, as revisões e os ajustes deixa visível uma parte do trabalho que o resultado final sozinho não mostra. ## Agora o link pode circular Com o Garfim nas duas lojas, o acesso muda. Quem encontra o projeto pode escolher seu aparelho, instalar e começar. O [site do Garfim](https://garfim.com.br/) reúne a apresentação e os detalhes do aplicativo. Isso me dá uma satisfação muito concreta: conseguir apresentar o produto funcionando e deixar a pessoa conhecer com as próprias mãos. Ao mesmo tempo, abre uma fase em que vou aprender com gente que chega sem ter acompanhado nenhuma das decisões de desenvolvimento. Quero entender onde o primeiro registro ainda pede explicação, o que facilita voltar ao diário e quais dificuldades aparecem no uso comum. Se você experimentar e encontrar algo confuso, contar o que estava tentando fazer já ajuda bastante. O contexto costuma ser mais útil do que uma nota isolada sobre o aplicativo. E fica meu agradecimento a quem participou dos testes. Conseguir reunir as pessoas e atravessar essa etapa deu trabalho; a disponibilidade de quem ajudou fez parte dessa chegada. Depois de tantas vezes explicar que o Android ainda estava em preparação, hoje consigo terminar de outro jeito: o Garfim está no Google Play. O link está aberto. --- ## Conseguir testadores e esperar 14 dias: a reta final do Garfim no Android. URL: https://luisjunior.ai/blog/garfim-testadores-14-dias-antes-do-lancamento Publicado em 22 de outubro de 2026 · Bastidores · Construindo o Garfim, parte 13 Reunir pessoas para testar o Garfim foi uma das partes difíceis do lançamento. O que aprendi sobre convites, tempo, responsabilidade e a espera pelo Google Play. Conseguir 14 pessoas para testar um aplicativo parece uma tarefa pequena quando você escreve isso numa lista. Para mim, foi uma das partes difíceis de colocar o Garfim no Android. O aplicativo podia estar funcionando, o registro por foto podia fazer sentido, a tela podia estar pronta. Ainda havia uma etapa que dependia de outras pessoas aceitarem dedicar um pedaço do dia a algo que eu estava construindo. E, depois, havia o tempo: 14 dias consecutivos de teste antes de poder pedir acesso à produção. Agora que o Garfim [já está no Google Play](/blog/garfim-lancado-google-play), dá para contar essa reta final com um pouco mais de distância. Ela me ensinou bastante sobre o trabalho que existe entre ter um aplicativo no próprio celular e conseguir distribuí-lo. ## O trabalho escondido em um convite Quando penso em alguém usando o Garfim, penso numa situação simples: a pessoa vai almoçar, fotografa o prato, confere a estimativa e registra a refeição. Só que, durante um teste fechado, existe um caminho anterior a esse almoço. A pessoa precisa entender o convite, entrar no teste com a conta certa, instalar uma versão que ainda está em preparação e encontrar um momento para experimentar. Se alguma coisa não funcionar, ainda precisa explicar o que aconteceu. Tudo isso concorre com trabalho, família, mensagens e com os aplicativos que ela já usa. Pedir esse tempo é bem diferente de mostrar uma tela pronta e ouvir que ficou bonita. Quem testa está ajudando a descobrir o que eu ainda não consegui enxergar. Há um esforço nessa ajuda, mesmo quando o procedimento de instalação parece curto. Foi essa dificuldade de reunir gente que ficou marcada para mim. O número, visto de fora, parece modesto. Na prática, cada participante é uma pessoa com a própria rotina. Eu estava envolvido com o Garfim o tempo todo; ninguém tinha obrigação de estar envolvido na mesma medida. Essa percepção muda a forma de organizar um teste. O convite precisa explicar para que serve o aplicativo, o que a pessoa pode experimentar e por onde contar uma dificuldade. Quanto mais trabalho eu deixo para ela descobrir sozinha antes de começar, mais difícil fica pedir a participação. ## Os 14 testadores da minha experiência e a regra da loja Vale acertar os números, porque eles se misturam facilmente. Quando falo da dificuldade de reunir 14 pessoas, estou falando do desafio que vivi com o Garfim. A exigência do Google aplicável a novas contas pessoais de desenvolvedor é de **pelo menos 12 testadores inscritos continuamente por 14 dias** antes da solicitação de acesso à produção. A [documentação oficial explica os critérios](https://support.google.com/googleplay/android-developer/answer/14151465?hl=pt-BR). Isso também ajuda a entender o que registrei no [primeiro texto sobre o teste fechado](/blog/garfim-testadores-teste-fechado-google-play): na conferência de 7 de outubro, havia doze pessoas inscritas continuamente, e a contagem estava no terceiro dia. O prazo tem uma consequência importante para quem está planejando lançar. Cumprir o período habilita a solicitação de acesso à produção. Ainda existe uma análise, com informações sobre como foi o teste e sobre a preparação do aplicativo. Chegar ao último dia não equivale a colocar automaticamente o download na loja. Eu precisava manter essas etapas separadas, inclusive ao falar do lançamento. Havia uma diferença entre conseguir participantes, cumprir o período, obter acesso à produção e conferir o aplicativo disponível para o público. Usar uma única palavra, “pronto”, para tudo isso escondia trabalho que ainda precisava acontecer. ## Tem uma parte que não acelera junto com o desenvolvimento Construir com IA dá uma sensação forte de velocidade. Você consegue discutir uma hipótese, transformar a ideia em uma tela e revisar a implementação num intervalo relativamente curto. Isso faz a gente se acostumar a procurar a próxima ação que destrava o projeto. Na etapa dos 14 dias, existe uma restrição que não responde a esse ritmo. Trabalhar mais numa noite não transforma o calendário do dia seguinte no calendário da semana seguinte. O prazo continua lá. Essa espera pesa porque o produto já é concreto. Você consegue abrir o aplicativo, registrar uma refeição, enxergar o que quer entregar. Ao mesmo tempo, ainda não pode mandar um link público de download para qualquer pessoa com Android. O trabalho avançou, mas a distribuição continua condicionada à etapa seguinte. Para mim, uma das lições foi tratar esse tempo como parte do desenvolvimento desde o planejamento. Se a conta precisa passar por teste fechado, recrutar participantes entra no caminho do lançamento. Deixar isso para depois de considerar todo o resto concluído cria uma espera que poderia ter sido prevista. Também muda o cuidado com uma data anunciada. Uma previsão precisa respeitar as dependências da loja, além das tarefas que consigo executar. Eu posso organizar meu trabalho e responder ao que aparecer. A decisão de liberação continua tendo seu próprio processo. ## O que merece atenção enquanto o prazo corre O risco de uma contagem é ela virar o centro da conversa. Fica fácil olhar para quantos dias faltam e perder a pergunta que justifica o teste: a pessoa consegue fazer o que veio fazer? No Garfim, há situações muito concretas para observar. A câmera abre quando a pessoa quer fotografar? Ela entende que pode corrigir a porção antes de salvar? Se a conexão falha, fica claro como tentar de novo? Quem decide começar grátis consegue continuar usando o diário? São perguntas que acompanham um produto de alimentação na vida real. Uma refeição acontece no meio do dia, às vezes com pressa. Um caminho que exige explicação demais disputa espaço com a própria vontade de registrar. Os ajustes que já relatei durante os testes incluíram o tratamento de cancelamento de compra, falhas temporárias de login e consentimento. Fechar uma oferta porque decidiu não assinar, por exemplo, precisa ser uma saída normal. Se o aplicativo reage como se algo inesperado tivesse quebrado, a pessoa pode ficar em dúvida sobre uma compra que nem concluiu. Esses detalhes ajudam a entender por que acompanhar o teste exige mais do que acompanhar o prazo. Um relato útil precisa chegar a uma decisão: entender o problema, tentar reproduzi-lo e corrigir o que faz sentido. A contagem, sozinha, não informa se essa parte do trabalho foi bem feita. ## O que eu levaria para o próximo aplicativo Eu colocaria a organização dos testes mais cedo no planejamento. Reservaria atenção para explicar a participação com clareza e para facilitar o retorno de quem encontrar um problema. Também separaria o tempo de desenvolvimento do tempo necessário para cumprir as etapas de distribuição. Outra coisa que levo é o respeito pelo esforço de quem aceita testar. Quando alguém ajuda nessa fase, está emprestando tempo e atenção a um produto que ainda procura seu lugar. O mínimo que posso fazer é dar contexto, ouvir com cuidado e usar o que aprendi para melhorar a experiência. Reunir os participantes e atravessar os 14 dias foi uma parte trabalhosa do lançamento do Garfim. Ficaria faltando um pedaço importante da história se eu publicasse só o botão de download e a notícia da aprovação. O botão finalmente está disponível. Antes dele, houve gente que topou entrar enquanto ainda era teste. Quero deixar esse agradecimento registrado junto com o lançamento. --- ## O ClipLeve chegou à App Store. O que aprendi até aqui. URL: https://luisjunior.ai/blog/clipleve-aprovado-lancado-app-store Publicado em 20 de outubro de 2026 · Lançamento · Construindo o ClipLeve, parte 3 Meu aplicativo para deixar vídeos mais leves no iPhone foi lançado. As decisões sobre imagem, originais, compras e acessibilidade que deram trabalho e mudaram minha forma de construir produtos. O ClipLeve está na App Store. Depois dos testes, da gravação no iPhone, dos pedidos de informação e de uma nova rejeição, chegou a aprovação. Em 20 de outubro de 2026, liberei a versão 1.0.0 para distribuição. Agora, quem acompanhou essa construção pode baixar o aplicativo. [**Baixar o ClipLeve na App Store**](https://apps.apple.com/br/app/clipleve-comprimir-v%C3%ADdeos/id6821932730). Ele funciona em iPhones com iOS 18 ou posterior. O download é gratuito, e a primeira versão leve salva e verificada também é gratuita, sem marca d'água. Depois dessa experiência, o Pro oferece assinatura anual ou acesso vitalício por pagamento único, com as condições apresentadas antes da compra. Chegar a esse ponto deu trabalho. Aprendi sobre vídeo, sobre o funcionamento das compras da Apple e sobre situações em que uma interface precisa explicar melhor o que está acontecendo. Também precisei rever o que eu considerava suficiente para dizer que uma tarefa estava concluída. Quero contar algumas dessas decisões porque elas ajudam a enxergar o que existe por trás de uma proposta que cabe em poucas palavras: deixar seus vídeos mais leves. ## A economia de espaço precisava vir acompanhada de confiança Um vídeo pode ocupar muito espaço e, ao mesmo tempo, ser algo que a pessoa não aceita perder. O registro de uma viagem, uma apresentação ou um momento em família não vira um arquivo sem importância porque está pesado. Por isso, o ClipLeve foi construído em torno de uma cópia. O original não é sobrescrito durante a compressão. A versão leve é um novo vídeo, que pode ser comparado antes de a pessoa decidir o que fazer com os dois. Essa escolha torna a jornada um pouco mais cuidadosa. Há uma estimativa antes do processamento, uma comparação visual e a confirmação do tamanho ao terminar. Depois, a pessoa pode guardar as duas versões ou seguir para a remoção do original, com as verificações e a confirmação do sistema. O tamanho menor é um resultado fácil de exibir. A confiança depende de outras respostas: consigo avaliar a imagem? Sei onde a cópia foi salva? Entendo qual arquivo será removido? Posso simplesmente manter os dois? Essas perguntas orientaram decisões que não aparecem em uma porcentagem de redução, mas fazem diferença quando o vídeo pertence a alguém. ## Um arquivo menor ainda pode ter uma imagem pior do que deveria Nos testes com HDR, apareceram perdas de detalhe nas regiões escuras. HDR é uma forma de registrar uma faixa maior de luminosidade: permite representar diferenças entre áreas claras e escuras que exigem cuidado durante a compressão. Aumentar apenas a quantidade de dados destinada ao vídeo não resolveu o problema de forma consistente. Foi necessário ajustar o controle de compressão e preservar uma alternativa para aparelhos que não oferecem o mesmo recurso. Esse trabalho reforçou uma regra prática para mim: medir os bytes e olhar para a imagem são verificações complementares. Um teste que comprova que o arquivo diminuiu ainda deixa aberta a pergunta sobre a qualidade do resultado. No aplicativo, as opções **Quase igual, Equilibrado e Bem menor** ajudam a escolher a redução. A comparação com um divisor sobre o vídeo permite observar a diferença diretamente. A gravação de origem, o movimento e os detalhes da cena influenciam o resultado; por isso, as estimativas não são uma garantia. Também existem limites de compatibilidade. A versão de lançamento não aceita modo Cinema, câmera lenta e vídeos espaciais. Deixar isso claro evita que a pessoa descubra uma restrição depois de esperar por uma operação que o app não consegue concluir. Foi um aprendizado sobre a própria promessa do produto. Eu precisava explicar o que a pessoa podia escolher e avaliar, com palavras que fizessem sentido antes de qualquer discussão sobre formato ou configuração de compressão. ## Salvar e confirmar o salvamento são trabalhos diferentes Criar o arquivo leve não encerra a operação. Ele ainda precisa chegar ao Fotos, e o aplicativo precisa conferir a cópia salva. No ClipLeve, a verificação continua depois desse salvamento. O projeto também trata situações em que uma operação pode ter sido concluída, mas a confirmação ficou incerta. Repetir o salvamento sem conferir poderia criar outra cópia e aumentar a confusão. Pense em um aplicativo interrompido no meio de uma etapa. Quando ele volta, precisa lidar com o que de fato aconteceu, inclusive quando o último estado conhecido ficou incompleto. Esse tipo de situação exige mais trabalho do que desenhar apenas o percurso em que tudo responde na hora. Aprendi a dar mais atenção a essas fronteiras: o momento em que o arquivo foi produzido, o momento em que o Fotos o recebeu e o momento em que o app conseguiu confirmar o resultado. Para quem usa, tudo parece uma única ação. Por dentro, cada passagem precisa ser tratada. Esse cuidado fica ainda mais importante antes de oferecer a remoção do original. A interface só deve conduzir a uma decisão quando consegue apresentar informação suficiente para que a pessoa entenda o que está fazendo. ## Um vídeo menor não significa espaço livre imediato Se o original continua no Fotos e uma cópia acaba de ser adicionada, os dois ocupam espaço. Mesmo quando o original vai para Apagados, ele permanece ali durante o período de recuperação. Isso cria uma diferença que precisava ficar visível: **redução do tamanho do arquivo e espaço disponível no aparelho são medidas distintas**. Seria fácil mostrar a economia calculada e deixar a pessoa concluir que aquela quantidade de espaço já voltou. Mas ela poderia abrir os Ajustes do iPhone e encontrar outro número. A orientação do ClipLeve acompanha esse percurso. Quando a pessoa decide remover o original, há a confirmação do sistema. O app não faz a exclusão permanente. Com o Fotos do iCloud, a remoção também pode se refletir em outros aparelhos; Apagados oferece uma possibilidade de recuperação, mas não substitui um backup. Essa foi uma das partes em que a comunicação mais influenciou o produto. Precisava explicar o resultado de uma ação, o que ainda faltava acontecer e qual decisão continuava nas mãos da pessoa. ## Compras precisavam ser testadas além do primeiro pagamento A oferta do ClipLeve inclui uma assinatura anual e uma compra vitalícia. Para a pessoa, a expectativa é direta: escolher, entender o preço e receber o acesso correspondente. Para quem desenvolve, há mais estados para considerar. Exercitei compras e restaurações no ambiente de testes da Apple. Também precisei distinguir uma compra válida do carregamento do catálogo que apresenta novas ofertas. Um exemplo apareceu ao reabrir o aplicativo sem internet: um acesso vitalício já restaurado continuava ativo, mas a tela avisava que a loja estava indisponível. A mensagem juntava duas situações diferentes. O catálogo de preços podia estar indisponível, enquanto o direito de uso já era conhecido pelo aplicativo. Esse caso mostrou como uma informação tecnicamente verdadeira pode confundir quando aparece no lugar errado. Quem já comprou pode interpretar um aviso sobre a loja como perda do acesso. Corrigir a experiência exigiu separar esses estados também na comunicação. Os testes de compra foram feitos em sandbox, o ambiente da Apple para simular essas transações sem cobrança real. A aprovação para distribuição acrescenta uma etapa importante, mas o acompanhamento de compras no uso público continua fazendo parte do trabalho depois do lançamento. ## Acessibilidade mudou a forma de conferir a jornada Uma comparação de vídeos é bastante visual. Isso torna ainda mais importante conferir os controles e as informações disponíveis para quem navega de outra maneira. Percorri a jornada com o VoiceOver no simulador: escolher o vídeo, criar a versão leve, salvar, comparar e chegar à decisão sobre o original. Também foram revisados áreas de toque, contraste e textos com letras ampliadas. Com um leitor de tela, o nome de um botão passa a carregar parte do contexto que o desenho oferece a quem está olhando. A ordem de navegação precisa fazer sentido, e um controle indisponível precisa ser compreensível naquele estado. O consentimento para remover o original foi um exemplo concreto. A opção começava desmarcada, e a ação de remoção só ficava disponível depois da escolha. Conferir se os dois elementos eram alcançáveis pelo VoiceOver ajudava a avaliar o percurso inteiro. Esse trabalho ampliou meu critério de conclusão. Além de conferir se uma ação respondia, eu precisava verificar se era possível encontrá-la e entender sua consequência. ## A revisão da loja também fez parte da construção A primeira resposta da Apple pediu informações adicionais e uma demonstração em aparelho físico. Gravei o percurso no próprio iPhone, incluindo planos, compra de teste e criação de uma versão leve com o original preservado. Depois veio a negativa pelo subtítulo em inglês. Troquei “Shrink big videos on iPhone” por “Shrink your biggest videos” e reenviei o mesmo aplicativo. Contei esse percurso com mais detalhe no [artigo sobre a nova rejeição](/blog/clipleve-nova-rejeicao-subtitulo-app-store). A Apple aprovou a versão 1.0.0, a assinatura anual, o acesso vitalício e o grupo de assinatura. O lançamento estava configurado para liberação manual. Em 20 de outubro, acionei essa liberação para Brasil e Estados Unidos e, depois, conferi a página pública brasileira. Esse intervalo entre aprovação, liberação e disponibilidade é pequeno no relato, mas importante na prática. Só depois de encontrar a página pública eu podia colocar aqui um link de download acompanhado do anúncio de que o produto chegou à loja. ## O que levo dessa construção Construir com ajuda de IA me permite avançar por muitas partes de um projeto. O ClipLeve também mostrou quanto trabalho existe em formular os critérios, examinar as evidências e perceber o que uma resposta ou um teste ainda não demonstrou. Um teste aprovado responde às condições que foram exercitadas. Uma demonstração comprova o percurso mostrado. Uma compra em ambiente de testes ajuda a validar a integração. Cada evidência tem um alcance, e entender esse alcance melhora a próxima decisão. Foi assim com as sombras dos vídeos HDR, com a confirmação da cópia, com o aviso de loja indisponível e com o subtítulo em outro idioma. Eram problemas diferentes, encontrados em lugares diferentes. O avanço veio de observar cada um com atenção e transformar o aprendizado em uma mudança concreta. Hoje, o ClipLeve chegou à App Store com uma proposta que consigo explicar melhor porque precisei examinar seus detalhes: ajudar a encontrar os vídeos maiores, criar versões mais leves no próprio aparelho e dar à pessoa condições de decidir o que preservar. Não exige conta, não exibe anúncios e não envia os vídeos a servidores do produto. Se um original estiver apenas no iCloud, o download depende da autorização da pessoa antes de continuar. A primeira versão leve gratuita permite conhecer esse percurso com um vídeo seu. Você pode começar por um arquivo que ocupa bastante espaço, comparar a imagem e guardar as duas versões enquanto avalia o resultado. Depois de tantas rodadas de preparação, é muito bom poder terminar esse relato com um convite concreto: [o ClipLeve já pode ser baixado na App Store](https://apps.apple.com/br/app/clipleve-comprimir-v%C3%ADdeos/id6821932730). --- ## O ClipLeve foi rejeitado de novo. Dessa vez, por uma palavra. URL: https://luisjunior.ai/blog/clipleve-nova-rejeicao-subtitulo-app-store Publicado em 20 de outubro de 2026 · Produto · Construindo o ClipLeve, parte 2 Depois de gravar a demonstração no iPhone e responder à Apple, um termo no subtítulo em inglês trouxe outra negativa. O que esse percurso me ensinou sobre preparar um produto para a loja. Depois de testar a compressão, conferir o salvamento dos vídeos, exercitar compras e gravar uma demonstração no iPhone, recebi outra negativa da Apple. O motivo estava em uma frase curta da página do aplicativo: o subtítulo em inglês continha a palavra “iPhone”. O ClipLeve é um aplicativo para iPhone. Por isso, a frase parecia uma descrição natural do produto. Mas aquele campo da loja tem regras próprias, e a Apple apontou o uso do termo pela diretriz 5.2.5. No português, o subtítulo era “Reduza seus maiores vídeos”. No inglês, “Shrink big videos on iPhone”. A correção coube em uma linha. O aprendizado ocupou bem mais espaço. Hoje, com o [ClipLeve aprovado e lançado](/blog/clipleve-aprovado-lancado-app-store), vale voltar a essa etapa. Houve dois pedidos diferentes no caminho, e entender exatamente o que cada um exigia foi parte do trabalho. ## Primeiro, eu precisava mostrar o aplicativo funcionando No [primeiro texto sobre o ClipLeve](/blog/clipleve-videos-mais-leves-no-iphone), contei algumas decisões sobre qualidade da imagem, preservação do original e acessibilidade. A preparação técnica já envolvia bastante coisa que não aparece quando alguém vê apenas um botão para diminuir um vídeo. Em 13 de outubro, a Apple respondeu à submissão com um pedido de informações adicionais, associado à diretriz 2.1. A mensagem citava o histórico ainda limitado da conta de desenvolvedor e pedia uma demonstração gravada em um aparelho físico. Também era necessário explicar a finalidade do aplicativo, o público, o acesso aos recursos, as ferramentas externas utilizadas, o funcionamento entre regiões e o que cada compra liberava. Os recursos pagos precisavam aparecer de forma compreensível, com as informações da oferta e os links de termos e privacidade. A mensagem não apontava uma falha específica na compressão ou no salvamento. Ler essa diferença com atenção evitava começar a mexer em partes do aplicativo que não tinham sido questionadas. O que faltava naquele momento era entregar à revisão uma explicação acompanhada de evidência. Quem desenvolve conhece os caminhos da própria interface. Sabe onde ficam os planos, o que a versão gratuita permite e por que determinado botão ainda não apareceu. A pessoa que recebe o aplicativo para revisar precisa encontrar tudo isso a partir do material enviado. Cada dependência que eu deixasse implícita poderia dificultar a avaliação. ## Uma gravação curta exigiu uma jornada inteira Gravei a demonstração pela captura de tela do próprio iPhone. O percurso começava na abertura do ClipLeve, passava pela apresentação dos planos e por uma assinatura no ambiente de testes da Apple, e seguia até a criação e o salvamento de uma versão leve. Usei vídeos sintéticos, preparados para a verificação. Assim, podia mostrar a jornada e conferir o resultado sem usar lembranças pessoais como material de teste. A gravação enviada tinha 77 segundos. Nela, um vídeo de **42,4 MB gerou uma cópia de 7,5 MB**, com o original preservado. Esse resultado dizia respeito àquele arquivo. A redução depende da gravação e da opção escolhida; transformar um exemplo em promessa para todos os vídeos seria esconder uma parte importante da experiência. O trecho mais útil da demonstração era a continuidade. Dava para acompanhar a entrada no app, entender a oferta, ver o acesso Pro ativo e chegar à cópia salva. A compra mostrada era de teste, sem cobrança real. Em 15 de outubro, a gravação e as sete respostas foram incluídas nas notas da versão e na conversa com a Apple. Reenviei o mesmo pacote do aplicativo. A versão, a assinatura anual, o acesso vitalício e o grupo de assinatura voltaram a aguardar revisão. Preparar esse material me fez olhar para o produto de fora. Uma sequência que precisa de muita explicação pode estar escondendo uma dúvida da interface. Mesmo quando o percurso está claro, registrar os passos ajuda a conferir se a descrição comercial corresponde ao que a pessoa realmente consegue fazer. ## A experiência do Garfim deveria ter entrado antes Eu já havia recebido um pedido semelhante na revisão do Garfim. A demonstração em aparelho físico e os esclarecimentos sobre o produto não eram uma surpresa completa. Ainda assim, esse contexto não entrou a tempo na preparação inicial do ClipLeve. Houve retrabalho que poderia ter sido antecipado. Essa foi uma das lições mais úteis do processo. Trabalhar em mais de um produto só gera aprendizado acumulado quando uma experiência muda a preparação do próximo. Deixar a resposta resolvida em uma conversa antiga não garante que ela será lembrada no momento de um novo envio. Passei a tratar o material de revisão como parte da entrega: o caminho demonstrável, as explicações sobre compras, os arquivos de exemplo e as informações que permitem entender o produto. É o tipo de trabalho que fica fácil adiar enquanto há um problema de código mais visível para resolver. No entanto, ele também determina se o aplicativo consegue chegar às pessoas. ## A segunda negativa estava no subtítulo em inglês Em 17 de outubro, veio outra resposta. Dessa vez, o ponto registrado era o uso de “iPhone” no subtítulo em inglês, pela diretriz 5.2.5, de propriedade intelectual. Troquei **“Shrink big videos on iPhone”** por **“Shrink your biggest videos”**. A nova frase manteve a ideia central: reduzir os vídeos que mais ocupam espaço. O subtítulo em português já seguia essa direção. Conferi o campo salvo, respondi à Apple e reenviei os itens para revisão. Não houve alteração de código, recompilação ou novo envio de binário nessa correção. O aplicativo continuava sendo a versão 1.0.0, build 1. A palavra ocupava pouco espaço, mas fazia parte do material submetido. Nome, subtítulo, imagens, descrição e informações de compra também entram na avaliação. As [diretrizes de revisão da Apple](https://developer.apple.com/app-store/review/guidelines/#intellectual-property) tratam desse conjunto. O cuidado aqui é entender o motivo concreto da mensagem. O caso não significa que a compatibilidade com o iPhone deixou de poder ser explicada. O apontamento foi sobre aquele uso no subtítulo, e foi ali que a correção aconteceu. ## Cada idioma precisa de uma revisão própria Uma tradução pode soar natural e, ainda assim, criar uma pendência que não existia no texto original. Foi exatamente o que aconteceu: o português descrevia o benefício, enquanto o inglês acrescentava o nome do aparelho. Isso mudou a forma como passei a olhar para a localização da página. Conferir o português não encerrava a revisão do inglês. Também precisava comparar o sentido das promessas, os campos utilizados e a correspondência com os recursos entregues. O mesmo cuidado vale para as imagens da loja. Uma arte legível no arquivo original pode perder informação no corte da prévia. Durante a preparação do ClipLeve, as artes de cabeçalho e de busca precisaram de composições diferentes porque o texto não se comportava da mesma forma nos dois espaços. Esses detalhes têm uma consequência muito concreta: o visitante conhece o aplicativo pelo que a loja mostra. Se a informação fica cortada, ambígua ou diferente entre idiomas, essa dificuldade chega antes mesmo da instalação. ## O que ficou para o próximo envio Eu saí dessa etapa com uma ideia mais precisa do que significa estar pronto para submeter um aplicativo. Os testes precisam mostrar o que foi exercitado. A apresentação precisa corresponder ao produto. As notas de revisão precisam permitir que outra pessoa percorra os recursos. E cada idioma precisa ser conferido dentro dos campos em que será publicado. Também aprendi a responder a uma negativa com uma sequência mais objetiva: ler o apontamento inteiro, localizar a informação ou o comportamento mencionado, corrigir, conferir o resultado e explicar o que mudou. No segundo retorno do ClipLeve, essa sequência levou a uma alteração pequena e verificável. A aprovação veio depois. A história do lançamento está no [próximo capítulo](/blog/clipleve-aprovado-lancado-app-store). Mas eu quis registrar essa passagem porque ela ajuda a dimensionar o trabalho de colocar um produto no mundo: às vezes, depois de resolver problemas difíceis de mídia, compras e segurança dos arquivos, ainda falta revisar uma única linha. --- ## O Garfim foi aprovado. E já está na App Store. URL: https://luisjunior.ai/blog/garfim-aprovado-lancado-app-store Publicado em 16 de outubro de 2026 · Lançamento · Construindo o Garfim, parte 12 Depois das revisões, dos testes e do reenvio, o Garfim chegou ao iPhone. O que está disponível no lançamento e o trabalho que começa com as primeiras pessoas usando. O Garfim está disponível na App Store. Depois das perguntas da primeira revisão, de uma nova negativa e do reenvio com as correções, veio a aprovação. Agora existe um passo simples para quem acompanhou essa construção: baixar e experimentar. O aplicativo se chama **Garfim: Calorias por Foto** na loja. Está disponível para iPhone, com iOS 16.4 ou posterior, e tem um plano gratuito para começar. [Baixar o Garfim na App Store](https://apps.apple.com/br/app/garfim-calorias-por-foto/id6819910416). ## A ideia chegou à rotina de quem pode usá-la O ponto de partida era facilitar o registro alimentar. Fotografar uma refeição pode reduzir o trabalho de procurar e preencher cada item, mas a imagem não conta tudo: quantidade, ingredientes e preparo precisam ser conferidos. Por isso, o percurso do Garfim inclui revisar a estimativa e ajustar o que for necessário antes de salvar. A IA ajuda a começar o registro. A pessoa continua tendo como corrigir o resultado. Ao longo da construção, o produto ganhou outros caminhos para manter o diário: busca de alimentos, código de barras, favoritos e repetição de refeições, além do acompanhamento de água e peso. Essa continuidade importa porque nem toda refeição será registrada por foto. O lançamento coloca essas decisões em contato com a rotina de pessoas que não participaram do desenvolvimento. É aí que vou aprender quais etapas ajudam e quais ainda pedem explicação demais. ## Dá para começar sem assinatura O plano gratuito mantém o diário e seus caminhos de registro, com uma cota compartilhada de um uso de foto ou voz por dia. Usar essa cota não impede continuar preenchendo o diário pelas outras opções. O Pro amplia o uso de IA. Os planos, os valores e as condições da oferta aparecem no aplicativo antes de uma compra. Quem começa grátis pode conhecer o produto antes de decidir se precisa dessa ampliação. Essa escolha foi importante durante a preparação. Um registro alimentar precisa de tempo para mostrar se cabe na vida de alguém. Eu queria permitir essa descoberta sem colocar uma decisão de assinatura na entrada. Expliquei esse raciocínio no texto sobre [por que o Garfim ganhou um plano gratuito](/blog/garfim-plano-gratuito). ## Aprovação e disponibilidade são etapas diferentes Receber a aprovação foi um marco. Conferir a página pública da App Store e encontrar o aplicativo disponível para download completou a passagem para o lançamento. O build aprovado foi o 10. Antes dele, a [última rodada de revisão](/blog/garfim-ultima-negativa-camera-assinaturas) apontou a apresentação da permissão da câmera e uma falha no carregamento das assinaturas. A resposta exigiu ajustes e conferências em aparelhos, incluindo a restauração de uma compra existente. Agora posso anunciar o download no iPhone. O Android tem seu próprio percurso de testes e publicação; a disponibilidade em uma loja não antecipa a liberação na outra. ## Lançar muda as perguntas Durante a preparação, boa parte das perguntas era sobre conseguir concluir o percurso: abrir a câmera, revisar uma refeição, salvar no diário, carregar um plano e recuperar uma assinatura. Com o produto disponível, aparecem outras: o primeiro registro é fácil de entender? A correção da estimativa fica evidente? A pessoa encontra o diário no dia seguinte? O plano gratuito entrega continuidade quando a cota de IA termina? Vou acompanhar essas situações e as falhas que aparecerem no uso. A aprovação da loja encerra uma etapa de distribuição; o acompanhamento do produto continua depois dela. Construir o Garfim com IA envolveu decisões de interface, acesso, dados, cobrança e comunicação, além de escrever código. Os bastidores publicados até aqui registram esse percurso. A partir de agora, ele também pode ser conhecido pelo aplicativo funcionando no seu iPhone. --- ## A última negativa do Garfim: câmera, assinatura e o caminho inteiro. URL: https://luisjunior.ai/blog/garfim-ultima-negativa-camera-assinaturas Publicado em 16 de outubro de 2026 · Lançamento · Construindo o Garfim, parte 11 A Apple apontou dois problemas na revisão de 15 de outubro. O que precisei conferir entre explicar uma permissão, carregar os planos e recuperar uma compra. O Garfim já tinha passado pela primeira rodada de perguntas da Apple. Eu havia preparado a demonstração e explicado o funcionamento do aplicativo. Em 15 de outubro, chegou outra negativa, desta vez com dois pontos concretos: a apresentação da permissão da câmera e uma falha ao carregar as opções de assinatura. A revisão havia sido feita em um iPad Air. O aplicativo precisava funcionar para quem chegasse sem conhecer sua história, com as condições que o revisor encontrasse naquele momento. Essa foi a última negativa antes da aprovação. Ela me obrigou a conferir o caminho inteiro, incluindo as pequenas transições entre uma tela e outra. ## Explicar a câmera também faz parte da permissão Fotografar uma refeição é um dos caminhos principais do Garfim. Antes de abrir o pedido de acesso à câmera feito pelo iOS, o aplicativo mostrava uma explicação com os botões “Permitir câmera” e “Voltar”. A Apple pediu uma mudança nessa etapa: usar uma ação neutra, como “Continuar”, e conduzir diretamente ao diálogo do sistema, sem oferecer o adiamento na própria explicação. Parece uma troca pequena de palavras, mas cada tela tem uma responsabilidade. A tela do aplicativo explica por que a câmera será usada. A decisão de conceder ou negar o acesso acontece no pedido do iOS. Um botão chamado “Permitir câmera” antes desse pedido pode misturar as duas coisas. O ajuste não elimina a escolha da pessoa. O sistema continua oferecendo a recusa. Ele torna mais claro em que momento a autorização é realmente solicitada. Depois da correção, conferi esse percurso com uma instalação nova. Reabrir um aplicativo que já recebeu permissão não reproduz a experiência de quem está usando pela primeira vez. ## A assinatura precisa aparecer antes de poder ser comprada O segundo ponto era mais direto: a tela de assinatura apresentou um erro e não mostrou as opções, mesmo com conexão à internet. O parecer registrava o que aconteceu, sem determinar uma causa única. Seria precipitado transformar esse sintoma em uma explicação definitiva sobre a loja, a rede ou o aplicativo. Também havia uma orientação útil da Apple: os produtos de assinatura não precisavam estar previamente aprovados para que a equipe pudesse testá-los durante a revisão. Esperar apenas pela aprovação dos planos não resolveria, por si só, a falha observada. Na nova validação, conferi o carregamento das opções depois de fechar e reabrir o app e a restauração de uma compra existente. A restauração foi confirmada tanto no aplicativo quanto no servidor que acompanha o acesso ao Pro. São verificações diferentes. Mostrar o preço, concluir uma compra e reconhecer um direito já adquirido pertencem ao mesmo percurso, mas uma etapa funcionando não comprova todas as outras. ## O que foi testado no novo envio A preparação do build 10 incluiu 107 testes automatizados, a permissão da câmera depois de reinstalar o aplicativo e uma análise real de refeição por foto em iPhone. A busca de alimentos também foi corrigida e conferida em dois iPads. Havia uma assinatura ativa na conta usada para validar a restauração. Por isso, não repeti naquele ciclo uma compra nova do início ao fim. Essa diferença ficou registrada: restaurar um acesso existente não é o mesmo teste que assinar pela primeira vez. Registrar o limite do teste ajuda a decidir o que ainda precisa ser observado. Um número de testes aprovados tem utilidade quando sabemos quais situações ele cobre. Com as conferências concluídas, respondi aos dois pontos do parecer e reenviei o aplicativo e os planos para revisão. ## A experiência acontece entre as telas Essa rodada deixou uma lição concreta para mim. Uma boa explicação pode terminar em um botão ambíguo. Uma tela de planos bem desenhada pode ficar inutilizável se as opções não chegarem. O trabalho precisa acompanhar o que a pessoa tenta fazer até o resultado. No Garfim, isso significou olhar para uma primeira instalação, uma permissão ainda não concedida, um aplicativo reaberto e uma compra já existente. São estados comuns na vida de quem usa, embora sejam fáceis de deixar de fora quando estamos concentrados em construir a próxima funcionalidade. A [primeira negativa](/blog/garfim-primeira-negativa-app-store) havia exigido tornar o produto compreensível para a revisão. A última exigiu demonstrar que esses caminhos podiam ser percorridos. No capítulo seguinte, veio a aprovação e a chegada à App Store. --- ## ClipLeve: o cuidado por trás de um vídeo mais leve. URL: https://luisjunior.ai/blog/clipleve-videos-mais-leves-no-iphone Publicado em 12 de outubro de 2026 · Produto · Construindo o ClipLeve, parte 1 Qualidade da imagem, segurança do original e navegação com VoiceOver: as decisões que estão dando forma ao meu aplicativo para iPhone. Diminuir um vídeo pode parecer uma tarefa resolvida quando o arquivo final ocupa menos espaço. Mas vale olhar para a imagem: os detalhes das partes escuras continuam lá? O áudio foi preservado? A cópia foi salva corretamente antes de você decidir apagar o original? Essas perguntas estão no centro do ClipLeve, meu aplicativo para criar versões menores de vídeos no próprio iPhone, sem enviá-los a servidores do produto. A primeira versão está em preparação para a App Store. Quero apresentar algumas decisões dessa construção porque elas mostram o trabalho que existe por trás de uma tarefa aparentemente simples. ## O tamanho conta apenas parte da história Nos testes com vídeos HDR, que registram uma faixa maior de luminosidade, apareceram perdas de detalhe em regiões escuras. Aumentar apenas a taxa de dados usada na compressão não resolveu o problema de forma consistente. Foi necessário ajustar o controle de compressão e manter uma alternativa para aparelhos que não oferecem o mesmo recurso. Isso reforçou um critério do projeto: comparar a imagem produzida, além de medir os bytes economizados. No ClipLeve, as opções Quase igual, Equilibrado e Bem menor apresentam estimativas antes do processamento. Depois, a pessoa vê o tamanho medido e pode comparar as versões arrastando um divisor sobre o vídeo. A redução varia conforme a gravação. Dar acesso à comparação permite decidir se aquele resultado serve para uma lembrança que será guardada ou para um arquivo que será compartilhado. ## Apagar o original exige outra conferência O aplicativo verifica a versão produzida e confere a cópia salva no Fotos. Só então a pessoa decide se mantém as duas ou autoriza a remoção do original, com confirmação do sistema. Mesmo depois de mover um vídeo para Apagados, o espaço pode não voltar imediatamente. Essa diferença precisa aparecer na orientação. Exibir o tamanho reduzido como se já fosse espaço liberado criaria uma expectativa errada. Para testar o percurso, usamos vídeos sintéticos, preparados para a verificação. Assim é possível exercitar inclusive a remoção sem envolver lembranças pessoais. ## Como comparar sem depender da imagem? Essa pergunta levou a uma jornada com o VoiceOver, o leitor de tela do iPhone. Com ele ativado, a pessoa navega pelos elementos e escuta seus nomes e estados. No simulador, o teste percorreu a escolha do vídeo, a criação e o salvamento da versão leve, a comparação e a decisão sobre o original. O comando de remoção começava desabilitado e só ficava disponível depois de marcar o consentimento. Conferimos se ambos eram alcançáveis pelo leitor de tela. Um botão pode estar visível e ainda ser difícil de entender sem o contexto ao redor. Por isso, avaliar acessibilidade pede atenção ao nome anunciado, à ordem da navegação e à informação sobre o que está disponível naquele momento. Também ajustamos áreas de toque, contraste e a ajuda com letras ampliadas. Nessa jornada, a navegação chegou aos controles dos planos, mas não houve uma compra pelo VoiceOver: os preços não estavam carregados naquela sessão. ## A loja indisponível não deveria contradizer um acesso válido Outra situação apareceu ao reabrir o aplicativo sem internet. O acesso vitalício já restaurado permanecia ativo, mas a tela avisava que a loja estava indisponível. A mensagem confundia duas coisas: carregar preços para uma nova compra e reconhecer um acesso existente. Ajustamos o comportamento para que uma compra válida não dependa do carregamento do catálogo. A correção passou nos testes locais; a mensagem ajustada ainda precisava ser reconferida no aparelho sem conexão. É um exemplo de como a experiência depende de explicar corretamente um estado que o sistema já conhece. > Em 12 de outubro: o pacote 1.0.0 passou pela validação técnica da Apple, e compras e restaurações dos planos anual e vitalício foram exercitadas no ambiente de testes. Ainda faltavam cenários de expiração, reembolso e compra interrompida, além de verificações no aparelho, antes da submissão à revisão e do lançamento. ## A decisão continua com quem usa O [ClipLeve](https://clipleve.com/) foi pensado para iPhones com iOS 18 ou posterior. Comparar a imagem, conferir o arquivo salvo e entender os controles pelo VoiceOver são partes de uma mesma preocupação: dar à pessoa condições de decidir o que fazer com os próprios vídeos. Uma operação pode funcionar por dentro e ainda deixar dúvida na tela. Desenvolver esse produto tem exigido cuidar das duas coisas: do resultado e de como alguém consegue avaliá-lo antes de seguir. --- ## Por que restaurar uma assinatura pode falhar em outra conta. URL: https://luisjunior.ai/blog/garfim-assinaturas-iphone-testflight Publicado em 12 de outubro de 2026 · Produto · Construindo o Garfim, parte 9 Uma assinatura ativa pode parecer perdida quando a compra pertence a outra conta do aplicativo. O que esse caso me fez ajustar no Garfim. Uma assinatura estava ativa, mas pertencia a outra conta do Garfim. Na tela do iPhone, a mensagem dizia apenas: “A loja não confirmou o pagamento”. Esse foi um dos problemas encontrados durante a preparação de uma demonstração do aplicativo. A frase juntava situações diferentes e deixava a pessoa sem saber como continuar. O caso levou a ajustes que chegaram ao grupo interno do TestFlight em 9 de outubro. Também ajuda a explicar uma parte pouco visível das assinaturas: a compra na loja e a conta dentro do aplicativo precisam se encontrar corretamente. ## Trocar de login não transfere a compra Um mesmo aparelho pode ser usado com contas diferentes do Garfim. A assinatura, porém, precisa continuar vinculada à conta que a possui. No episódio, os registros mostravam uma compra de teste ativa na conta anterior e nenhuma compra verificada na nova. Tentar restaurar naquela nova conta encontrava um conflito de titularidade. A restauração serve para recuperar o acesso de uma compra existente. Transferi-la entre contas é outra operação, com outras consequências. Confundir as duas coisas pode entregar o acesso à pessoa errada ou fazer parecer que uma assinatura desapareceu. Na versão 7, o Garfim passou a conferir compras ativas antes de iniciar uma nova tentativa e a explicar melhor os conflitos entre contas. ## Uma espera sem fim também é um problema de interface Durante a investigação, apareceram tentativas com a indicação de que já havia uma compra em andamento. Não foi possível estabelecer a causa da ausência da resposta inicial da loja. Mesmo assim, havia uma decisão de interface a tomar: quanto tempo deixar alguém olhando para uma ação que não termina? O novo fluxo encerra essa espera na tela após 60 segundos e orienta a restauração. Uma confirmação que chega mais tarde ainda pode ser verificada. O acesso só é liberado depois da conferência pelo servidor. A diferença é importante: parar de exibir uma espera não significa concluir que a compra falhou. A interface precisa dar um próximo passo sem inventar uma resposta que ainda não recebeu. ## Falha de comunicação não determina o estado da assinatura Nos dias 11 e 12 de outubro, o trabalho continuou na verificação com a Apple. Acrescentei ao projeto uma nova tentativa limitada para determinadas falhas temporárias e um tratamento para consultas sem informações de uma assinatura já conhecida. Nessa segunda situação, o sistema só aceita o encerramento quando o período anteriormente verificado já terminou. Uma resposta vazia não basta para retirar um acesso ainda válido. Esse cuidado separa duas perguntas que às vezes se misturam: o serviço respondeu? E qual é a situação da compra? Uma falha na primeira não resolve a segunda. > Situação até 12 de outubro: a versão 7 havia chegado ao TestFlight, o ambiente de testes da Apple. O fluxo e os ajustes posteriores ainda exigiam validação no aparelho; isso não representava aprovação para lançamento público. ## O que esse episódio mudou Para mim, o aprendizado está na precisão do caminho oferecido à pessoa. “Restaurar”, “tentar novamente” e “entrar na conta correta” orientam ações distintas. Escolher a mensagem certa exige entender o que aconteceu por trás dela. É uma parte do desenvolvimento que costuma caber em poucas palavras na tela. Para chegar a essas palavras, preciso acompanhar a compra, a conta, o tempo de resposta e a possibilidade de a confirmação chegar depois. --- ## Quando um aplicativo pode dizer que sua conta foi excluída? URL: https://luisjunior.ai/blog/garfim-confirmacao-exclusao-conta Publicado em 12 de outubro de 2026 · Produto · Construindo o Garfim, parte 10 Receber um pedido de exclusão e concluir a remoção são etapas diferentes. Como organizei a confirmação do Garfim para respeitar essa diferença. Você pede para excluir uma conta e recebe uma mensagem de confirmação. Ela confirmou o pedido ou avisou que os dados já foram apagados? A diferença muda o que você pode esperar a partir dali. No Garfim, existe um período de sete dias em que a conta ainda pode ser recuperada. A exclusão definitiva acontece depois. Em 8 de outubro, acrescentei à implementação um e-mail para esse segundo momento. Ele só deve ser preparado quando a remoção foi concluída. Essa pequena mensagem exigiu pensar na ordem das operações e no que fazer quando o envio falha. ## O aviso precisa vir depois do fato Excluir uma conta envolve refeições, fotos, peso e água associados a ela. Se uma etapa necessária falha, o sistema não pode anunciar que terminou. Um dos testes adicionados ao Garfim simula justamente uma falha ao apagar as fotos. A confirmação final não é preparada nesse caso. Pedidos cancelados e exclusões que ainda não chegaram ao prazo também ficam fora do envio. É um princípio que aplico a outras mensagens do produto: “concluído” precisa corresponder ao resultado que a pessoa entende por essa palavra. O sistema ter recebido uma solicitação é uma informação diferente. ## E se a conta for apagada, mas o e-mail falhar? A exclusão e a entrega da mensagem dependem de operações distintas. Pode dar certo apagar a conta e dar errado contatar o serviço de e-mail logo depois. Para lidar com isso, o Garfim registra a confirmação pendente junto com a remoção. O envio acontece a partir desse registro. Se houver uma interrupção, a próxima tentativa sabe que ainda existe uma pessoa a avisar. Essa organização evita depender de duas operações terminarem no mesmo instante. Também permite repetir o envio com controle para reduzir o risco de duplicar a confirmação. É uma solução útil sempre que uma mudança importante precisa gerar uma comunicação: primeiro preservar a informação de que o aviso é necessário, depois acompanhar sua entrega. ## Até a fila de envio precisa ter um limite Surge então outra pergunta: por quanto tempo manter o endereço de alguém que acabou de excluir a conta? Na fila de confirmação do Garfim, defini um limite de 24 horas. O endereço sai dela depois do envio ou quando esse prazo termina. Se a entrega não acontece a tempo, a falha fica registrada para acompanhamento. Esse limite vale para essa fila específica. O ponto da decisão é evitar que uma tentativa de comunicação conserve indefinidamente o contato que usou. Os testes também verificam que repetir a tarefa de exclusão não cria outra confirmação para a mesma conta. Falhas e repetições fazem parte da operação de um sistema; é melhor projetar o comportamento esperado do que presumir que tudo ocorrerá uma única vez. ## Excluir a conta e cancelar a assinatura são ações distintas O novo e-mail orienta que a exclusão não cancela automaticamente assinaturas na App Store ou no Google Play. Se houver uma assinatura ativa, a pessoa precisa administrá-la na loja. Vale colocar essa informação onde ela faz diferença. Quem está encerrando a conta precisa entender se ainda existe algo a fazer para interromper a renovação. > Em 12 de outubro: a atualização estava no código e nos testes. A entrega da confirmação em produção ainda precisava ser acompanhada. Quem decide sair também merece saber em que ponto está e quando o pedido terminou. Uma confirmação útil precisa corresponder ao que o sistema de fato concluiu. Pensar nessa experiência me obriga a olhar o produto inteiro, inclusive o momento em que alguém deixa de usá-lo. --- ## O que a primeira negativa da App Store me fez explicar. URL: https://luisjunior.ai/blog/garfim-primeira-negativa-app-store Publicado em 8 de outubro de 2026 · Lançamento · Construindo o Garfim, parte 7 A Apple pediu uma demonstração do Garfim e mais informações. Preparar a resposta exige olhar o produto com os olhos de quem acaba de chegar. O Garfim foi enviado à App Store em 7 de outubro. No dia seguinte, veio a primeira negativa: a Apple pediu mais informações e uma demonstração do aplicativo funcionando em um iPhone. O parecer se enquadrava em “Information Needed”, dentro da diretriz 2.1. A conta tinha pouco histórico de revisão, e a equipe queria conhecer melhor o produto antes de continuar a avaliação. Ler esse retorno trouxe um trabalho diferente daquele de construir as telas: apresentar o funcionamento para alguém que não acompanhou nenhuma das decisões anteriores. ## O status sozinho explica pouco “Rejeitado” pode dar a impressão de um diagnóstico completo. O que orienta a próxima ação é o conteúdo do parecer. Neste caso, o pedido não apontava uma tela quebrada ou uma compra recusada. Solicitava informações e evidências. A análise continuava pendente, e minha resposta precisava atender aos pontos levantados. Essa leitura muda a preparação. Antes de mexer no produto, preciso entender o que a pessoa responsável pela revisão não conseguiu avaliar. Corrigir por suposição pode consumir tempo sem responder ao pedido. A [diretriz citada pela Apple](https://developer.apple.com/app-store/review/guidelines/#app-completeness) serviu de referência para organizar essa conferência. ## Um vídeo precisa mostrar as ligações entre as telas A Apple pediu uma gravação em aparelho físico, com o sistema atualizado. O roteiro deveria começar na abertura e mostrar uso típico, cadastro, login, exclusão da conta e acesso aos recursos pagos. Na assinatura, precisavam aparecer nome, duração, preço e links para termos e privacidade. Preparar isso exige percorrer o produto como uma sequência. Uma captura mostra o estado de uma tela. A gravação revela como alguém chega até ela, o que precisa decidir e se consegue seguir adiante. Para o Garfim, o percurso central é fotografar a refeição, conferir os alimentos e salvar. O revisor precisa encontrar esse caminho com as instruções entregues, sem depender de uma explicação minha ao lado. ## Quem constrói já sabe coisas que precisa explicar O pedido também incluía público, problema resolvido, serviços externos, diferenças entre regiões e o que pode ser comprado no aplicativo. Essas informações parecem familiares depois de semanas dentro do projeto. Para quem o recebe pela primeira vez, são peças necessárias para entender o conjunto. Ao organizar a resposta, preciso explicar a função de cada serviço e relacioná-la ao que acontece no app. Dizer que há IA, por exemplo, deixa em aberto onde ela entra, o que recebe e o que devolve à pessoa. A mesma dificuldade aparece ao apresentar software a um cliente ou a uma nova equipe. Conhecer o funcionamento por dentro pode fazer a gente pular justamente a explicação que falta para o outro. ## Preparar a resposta é revisar a apresentação do produto Organizei a preparação em torno de uma conta de teste e de um roteiro que incluía a exclusão dessa conta. A gravação precisava mostrar o percurso real no aparelho, com as informações necessárias para que o revisor conseguisse repeti-lo. Em 8 de outubro, essa resposta ainda estava em preparação. A primeira negativa acrescentou uma tarefa clara ao lançamento: tornar o funcionamento verificável por quem está chegando agora. O exercício tem valor além da revisão. Se preciso de muitas explicações para alguém completar uma tarefa, vale olhar também para as instruções e para a própria interface. A forma de demonstrar um produto ajuda a perceber onde ele ainda exige conhecimento demais de quem usa. --- ## O que quero aprender com o teste fechado do Garfim. URL: https://luisjunior.ai/blog/garfim-testadores-teste-fechado-google-play Publicado em 8 de outubro de 2026 · Produto · Construindo o Garfim, parte 8 Ter participantes inscritos ainda não mostra se o aplicativo cabe na rotina. Como observo dificuldades de uso no teste fechado do Garfim. Ter pessoas inscritas em um teste ainda não diz se elas conseguem usar o aplicativo. Para descobrir isso, preciso acompanhar o que acontece quando alguém tenta registrar uma refeição no meio da própria rotina. Na conferência de 7 de outubro, doze pessoas estavam inscritas continuamente no teste fechado do Garfim. Era o terceiro dos 14 dias exigidos para aquela etapa da conta no Google Play. A contagem marcava um avanço na distribuição; entender as dificuldades de uso exigia olhar além dela. Depois dos [testes internos no Android](/blog/garfim-testes-internos-android), o Garfim entrou no teste fechado. A versão chega a um grupo definido enquanto acompanho o funcionamento e preparo o lançamento público. ## Participar do teste e criar um hábito são coisas diferentes Uma inscrição confirma que alguém entrou no grupo. Para entender a experiência, preciso observar se a pessoa consegue registrar uma refeição, ajustar uma porção e voltar quando precisa. Um diário alimentar encontra fotos feitas com pressa, conexão instável e refeições repetidas. O mesmo caminho que parece simples numa demonstração pode ficar cansativo quando é usado todos os dias. Quero usar essa etapa para descobrir onde existe esforço desnecessário. O número de participantes ajuda a acompanhar a exigência da loja; os relatos e o uso ajudam a decidir o que melhorar. Na regra aplicável à conta, cumprir o período permite solicitar acesso à produção, que ainda passa por análise. O Google detalha esse processo na [documentação de testes](https://support.google.com/googleplay/android-developer/answer/14151465?hl=pt-BR). Por isso, a contagem não se transforma automaticamente numa data de lançamento. ## Um bom relato começa pela intenção “Não consegui registrar o almoço” é uma informação importante, mas pode descrever problemas diferentes. A câmera não abriu? A análise demorou? A porção estava errada? O botão de salvar não respondeu? Para investigar, procuro entender o que a pessoa queria fazer, os passos seguidos e o que apareceu na tela. Modelo do aparelho e versão instalada completam o contexto. Isso diminui a distância entre um relato e uma situação que consigo reproduzir. Muitas vezes, uma descrição do percurso permite investigar sem pedir fotos ou registros pessoais de alimentação. Quem conduz testes pode ajudar bastante fazendo perguntas específicas sobre a tarefa, em vez de se limitar a “o que achou do aplicativo?”. ## Desistir de uma compra é uma ação válida Entre os ajustes recentes está o tratamento do cancelamento de uma compra. A pessoa abre a oferta, decide não continuar e fecha a janela da loja. Essa escolha precisa ser reconhecida corretamente. Se o aplicativo reage com uma mensagem de falha inesperada, cria dúvida sobre algo que a própria pessoa acabou de decidir. O sistema deve distinguir desistência, espera e erro. Também houve trabalho em falhas temporárias de login e envio de uma atualização com ajustes de consentimento. Acompanhar a versão instalada pelos participantes ajuda a relacionar cada relato ao comportamento que estava disponível naquele momento. ## O lançamento está avançando por caminhos diferentes Em 8 de outubro, o Android seguia no teste fechado, enquanto o iPhone exigia preparar a resposta à [primeira solicitação de informações da Apple](/blog/garfim-primeira-negativa-app-store). O Garfim ainda estava em preparação para o público. Essa fase está aproximando o desenvolvimento das situações em que o aplicativo precisa ser útil. A pergunta que orienta meu acompanhamento é concreta: em qual ponto alguém deixa de conseguir fazer o que veio fazer, e o que precisa mudar para que possa continuar? --- ## O trabalho de uma assinatura continua depois da compra. URL: https://luisjunior.ai/blog/garfim-assinaturas-google-play Publicado em 3 de outubro de 2026 · Desenvolvimento · Construindo o Garfim, parte 5 Cancelamento, restauração e avisos atrasados: as decisões por trás da integração direta do Garfim com o Google Play. Tocar em “assinar” leva poucos segundos. O trabalho de manter esse acesso correto pode durar meses: a compra fica pendente, a renovação é cancelada, o celular muda, o aplicativo é reinstalado. Ao preparar o Garfim para o Android, decidi concentrar a cobrança na integração direta com o Google Play. Retirei o caminho anterior, que incluía Pix e RevenueCat, uma plataforma de gestão de assinaturas. A escolha reduziu a quantidade de serviços envolvidos e trouxe para o projeto a responsabilidade de acompanhar a assinatura diretamente com a loja. Vale explicar essa troca, porque ela vai muito além do botão de pagamento. ## Cancelar a renovação não encerra o período pago Pense em alguém que assina, usa por alguns dias e desliga a renovação automática. Essa pessoa ainda pode ter um período contratado pela frente. Se o aplicativo interpreta qualquer cancelamento como perda imediata de acesso, ele corta algo que deveria continuar disponível. Se ignora o vencimento, pode manter um acesso que já terminou. Por isso, o Garfim consulta a situação da assinatura para decidir sobre o Pro. Preciso distinguir o que foi comprado, até quando vale e se haverá renovação. São informações relacionadas, mas cada uma responde a uma pergunta diferente. ## As notícias da loja podem chegar fora de ordem O sistema recebe avisos sobre mudanças na assinatura. Uma mensagem pode chegar atrasada ou ser repetida. Tratar cada aviso como uma ordem isolada cria o risco de fazer a conta voltar a um estado antigo. No Garfim, esses eventos levam o servidor a conferir a situação da compra na loja. O acesso acompanha essa verificação. A mensagem de sucesso na tela do celular, sozinha, não autoriza liberar o Pro. Esse cuidado é útil em muitas integrações: quando um serviço avisa que algo mudou, vale entender se o aviso descreve o estado atual ou apenas um acontecimento anterior. ## Escolher menos serviços também exige assumir trabalho Uma plataforma intermediária pode reunir diferenças entre lojas e oferecer ferramentas prontas. A integração direta pede que eu cuide de verificação, restauração e mudanças de acesso. Para esta etapa do Garfim, concentrada no Android, escolhi trabalhar com um caminho de compra e conhecer suas responsabilidades. A implementação para iPhone ficou para outra etapa. É uma decisão de escopo. O que faz sentido aqui depende de quais plataformas estão sendo preparadas e do que consigo operar. Acrescentar outra forma de pagamento significa acrescentar também seus casos de falha e suporte. ## O teste precisa chegar até o celular > Em 3 de outubro: a integração do servidor estava publicada e a comunicação com as notificações da loja havia sido verificada. Compra, restauração e mudanças de acesso ainda precisavam ser percorridas no aplicativo instalado. Essa sequência evita confundir comunicação entre serviços com uma compra percorrida por uma pessoa. É no celular que aparecem a espera, a desistência e a dúvida sobre o que fazer depois. Uma assinatura continua mudando depois da compra. Projetar esse caminho exige acompanhar o acesso ao longo do tempo e conseguir explicar cada mudança a quem pagou. É isso que transforma a integração com a loja em uma experiência de assinatura que faz sentido para a pessoa. --- ## Por que o Garfim ganhou um plano gratuito. URL: https://luisjunior.ai/blog/garfim-plano-gratuito Publicado em 3 de outubro de 2026 · Produto · Construindo o Garfim, parte 4 Um diário alimentar precisa caber na rotina antes de pedir uma assinatura. Como essa escolha mudou a entrada, os limites e a continuidade do Garfim. Um aplicativo de registro alimentar precisa de mais de uma refeição para mostrar se cabe na vida de alguém. A pessoa pode gostar da primeira tentativa e descobrir, no dia seguinte, que o processo exige atenção demais. Foi pensando nesse tempo de descoberta que mudei a entrada do Garfim. A versão em preparação passou a ter um plano gratuito, sem prazo para acabar. Antes, continuar usando dependia de uma assinatura após o período de teste. A mudança permite experimentar o produto na própria rotina antes de decidir pagar. ## O diário precisa continuar útil O plano gratuito mantém o diário alimentar, a busca de alimentos, o código de barras, os favoritos e a repetição de refeições. Também inclui água, peso e histórico. Para o reconhecimento com IA, defini uma cota compartilhada: um registro por foto ou voz por dia. Depois de usá-la, a pessoa ainda pode preencher o diário pelos outros caminhos. Essa divisão preserva uma tarefa completa. Quem começou a registrar o dia consegue continuar, mesmo que já tenha usado a foto no almoço. Minha hipótese é que encontrar utilidade no diário dá à pessoa mais condições de avaliar o Pro, que amplia o uso da IA. Vou acompanhar essa escolha depois do lançamento para entender se ela ajuda as pessoas a conhecer e continuar usando o produto. ## “Uma vez por dia” exige algumas decisões Um limite assim parece simples até chegar ao código. Em qual fuso o dia começa? O que acontece se a pessoa tocar duas vezes? E se a análise falhar depois de começar? No Garfim, o dia acompanha o fuso da pessoa. Solicitações simultâneas precisam respeitar a mesma cota, e uma tentativa que falha ou não reconhece alimento deve permitir tentar novamente. É fácil imaginar a frustração do caso contrário: alguém fotografa o prato, recebe um erro e descobre que gastou sua única tentativa. O texto do plano só será justo se o comportamento do sistema acompanhar a promessa. Esse tipo de detalhe costuma ficar fora da comparação entre “grátis” e “pago”, mas influencia a confiança muito cedo. ## A mudança de plano não deve apagar a continuidade A opção de seguir grátis fica visível na entrada, e o aplicativo guarda essa escolha. Reapresentar a mesma barreira a cada acesso atrapalharia justamente o hábito que quero permitir. Se uma assinatura termina, a conta volta ao plano gratuito e os registros permanecem. Quem acompanhou suas refeições ao longo do tempo precisa continuar encontrando esse histórico. O Pro entra como uma ampliação de uso, com limites próprios do serviço. Para avaliar essa divisão, quero observar em que momento alguém sente necessidade de mais recursos e o que já consegue fazer sem eles. ## O que vou observar depois do lançamento O primeiro registro, o retorno em outros dias e os momentos em que a cota é atingida vão ajudar a revisar essa escolha. São sinais mais úteis do que olhar apenas quantas pessoas abriram a tela de assinatura. Em 3 de outubro, esse desenho estava implementado e a preparação para o lançamento se concentrava no Android. A observação da rotina do público ainda viria depois. Criar um plano gratuito me obrigou a definir qual experiência o Garfim deve entregar desde o começo. A resposta ficou mais concreta: permitir que alguém acompanhe sua alimentação e conheça o reconhecimento por foto sem ter que decidir sobre uma assinatura na porta de entrada. --- ## O login funcionou. Por que a tela do Garfim não saiu do lugar? URL: https://luisjunior.ai/blog/garfim-testes-internos-android Publicado em 3 de outubro de 2026 · Lançamento · Construindo o Garfim, parte 6 Um teste no Android mostrou a distância entre uma sessão criada e uma pessoa que consegue entrar. O que esse episódio mudou na forma de conferir o aplicativo. O login do Garfim funcionava no servidor, mas a pessoa continuava olhando para a tela de entrada. Foi o que aconteceu numa versão instalada em um Galaxy S23. A sessão era criada; ao fechar e abrir o aplicativo, a conta aparecia conectada. O caminho entre essas duas coisas estava incompleto. Esse episódio marcou a chegada do Garfim aos testes internos do Google Play. Depois de [abrir a lista de espera](/blog/garfim-preparando-o-lancamento), o projeto passou a ter uma versão distribuída a um grupo restrito no Android. Usar o aplicativo instalado começou a revelar problemas que uma resposta bem-sucedida do servidor não mostra. ## O resultado precisa chegar à tela Para quem toca em “entrar”, a expectativa é seguir para o aplicativo. A existência de uma sessão nos bastidores não ajuda se a tela continua pedindo login. A correção passou a atualizar a sessão após a autenticação e usar essa confirmação para sair da entrada. Uma nova versão foi enviada aos testes internos. O caso deixa um critério que procuro aplicar aos outros fluxos: uma ação termina quando a pessoa consegue perceber o resultado e continuar. Isso vale para salvar uma refeição, restaurar uma assinatura ou enviar um pedido de exclusão. ## Cada teste enxerga uma parte Gerar o aplicativo mostra que o projeto pode ser transformado em uma versão instalável. Um teste automatizado verifica os cenários que foram preparados. Usar no celular coloca interface, sistema, conexão e conta para trabalhar juntos. No caso do login, uma parte tinha cumprido sua função. Faltava a transição que tornaria esse sucesso visível. É por isso que gosto de percorrer tarefas completas. Em vez de encerrar a conferência na resposta de uma integração, acompanho o que aparece depois: a tela mudou? A informação está atualizada? A próxima ação está disponível? Essa forma de testar aproxima o critério técnico da experiência de quem vai usar. ## A distribuição também acontece em etapas A faixa interna do Google Play permite instalar o aplicativo em um grupo restrito. Naquele momento, a conta do Garfim ainda precisava passar pelo teste fechado e obter acesso à distribuição pública. Também havia trabalho na ficha da loja, nas declarações de dados e nas capturas de tela. A versão pública estava preparada como rascunho, enquanto as verificações continuavam. Assim, os testes internos já permitiam aprender com o app instalado sem anunciar uma data de lançamento antes de completar o caminho necessário. > Em 3 de outubro: o foco dos testes era o Android, a correção do login ainda precisava ser confirmada no aparelho e não havia download público. A página recebia interessados em iPhone e Android. ## Voltar no dia seguinte faz parte do roteiro O teste de um diário alimentar precisa acompanhar mais do que uma primeira abertura. Quero conferir o registro da refeição, os limites de uso, a assinatura e o retorno à conta depois de uma interrupção. Uma pessoa pode alternar de aplicativo, perder a conexão ou voltar horas depois. O Garfim precisa conservar o sentido do que ela estava fazendo. O avanço mais útil dessa fase foi colocar as tarefas completas no centro da revisão: instalar, entrar, registrar e conseguir continuar. É esse percurso que mostra se o resultado técnico chegou a quem precisava dele. --- ## Pagenello: um site começa pelo que o visitante veio fazer. URL: https://luisjunior.ai/blog/pagenello-sites-para-pequenos-negocios Publicado em 3 de outubro de 2026 · Lançamento Cardápio, endereço, trabalhos ou orçamento: como a intenção de quem visita orienta os sites que estou construindo para pequenos negócios. Quem abre o site de um café pode estar procurando o cardápio ou tentando descobrir se ainda dá tempo de chegar. Quem visita a página de um estúdio talvez queira ver trabalhos e entender como pedir um orçamento. Essa intenção deveria orientar a organização do site. Uma página bonita pode exigir esforço demais se esconder justamente a informação que trouxe a pessoa até ali. Foi com esse olhar que criei o [Pagenello](https://pagenello.com/), meu estúdio de sites para pequenos negócios. Cuido do design e do desenvolvimento, começando pela história do negócio e pelo que seu visitante precisa encontrar. ## Uma página também precisa de uma ordem A oferta inicial reúne um site de uma página, com conteúdo em inglês e adaptação para computador e celular. Concentrar a apresentação nesse formato exige escolher a sequência das informações. Primeiro, o visitante precisa entender onde chegou e o que o negócio oferece. Depois, encontrar detalhes que ajudem a avaliar a proposta e um caminho para entrar em contato ou seguir adiante. Essa ordem muda conforme a atividade. Imagens do ambiente podem ajudar a escolher um café. Exemplos de trabalhos podem ser mais importantes para contratar um estúdio. Repetir a mesma estrutura sem olhar para essas diferenças deixa de aproveitar o que o negócio tem para mostrar. ## O celular revela as prioridades Numa tela pequena, cada bloco empurra o seguinte para baixo. Um parágrafo longo antes do endereço pode atrapalhar quem só precisa chegar ao local. Muitas chamadas com o mesmo destaque tornam a escolha mais difícil. Ao desenhar a página, observo o caminho até a informação: quanto é preciso ler, onde estão os botões e o que continua compreensível quando as imagens mudam de tamanho. Essas decisões ajudam a dar função ao design. Tipografia, espaço e contraste orientam a leitura e mostram o que merece atenção primeiro. ## A identidade aparece nos detalhes que pertencem ao negócio O Pagenello se apresenta como um pequeno bairro ilustrado, com café, floricultura e estúdio criativo. São conceitos fictícios, identificados como exemplos visuais, que exploram maneiras diferentes de contar uma história numa página. Um negócio pode se tornar reconhecível pelo ambiente, pelo tipo de trabalho, pelas imagens e pelo jeito de falar. Procuro trazer esses elementos para o projeto, em vez de preencher seções apenas porque o modelo de site reservou espaço para elas. O visitante precisa perceber quem está por trás da oferta e encontrar o que veio procurar. Personalidade e clareza participam da mesma experiência. ## Definir o escopo ajuda a fazer escolhas melhores O pacote inicial inclui uma página personalizada, texto em inglês, adaptação para celular e uma rodada de revisão. Domínio e hospedagem são tratados separadamente. Esse recorte também indica quando a conversa precisa mudar. Um negócio que exige muitas páginas, área restrita ou uma operação mais complexa pede outro escopo. Eu cuido do design e da construção. Quem me apresenta o negócio conversa com a mesma pessoa que organiza o conteúdo e monta a página. Isso ajuda a manter a intenção do projeto presente nas escolhas de texto, imagem e navegação. O [Pagenello está no ar](https://pagenello.com/) com essa proposta. É uma forma de aplicar uma preocupação que atravessa meus projetos: entender a tarefa de quem chega e organizar a tecnologia para que essa pessoa consiga realizá-la. --- ## Como uma foto do almoço vira um produto. URL: https://luisjunior.ai/blog/da-ideia-ao-produto-na-era-da-ia Publicado em 27 de setembro de 2026 · Concepção · Construindo o Garfim, parte 1 Porções, comida brasileira e espaço para corrigir a IA: as decisões que dão forma ao Garfim antes de escrever a primeira tela. Uma foto do almoço parece um bom começo para um aplicativo. A IA reconhece os alimentos, estima as porções e ajuda a registrar a refeição. Foi dessa possibilidade que nasceu o Garfim. Mas imagine fazer isso no intervalo do trabalho. O prato tem arroz, feijão, carne e uma salada parcialmente escondida. Você está com pressa. Se o aplicativo exigir que você organize todos esses detalhes antes de salvar, a tecnologia acrescentou trabalho ao almoço. É aí que começa a parte da construção que mais me interessa: transformar uma capacidade técnica em algo que faça sentido na rotina. ## O prato brasileiro muda o projeto Uma concha de feijão e uma porção de feijão em gramas descrevem a mesma comida de maneiras diferentes. Para quem está servindo o almoço, uma delas pode ser muito mais fácil de responder. No Garfim, alimentos brasileiros e medidas caseiras entram na base de dados e na apresentação do resultado. Essa escolha atravessa o produto inteiro. Influencia o que a pessoa procura, como reconhece uma porção e quanto precisa corrigir antes de registrar. Gosto de olhar para esse esforço como parte do custo de usar um aplicativo. Cada campo exige atenção. Se peço uma informação que a pessoa não tem à mão, preciso oferecer um caminho razoável para continuar. ## Uma foto também deixa informações de fora A imagem pode mostrar arroz. Dificilmente mostra quanto óleo foi usado no preparo ou o peso exato daquela porção. Um alimento pode estar coberto por outro. Por isso, o reconhecimento no Garfim chega a uma tela de revisão. A pessoa confere os alimentos, ajusta as porções e salva. Corrigir faz parte do caminho previsto desde a concepção. Essa decisão muda a interface: o resultado precisa ser fácil de editar. Se uma estimativa parece exata demais e a correção fica escondida, o aplicativo incentiva a confiança no número errado. **A forma de apresentar uma resposta da IA influencia o quanto alguém vai confiar nela.** Para quem constrói produtos com essa tecnologia, o desenho da revisão merece tanta atenção quanto o reconhecimento. ## Cada recurso acrescenta uma responsabilidade Foto, voz, água, histórico, lembretes. É fácil enxergar valor em cada possibilidade separadamente. Reunir tudo exige decidir o que deve aparecer primeiro e o que pode esperar. Escolhi organizar a experiência principal ao redor da refeição: fotografar, conferir, ajustar e registrar. Os outros recursos precisam encontrar seu lugar sem interromper esse percurso. A IA permite experimentar uma tela rapidamente. Depois vêm as perguntas menos visíveis: o que acontece sem conexão? Como a pessoa corrige um erro? O que precisa ser mantido quando ela volta amanhã? Antes de acrescentar algo, procuro entender esse compromisso. Uma função pequena na tela pode exigir bastante trabalho para continuar útil fora de uma demonstração. O Garfim está ganhando forma nessas escolhas. A ideia cabe em uma frase; o produto precisa caber no horário de almoço de alguém. --- ## As decisões que continuo tomando ao desenvolver com IA. URL: https://luisjunior.ai/blog/desenvolver-com-ia-alem-do-codigo Publicado em 27 de setembro de 2026 · Desenvolvimento · Construindo o Garfim, parte 2 De onde vêm os números, quanto custa cada uso e como lidar com falhas: o que preciso resolver para transformar código em um aplicativo útil. Uma IA pode escrever rapidamente a integração que eu pedir. Se eu escolher mal o que integrar, ela também acelera a construção do problema. No desenvolvimento do Garfim, uso essas ferramentas para implementar, comparar caminhos e revisar código. O tempo economizado abre espaço para perguntas que um aplicativo precisa responder: de onde vêm os números, quanto custa cada uso e o que acontece quando um serviço falha? São decisões que chegam até quem usa, mesmo quando ficam escondidas atrás de uma tela simples. ## Reconhecer arroz é uma etapa. Calcular a porção é outra Quando a IA identifica um alimento na foto, ainda falta associá-lo a uma quantidade e a uma referência nutricional. Essas etapas podem errar de maneiras diferentes. O Garfim usa dados da TACO, uma tabela brasileira de composição de alimentos, e referências de medidas caseiras do IBGE. Quando há uma correspondência na base, o cálculo usa aqueles dados. Quando falta uma referência, o resultado precisa deixar claro que é uma estimativa. Isso exige cuidado com nomes, unidades e preparo. A palavra reconhecida pode parecer correta, enquanto a associação usada no cálculo está errada. Por isso, avalio a ligação entre reconhecimento e base de dados, além da resposta isolada do modelo. Para quem trabalha com IA, esse é um ponto que merece atenção: uma resposta plausível pode atravessar várias etapas antes de virar um número na tela. É preciso saber de onde ele veio. ## O modelo precisa funcionar dentro de uma rotina Comida brasileira, tempo de resposta, custo e consistência do formato são critérios da escolha. Uma demonstração bem-sucedida responde pouco sobre o comportamento ao longo de muitas refeições. Se a resposta demora, a pessoa fica esperando com o prato à frente. Se chega em um formato inesperado, o aplicativo precisa lidar com isso. Se cada análise custa mais do que o produto consegue sustentar, o problema aparece na operação. Organizei a integração do Garfim para permitir comparar e trocar modelos sem reconstruir todo o aplicativo. Assim, a escolha pode acompanhar o que os testes e o uso mostrarem. ## O preço também aparece no código Definir um plano gratuito obriga a decidir como contar o uso. Cobrar uma assinatura exige saber quando liberar acesso, quando restaurá-lo e o que fazer depois de um vencimento. Até uma tentativa repetida merece atenção. Se a conexão cai e a pessoa toca novamente, o sistema precisa entender se está recebendo uma nova ação ou a repetição da anterior. Caso contrário, uma interface simples pode esconder registros ou cobranças indevidas. Procuro trazer essas perguntas para o desenvolvimento cedo. Deixá-las para o fim costuma obrigar a rever um caminho que já parecia pronto. ## A revisão acompanha a velocidade O celular reúne a câmera e o registro das refeições; outros serviços cuidam da conta, dos dados e do reconhecimento. Essa divisão permite ajustar uma parte, mas exige conferir o percurso inteiro: uma análise concluída no servidor ainda precisa chegar à tela para ser útil. Meu trabalho inclui entender como essas partes se comportam juntas. Peço ajuda à IA para explorar soluções e construir testes, mas preciso avaliar se o resultado atende à intenção e aos casos de erro. A velocidade é valiosa quando encurta o caminho até uma versão que posso examinar. É nesse exame — da origem dos dados ao que a pessoa vê quando algo falha — que boa parte das decisões de produto acontece. --- ## Apresentar o Garfim ao público também é um teste do produto. URL: https://luisjunior.ai/blog/garfim-preparando-o-lancamento Publicado em 27 de setembro de 2026 · Lançamento · Construindo o Garfim, parte 3 A página de lançamento coloca uma pergunta à prova: alguém que nunca viu o aplicativo consegue entender o que ele faz e o que esperar dele? Explicar um aplicativo para quem nunca ouviu falar dele é um bom teste para quem o construiu. Tudo o que parecia óbvio durante o desenvolvimento precisa caber em uma apresentação curta. O Garfim chegou a essa etapa. A [página do produto](https://garfim.com.br/) está no ar e recebe interessados no lançamento para iPhone e Android. Em 27 de setembro, a chegada às lojas ainda está em preparação. Publicar a página me colocou diante de uma pergunta prática: o que alguém precisa entender antes de decidir se quer experimentar? ## A primeira explicação já cria uma expectativa A proposta do Garfim é ajudar a acompanhar calorias e macronutrientes a partir da refeição. A pessoa fotografa, confere a estimativa, ajusta alimentos e porções e registra. Fiz questão de incluir a revisão nessa explicação. A foto deixa informações de fora, e o aplicativo foi pensado para permitir correções. Se a apresentação omite esse passo, o primeiro uso pode parecer mais trabalhoso do que o prometido. Essa coerência começa nas palavras da página e continua nos botões e nas telas. Quem chega precisa reconhecer a experiência que foi apresentada. ## Interesse, instalação e hábito são sinais diferentes A lista de espera recebe o e-mail de quem quer ser avisado sobre o lançamento. Esse cadastro mostra interesse na proposta. Depois, será preciso descobrir quem instala, faz o primeiro registro e volta em outro dia. Olhar essas etapas separadamente ajuda a entender onde agir. Uma página pouco clara pede um tipo de ajuste. Uma pessoa que instala e não consegue registrar a refeição pede outro. No Garfim, quero acompanhar essa passagem. O produto precisa encontrar espaço no almoço apressado e na rotina repetida, além de despertar curiosidade numa primeira visita. O cadastro tem uma finalidade definida: receber o aviso de lançamento. Manter essa promessa é parte do cuidado com quem deixou o contato. ## O trabalho continua depois da instalação Na preparação descrita aqui, em 27 de setembro, a apresentação nas lojas e as integrações ainda estavam em trabalho. Essa etapa também me levou a olhar para os primeiros minutos de uso. Como alguém começa? Onde encontra ajuda? Como consigo investigar uma falha que aconteceu em outro celular? Essas perguntas influenciam o que deve estar pronto para receber as primeiras pessoas. Um problema relatado sem contexto pode ser difícil de reproduzir; uma mensagem clara e um caminho de suporte ajudam a entender o que houve. Por isso, estou tratando o lançamento como uma passagem para o uso acompanhado. A página abre essa conversa enquanto o aplicativo percorre as etapas de publicação. Nos [primeiros textos da série](/blog/da-ideia-ao-produto-na-era-da-ia), contei como a ideia ganhou forma. Agora, a questão é observar como essa forma será entendida por quem não participou da construção. A lista de espera está disponível no site para quem quiser receber o aviso quando chegar a hora de usar.