<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Engineering on jpcercal.com</title><link>https://jpcercal.com/categories/engineering/</link><description>Recent content in Engineering on jpcercal.com</description><generator>Hugo</generator><language>pt</language><lastBuildDate>Thu, 22 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jpcercal.com/categories/engineering/index.xml" rel="self" type="application/rss+xml"/><item><title>Um WAF Não É um Patch</title><link>https://jpcercal.com/um-waf-nao-e-um-patch/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://jpcercal.com/um-waf-nao-e-um-patch/</guid><description>&lt;p&gt;Uma CVE crítica é divulgada. Alguém pergunta no chat da equipe se estamos expostos, e a primeira resposta é &amp;ldquo;temos um WAF, estamos cobertos&amp;rdquo;.&lt;/p&gt;&#10;&lt;p&gt;Entendo o reflexo. O WAF é uma das formas mais rápidas de reagir, e eu não gostaria de operar uma aplicação pública sem um. Mas a frase mistura duas coisas diferentes. Um WAF muda a chance de um atacante alcançar um bug. Um patch remove o bug. Quando o primeiro é tratado como o segundo, uma ponte temporária vira, sem alarde, infraestrutura permanente.&lt;/p&gt;</description></item><item><title>PHP2Shell: Duas Vulnerabilidades Críticas no PHP e o Que Fazer Agora</title><link>https://jpcercal.com/php2shell-duas-vulnerabilidades-criticas-no-php/</link><pubDate>Wed, 21 Oct 2026 00:00:00 +0000</pubDate><guid>https://jpcercal.com/php2shell-duas-vulnerabilidades-criticas-no-php/</guid><description>&lt;p&gt;Duas falhas críticas no runtime do PHP foram divulgadas em 21 de outubro de 2026: CVE-2026-109618 e CVE-2026-109619, apelidadas de “PHP2Shell”. Ambas têm CVSS 9.2 (v4.0) e permitem execução remota de código sem autenticação. A divulgação foi antecipada em um dia após o vazamento dos IDs (&lt;a href="https://thephp.foundation/blog/2026/10/21/todays-php-security-release-and-how-were-strengthening-php-security/"&gt;PHP Foundation&lt;/a&gt;). O bug está no núcleo do PHP: o framework não importa.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;A versão curta:&lt;/strong&gt; atualize o PHP para 8.5.12, 8.4.27, 8.3.36 ou 8.2.35, reinicie todos os workers e confira a versão em execução. Um WAF ganha tempo; não é uma correção.&lt;/p&gt;</description></item><item><title>Mudar o modelo de decisão muda a política</title><link>https://jpcercal.com/mudar-o-modelo-de-decisao-muda-a-politica/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://jpcercal.com/mudar-o-modelo-de-decisao-muda-a-politica/</guid><description>&lt;p&gt;Tenho lido a comparação da Vercel entre Jev, Laya e Liquid d1, e a parte útil para mim não é qual modelo vence.&lt;/p&gt;&#10;&lt;p&gt;O artigo não estabelece um vencedor.&lt;/p&gt;&#10;&lt;p&gt;Ele mostra que os três podem responder às mesmas perguntas tipadas por meio do AI Gateway. Isso facilita a comparação. Não nos diz se a aplicação deve agir sobre as respostas deles da mesma forma.&lt;/p&gt;&#10;&lt;p&gt;É essa distinção que eu manteria em mente antes de mudar um modelo em um sistema existente.&lt;/p&gt;</description></item><item><title>GPT-6 Astra É um Operador, Não um Chatbot</title><link>https://jpcercal.com/gpt-6-astra-e-um-operador-nao-um-chatbot/</link><pubDate>Thu, 24 Sep 2026 00:00:00 +0000</pubDate><guid>https://jpcercal.com/gpt-6-astra-e-um-operador-nao-um-chatbot/</guid><description>&lt;p&gt;Tenho pensado no GPT-6 Astra menos como um novo chatbot e mais como uma oferta permanente para operar o computador.&lt;/p&gt;&#10;&lt;p&gt;A OpenAI o chama de &amp;ldquo;o modelo mais inteligente e alinhado do mundo&amp;rdquo;. Talvez. A afirmação que posso verificar é mais restrita. Na &lt;a href="https://openai.com/index/gpt-6-astra/"&gt;nota de lançamento&lt;/a&gt; e na &lt;a href="https://openai.com/index/gpt-6-astra-next-generation-work/"&gt;nota posterior sobre trabalho&lt;/a&gt;, o Astra é descrito como algo que usa os aplicativos que as pessoas já têm abertos, inclusive aplicativos sem API.&lt;/p&gt;</description></item><item><title>O Custo do Ciclo Importa Mais do que a Pontuação</title><link>https://jpcercal.com/o-custo-do-ciclo-importa-mais-do-que-a-pontuacao/</link><pubDate>Wed, 23 Sep 2026 18:00:00 +0000</pubDate><guid>https://jpcercal.com/o-custo-do-ciclo-importa-mais-do-que-a-pontuacao/</guid><description>&lt;p&gt;Tenho lido as notas da Anthropic sobre o Claude Opus 5.5, e a parte à qual sempre volto não é o ranking.&lt;/p&gt;&#10;&lt;p&gt;Eles dizem que ele tem desempenho no nível do Claude Fable 5.1 na maior parte do trabalho e que, no uso que fazem dele, a diferença é menor do que as pontuações dos benchmarks sugerem. Também dizem que, nesse nível de capacidade, as margens nos benchmarks se tornaram um guia menos confiável para as diferenças no mundo real.&lt;/p&gt;</description></item><item><title>Quando Decisões de IA se Tornam Entradas de Software</title><link>https://jpcercal.com/quando-decisoes-de-ia-se-tornam-entradas-de-software/</link><pubDate>Wed, 23 Sep 2026 00:00:00 +0000</pubDate><guid>https://jpcercal.com/quando-decisoes-de-ia-se-tornam-entradas-de-software/</guid><description>&lt;p&gt;Tenho pensado no que o software realmente precisa quando pergunta a um sistema de IA para onde enviar uma solicitação.&lt;/p&gt;&#10;&lt;p&gt;Geralmente não é mais um parágrafo. É uma resposta que ele possa inspecionar: uma categoria conhecida, uma indicação de incerteza e uma regra para o que acontece em seguida.&lt;/p&gt;&#10;&lt;p&gt;Considere uma mensagem de suporte: “Fui cobrado duas vezes, e a página do recibo não carrega.” Uma explicação em formato livre pode ajudar uma pessoa, mas a aplicação ainda precisa decidir qual fila recebe a mensagem. Extrair da prosa o nome de uma fila acrescenta mais um ponto em que o fluxo de trabalho pode falhar.&lt;/p&gt;</description></item><item><title>O que uma Sessão com IA Pode Ensinar à Próxima</title><link>https://jpcercal.com/o-que-uma-sessao-com-ia-pode-ensinar-a-proxima/</link><pubDate>Mon, 14 Sep 2026 00:00:00 +0000</pubDate><guid>https://jpcercal.com/o-que-uma-sessao-com-ia-pode-ensinar-a-proxima/</guid><description>&lt;p&gt;Um assistente de IA pode ajudar a escrever código, explicar um sistema desconhecido, investigar uma falha ou redigir documentação. Um agente de IA pode ir um passo além e realizar várias ações em nosso nome.&lt;/p&gt;&#10;&lt;p&gt;Nos dois casos, é fácil se concentrar apenas no resultado imediato. O código compilou? O documento pareceu razoável? A tarefa avançou?&lt;/p&gt;&#10;&lt;p&gt;Há outro resultado que é fácil perder: o que a sessão nos ensinou sobre a maneira como nossa equipe trabalha.&lt;/p&gt;</description></item><item><title>Trabalhando com Agentes de IA: Supervisione o Ciclo</title><link>https://jpcercal.com/trabalhando-com-agentes-de-ia-supervisione-o-ciclo/</link><pubDate>Sun, 13 Sep 2026 00:00:00 +0000</pubDate><guid>https://jpcercal.com/trabalhando-com-agentes-de-ia-supervisione-o-ciclo/</guid><description>&lt;p&gt;Tenho pensado recentemente em como nosso papel como engenheiros de software muda quando agentes de IA passam a fazer parte do processo de desenvolvimento.&lt;/p&gt;&#10;&lt;p&gt;Parece haver uma escolha tentadora entre dois extremos.&lt;/p&gt;&#10;&lt;p&gt;Ou deixamos o agente cuidar de tudo e confiamos no resultado, ou continuamos envolvidos em cada etapa, revisando cada trecho de código que ele produz.&lt;/p&gt;&#10;&lt;p&gt;Não acho que qualquer uma dessas abordagens escale particularmente bem.&lt;/p&gt;&#10;&lt;h2 id="o-que-é-produzido-não-é-o-processo-inteiro"&gt;O que é produzido não é o processo inteiro&lt;/h2&gt;&#10;&lt;p&gt;Ao construir software, muitas vezes nos concentramos bastante nos artefatos que produzimos: código, testes, projetos técnicos, configuração e documentação.&lt;/p&gt;</description></item><item><title>Entenda o Sistema Antes de Mudá-lo</title><link>https://jpcercal.com/entenda-o-sistema-antes-de-muda-lo/</link><pubDate>Thu, 10 Sep 2026 00:00:00 +0000</pubDate><guid>https://jpcercal.com/entenda-o-sistema-antes-de-muda-lo/</guid><description>&lt;p&gt;Uma coisa que aprendi ao longo dos anos é que uma boa arquitetura muitas vezes começa por entender o sistema que você já tem.&lt;/p&gt;&#10;&lt;p&gt;Antes de mudar alguma coisa, geralmente dedico um tempo a observar como as requisições realmente fluem, onde estão as dependências, quais podem ser os pontos de falha e, talvez o mais importante&amp;hellip; por que as coisas chegaram a esse ponto.&lt;/p&gt;&#10;&lt;p&gt;Às vezes existe um motivo muito bom. Às vezes o motivo é simplesmente que o sistema evoluiu com o tempo. De qualquer forma, entender o contexto geralmente leva a decisões melhores do que partir direto para uma solução.&lt;/p&gt;</description></item><item><title>Como Criar um Sincronizador de Arquivos Bidirecional com Unison</title><link>https://jpcercal.com/como-criar-um-sincronizador-de-arquivos-bidirecional-com-unison/</link><pubDate>Mon, 13 Jul 2020 06:35:28 +0000</pubDate><guid>https://jpcercal.com/como-criar-um-sincronizador-de-arquivos-bidirecional-com-unison/</guid><description>&lt;p&gt;Então, se você chegou aqui, considero que já tem um problema à resolver e que você conhece a ferramenta `unison&amp;rsquo;. Se esse for o caso, pule a introdução, por favor.&lt;/p&gt;&#10;&lt;p&gt;Caso contrário, continue lendo, pois isso pode esclarecer algumas coisas antes de começarmos a usar o &lt;code&gt;unison&lt;/code&gt; para criar uma sincronização bidirecional (two-way) de dois diretórios.&lt;/p&gt;&#10;&lt;h1 id="introdução"&gt;Introdução&lt;/h1&gt;&#10;&lt;p&gt;Para simplificar o entendimento, vamos imaginar que você tem duas pastas e deseja que ambas sejam sincronizadas quando um evento acontecer, como quando um novo arquivo é criado, um arquivo tenha sido alterado ou até mesmo um arquivo que tenha sido excluído. Você deseja que ambas as pastas reflitam exatamente o mesmo estado, como uma réplica.&lt;/p&gt;</description></item><item><title>Composer clear cache</title><link>https://jpcercal.com/composer-clear-cache/</link><pubDate>Sun, 31 Mar 2019 20:53:12 +0000</pubDate><guid>https://jpcercal.com/composer-clear-cache/</guid><description>&lt;p&gt;Bem, hoje eu estava enfrentando o seguinte problema:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;End-of-central-directory signature not found. Either this file is not&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; a zipfile, or it constitutes one disk of a multi-part archive. In the&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; latter &lt;span class="k"&gt;case&lt;/span&gt; the central directory and zipfile comment will be found on&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; the last disk&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt; of this archive.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unzip: cannot find zipfile directory in one of /var/www/apps/api/vendor/symfony/symfony/d9b1f549001f508e27a7334590534b83 or&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; /var/www/apps/api/vendor/symfony/symfony/d9b1f549001f508e27a7334590534b83.zip, and cannot find /var/www/apps/api/vendor/symfony/symfony/d9b1f549001f508e27a7334590534b83.ZIP, period.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; The archive may contain identical file names with different capitalization &lt;span class="o"&gt;(&lt;/span&gt;which fails on &lt;span class="k"&gt;case&lt;/span&gt; insensitive filesystems&lt;span class="o"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Unzip with unzip &lt;span class="nb"&gt;command&lt;/span&gt; failed, falling back to ZipArchive class&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Invalid zip file, retrying...&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;blockquote&gt;&#10;&lt;p&gt;Essa era a saída parcial do comando &lt;code&gt;composer install&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Revisitando o layout e o projeto do Blog</title><link>https://jpcercal.com/revisitando-o-layout-e-o-projeto-do-blog/</link><pubDate>Tue, 12 Mar 2019 21:33:54 +0000</pubDate><guid>https://jpcercal.com/revisitando-o-layout-e-o-projeto-do-blog/</guid><description>&lt;p&gt;Olá caros leitores, tinha vontade de revisitar o layout do &lt;em&gt;blog&lt;/em&gt; há muito tempo, no entanto, dar atenção para a família e escrever não são coisas que podem ser feitas ao mesmo tempo, pois, ambas requerem atenção.&lt;/p&gt;&#10;&lt;p&gt;Pois bem, tecnicamente falando eu gostaria de ter o blog com o código fonte aberto no GitHub para servir de inspiração para outros nerds tomarem meu projeto como base.&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;Ficou curioso e quer dar uma olhadinha no código fonte? Então aqui está o &lt;a href="https://github.com/jpcercal/jpcercal.com"&gt;link do repositório&lt;/a&gt;, mate sua vontade e deixe um &lt;em&gt;star&lt;/em&gt; pra mim por lá. Além disto, por que não fazer um &lt;em&gt;fork&lt;/em&gt; do projeto também? Encontrou algum bug? Abra uma issue ou melhor ainda manda um PR. ❤️&lt;/p&gt;</description></item><item><title>Como remover todas as branches locais do Git</title><link>https://jpcercal.com/how-to-delete-all-your-git-local-branches/</link><pubDate>Tue, 12 Mar 2019 11:31:29 +0000</pubDate><guid>https://jpcercal.com/how-to-delete-all-your-git-local-branches/</guid><description>&lt;p&gt;Bem, de tempos em tempos eu percebo que preciso limpar minhas branches locais, isto é parte do meu workflow e se você precisa ou quer fazer o mesmo, então poderia se beneficiar desse snippet abaixo:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ git branch --list &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;egrep --invert-match &lt;span class="s2"&gt;&amp;#34;(master|gh-pages|\*)&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xargs git branch -D&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;Acredito que, o comando listado acima não precisaria de explicações, mas se você não entendeu o que está sendo feito, aqui está a explicação para cada um dos comandos executados:&lt;/p&gt;</description></item><item><title>iTerm2 + Zplug = Produtividade</title><link>https://jpcercal.com/iterm2-mais-zplug-igual-produtividade/</link><pubDate>Mon, 26 Feb 2018 10:15:56 +0000</pubDate><guid>https://jpcercal.com/iterm2-mais-zplug-igual-produtividade/</guid><description>&lt;p&gt;Depois de passar muito tempo da minha vida usando o terminal normal, conheci uma nova ferramenta chamada iTerm2 por causa de um amigo há alguns anos. E, nesta semana, descobri o poder do zplug. Então, aqui está um breve tutorial de como conseguir algo parecido com isto:&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="terminal.png" alt="iTerm2 &amp;#43; zplug" loading="lazy" decoding="async"&gt;&#10;&lt;/p&gt;&#10;&lt;h2 id="iterm2"&gt;iTerm2&lt;/h2&gt;&#10;&lt;p&gt;Esta é uma ferramenta como o aplicativo nativo de terminal fornecido pela Apple, com muitos recursos que você pode simplesmente &lt;a href="https://www.iterm2.com/"&gt;conferir aqui&lt;/a&gt;. Ela permite personalizar tudo, do preenchimento automático ao destaque de sintaxe.&lt;/p&gt;</description></item><item><title>Acessando Instâncias Amazon RDS em seu Desktop</title><link>https://jpcercal.com/acessando-instancias-amazon-rds-em-seu-desktop/</link><pubDate>Fri, 15 Aug 2014 10:48:28 +0000</pubDate><guid>https://jpcercal.com/acessando-instancias-amazon-rds-em-seu-desktop/</guid><description>&lt;p&gt;Depois de alguns minutos de pesquisa, encontrei uma solução interessante para conectar no RDS da Amazon através de um cliente Desktop, pois bem, a fórmula mágica se dá através de uma conexão SSH que reencaminha os pacotes para a máquina local, permitindo desta forma, uma conexão remota.&lt;/p&gt;&#10;&lt;p&gt;Primeiramente você precisa adicionar a sua chave de conexão do serviço EC2 da Amazon. Faça isso executando o seguinte comando:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ ssh-add &amp;lt;your-key-filename&amp;gt;.pem&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;E para reencaminhar os pacotes execute o seguinte comando:&lt;/p&gt;</description></item></channel></rss>