<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>Imperfect Systems - Diário de bordo</title><description>Notas sobre o software, os jogos e a música que saem da Imperfect Systems.</description><link>https://imperfectsystems.com/</link><item><title>A playlist que já tinha o nome certo</title><link>https://imperfectsystems.com/pt/blog/playlist-already-had-right-name/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/playlist-already-had-right-name/</guid><description>Um artefato de renomeação, uma API sem campo de autor pra atualizar, e um teste em dispositivo real provando que o bug já tinha se corrigido sozinho, fechado como aceitar como está.</description><pubDate>Fri, 28 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>musickit</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>A pasta que ficou parada</title><link>https://imperfectsystems.com/pt/blog/folder-that-stayed-put/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/folder-that-stayed-put/</guid><description>Uma revisão de código encontrou um invariante que a feature de adotar/importar do Greenhouse quebrava silenciosamente, e a correção que tornou tudo chato de novo.</description><pubDate>Thu, 27 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>rust</category><category>tauri</category><category>testing</category><category>dev-log</category><category>greenhouse</category></item><item><title>Álbuns em destaque, dados reais do MusicKit, e um teste que mentiu sobre estar passando</title><link>https://imperfectsystems.com/pt/blog/featured-albums-test-that-lied/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/featured-albums-test-that-lied/</guid><description>Não existe uma flag isEssential - o Essentials que você vê é uma playlist de músicas. featuredAlbums é o sinal real, e uma mudança de fixture expôs um teste que ninguém tinha rodado de novo.</description><pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>musickit</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Um toggle por blog, e quando não &quot;corrigir&quot; um bug</title><link>https://imperfectsystems.com/pt/blog/per-blog-toggle-when-not-to-fix/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/per-blog-toggle-when-not-to-fix/</guid><description>Um booleano atravessando quatro camadas, e três passadas de revisão independentes concordando com um achado que eu deliberadamente não corrigi - porque o cache é o mecanismo de dedup.</description><pubDate>Tue, 25 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>syndication</category><category>dev-log</category><category>blog-manager</category></item><item><title>O blog que não conseguia publicar num cronograma</title><link>https://imperfectsystems.com/pt/blog/blog-couldnt-publish-on-schedule/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/blog-couldnt-publish-on-schedule/</guid><description>Um design de pipeline em lote que começou com uma checagem de cinco minutos na base do sistema: posts com data futura não ficavam escondidos, viravam 404, e nada nunca reconstruía o site.</description><pubDate>Mon, 24 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>astro</category><category>automation</category><category>publishing</category><category>dev-log</category><category>blog-manager</category></item><item><title>O scan que se ofereceu para importar a si mesmo</title><link>https://imperfectsystems.com/pt/blog/scan-that-offered-to-import-itself/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/scan-that-offered-to-import-itself/</guid><description>Um scanner de importação que encontrou a própria estrutura interna do app, e depois voltou a oferecer uma pasta que tinha acabado de importar, duas versões da mesma conversa que faltava entre camadas.</description><pubDate>Sun, 23 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>tauri</category><category>rust</category><category>dev-log</category><category>greenhouse</category></item><item><title>O diálogo que se fechava sozinho antes de eu conseguir usá-lo</title><link>https://imperfectsystems.com/pt/blog/dialog-that-closed-itself/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/dialog-that-closed-itself/</guid><description>Um callback renomeado para algo genérico manteve seu significado específico de wizard, e o mesmo sinal queria dizer duas coisas diferentes para dois ouvintes diferentes.</description><pubDate>Sat, 22 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>tauri</category><category>svelte</category><category>design</category><category>dev-log</category><category>greenhouse</category></item><item><title>Debugando um checkbox escondido na UI real do Medium</title><link>https://imperfectsystems.com/pt/blog/hidden-checkbox-medium-real-ui/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/hidden-checkbox-medium-real-ui/</guid><description>Um input invisível de tamanho zero atrás de um toggle estilizado, um estado disabled que engole cliques silenciosamente, e verificação contra a página real em vez dos meus próprios logs.</description><pubDate>Fri, 21 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>playwright</category><category>automation</category><category>syndication</category><category>dev-log</category><category>blog-manager</category></item><item><title>Colocando o pipeline de release do Greenhouse pra rodar no Mac Mini de uma câmera de segurança</title><link>https://imperfectsystems.com/pt/blog/greenhouse-release-pipeline-mac-mini/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/greenhouse-release-pipeline-mac-mini/</guid><description>Um build runner macOS self-hosted dividindo a máquina com um NVR, um empacotador de DMG que comanda o Finder via AppleScript, e a env var que sobrescreveu minha env var.</description><pubDate>Thu, 20 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>tauri</category><category>ci</category><category>macos</category><category>infrastructure</category><category>dev-log</category><category>greenhouse</category></item><item><title>Adicionando uma integração de newsletter com o Listmonk ao blog-manager</title><link>https://imperfectsystems.com/pt/blog/listmonk-newsletter-integration/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/listmonk-newsletter-integration/</guid><description>Um lote não é sincronização 1:1: por que a newsletter ganhou seu próprio model, a autenticação quase-Basic do Listmonk, um desvio de hostname num túnel, e uma peculiaridade do Brakeman.</description><pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>newsletter</category><category>dev-log</category><category>blog-manager</category></item><item><title>Uma seção de tracklist, e por que levou 30 minutos</title><link>https://imperfectsystems.com/pt/blog/tracklist-section-thirty-minutes/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/tracklist-section-thirty-minutes/</guid><description>Um método de protocolo, um enum de estado reaproveitado, uma convenção de roteamento que se manteve, e um orçamento de lint que forçou uma divisão que valia a pena fazer de qualquer forma.</description><pubDate>Tue, 18 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>The ULID spec admits its own bit math doesn&apos;t add up, then never explains it</title><link>https://imperfectsystems.com/pt/blog/the-ulid-spec-admits-its-own-bit-math-doesnt-add-up/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/the-ulid-spec-admits-its-own-bit-math-doesnt-add-up/</guid><description>A spec that states its own encoding wastes 2 bits and then never says how the remaining 128 map onto its two fields - decoded by trusting the spec&apos;s own worked example over its prose.</description><pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>security</category><category>testing</category><category>dev-log</category><category>freetoolbox</category></item><item><title>When an RFC test vector isn&apos;t the RFC&apos;s test vector</title><link>https://imperfectsystems.com/pt/blog/when-an-rfc-test-vector-isnt-the-rfcs-test-vector/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/when-an-rfc-test-vector-isnt-the-rfcs-test-vector/</guid><description>A fetched table of RFC hex values looked fine at a glance. Several entries were one character short - a summarization artifact, not a spec error, and it would have shipped silently if I&apos;d trusted it.</description><pubDate>Sun, 16 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>security</category><category>testing</category><category>dev-log</category><category>freetoolbox</category></item><item><title>Ensinando o Greenhouse a pré-visualizar áudio do vault dentro do app</title><link>https://imperfectsystems.com/pt/blog/greenhouse-vault-audio-preview/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/greenhouse-vault-audio-preview/</guid><description>Uma investigação no protocolo de assets do Tauri, um acesso em runtime para o vault do usuário, um alargamento estreito da CSP, e um bug de autoplay pego primeiro pelos testes de a11y.</description><pubDate>Sat, 15 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>tauri</category><category>rust</category><category>audio</category><category>dev-log</category><category>greenhouse</category></item><item><title>O scan de 8 segundos escondido em cada refresh</title><link>https://imperfectsystems.com/pt/blog/eight-second-scan-every-refresh/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/eight-second-scan-every-refresh/</guid><description>Medir no dispositivo encontrou um scan da biblioteca inteira rodando em cada lote do Discover - e uma armadilha de medição de 16x onde o cache HTTP favoreceu o caminho errado.</description><pubDate>Fri, 14 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>performance</category><category>musickit</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>try? transformou uma interrupção em &quot;all caught up&quot;</title><link>https://imperfectsystems.com/pt/blog/try-turned-outage-into-all-caught-up/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/try-turned-outage-into-all-caught-up/</guid><description>Um try? ?? [] fazia uma falha de rede parecer indistinguível de &quot;sem lançamentos&quot;, o que deixou uma interrupção guardar em cache um feed vazio por cima de dados bons durante 24 horas.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>error-handling</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>A configuração que funcionava perfeitamente e parecia completamente quebrada</title><link>https://imperfectsystems.com/pt/blog/setting-worked-perfectly-felt-broken/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/setting-worked-perfectly-felt-broken/</guid><description>Um filtro padrão que só era aplicado ao reabrir o app, porque uma TabView mantém os view models vivos e o estado semeado na construção fica congelado. A correção apagou um conceito.</description><pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>swiftui</category><category>ux</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Uma base de conhecimento para todos os seus agentes de IA</title><link>https://imperfectsystems.com/pt/blog/one-knowledge-base-all-agents/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/one-knowledge-base-all-agents/</guid><description>CLAUDE.md serve para convenções estáveis. O conhecimento bagunçado - pegadinhas, comportamento observado, lições de duas horas - precisa de um cofre central único, não uma cópia por repo.</description><pubDate>Tue, 11 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>ai</category><category>claude-code</category><category>knowledge-management</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Lançando o Deep Cut Atlas: o que quebrou na minha primeira submissão à App Store</title><link>https://imperfectsystems.com/pt/blog/shipping-deep-cut-atlas-first-submission/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/shipping-deep-cut-atlas-first-submission/</guid><description>Um consumível que deveria ter sido não consumível, um product ID que você nunca pode reutilizar, um archive que silenciosamente não foi rebuildado, e um rename com um pavio de duas semanas.</description><pubDate>Mon, 10 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>app-store</category><category>storekit</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>O runbook que mentiu duas vezes</title><link>https://imperfectsystems.com/pt/blog/runbook-that-lied-twice/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/runbook-that-lied-twice/</guid><description>Uma correção de uma linha na documentação virou três significados para um mesmo hostname, um diretório de runner renomeado, e uma automação que reintroduziu o bug que deveria prevenir.</description><pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>ci</category><category>documentation</category><category>infrastructure</category><category>dev-log</category><category>blog-manager</category></item><item><title>Fechando a porta que ninguém usava</title><link>https://imperfectsystems.com/pt/blog/closing-the-door-nobody-was-using/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/closing-the-door-nobody-was-using/</guid><description>O domínio apex não enviava nenhum e-mail e não tinha registro SPF nem DMARC, o que significava que qualquer um podia forjá-lo. Dois registros DNS, noventa segundos num painel, um dig para verificar.</description><pubDate>Sat, 08 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>security</category><category>dns</category><category>email</category><category>dev-log</category><category>site</category></item><item><title>O bug que na verdade era o depurador</title><link>https://imperfectsystems.com/pt/blog/bug-that-was-actually-the-debugger/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/bug-that-was-actually-the-debugger/</guid><description>O bug de corte mobile em todo o site que não existia: o Chrome headless trava silenciosamente num piso de 500px e recorta o screenshot para a largura que você pediu.</description><pubDate>Fri, 07 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>debugging</category><category>testing</category><category>dev-log</category><category>site</category></item><item><title>Três portas que nunca foram trancadas</title><link>https://imperfectsystems.com/pt/blog/three-doors-never-locked/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/three-doors-never-locked/</guid><description>Um CSP nulo, um valor de config unido a um caminho de arquivo sem checagem, e um seletor de vault que aceitaria seu diretório home, nada quebrado ainda, tudo destrancado.</description><pubDate>Thu, 06 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>tauri</category><category>rust</category><category>security</category><category>dev-log</category><category>greenhouse</category></item><item><title>O Medium ficava descartando minha imagem de capa, então a bridge agora cola ela direto</title><link>https://imperfectsystems.com/pt/blog/medium-bridge-hero-image/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/medium-bridge-hero-image/</guid><description>Duas teorias derrubadas com uma importação manual cada, um paste que salvou as dimensões mas não o src, e o caminho do seletor de arquivo nativo que finalmente anexou a imagem.</description><pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>playwright</category><category>automation</category><category>syndication</category><category>dev-log</category><category>blog-manager</category></item><item><title>Screenshots para um app sem simulador</title><link>https://imperfectsystems.com/pt/blog/screenshots-app-no-simulator/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/screenshots-app-no-simulator/</guid><description>O MusicKit não retorna nada no simulador, então as capturas de marketing vieram do serviço simulado que o app já tinha, mais as capas reais da API de busca da iTunes.</description><pubDate>Tue, 04 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>astro</category><category>ios</category><category>marketing</category><category>dev-log</category><category>site</category></item><item><title>Dark mode, e o teste de navegador que reagiu</title><link>https://imperfectsystems.com/pt/blog/dark-mode-browser-test-fought-back/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/dark-mode-browser-test-fought-back/</guid><description>light-dark() deixou o CSS fácil. Três falhas de tooling de teste deixaram o gate de contraste difícil. Depois, screenshots reais provaram que o gate verde não contava a história toda.</description><pubDate>Mon, 03 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>css</category><category>accessibility</category><category>testing</category><category>dev-log</category><category>greenhouse</category></item><item><title>Removendo um lock de cooldown que nunca foi fiel à fonte</title><link>https://imperfectsystems.com/pt/blog/removing-cooldown-lock/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/removing-cooldown-lock/</guid><description>O lock de 7 dias em projetos ativos era lógica de incubação de ideias colada no estágio errado do pipeline. A rotação já fazia a parte útil do trabalho.</description><pubDate>Sun, 02 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>tauri</category><category>rust</category><category>design</category><category>dev-log</category><category>greenhouse</category></item><item><title>Fazendo backfill da realidade num rastreador de sindicação</title><link>https://imperfectsystems.com/pt/blog/backfilling-reality-syndication-tracker/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/backfilling-reality-syndication-tracker/</guid><description>O prod dizia zero posts no Medium; as rake tasks resolveram isso em minutos. Depois o reconciler quebrou em todo lugar, um dashboard foi raspado direto do DOM, e o CI falhou de três formas diferentes.</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>ci</category><category>dev-log</category><category>blog-manager</category></item><item><title>O bug atrás do bug</title><link>https://imperfectsystems.com/pt/blog/the-bug-behind-the-bug/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/the-bug-behind-the-bug/</guid><description>Um widget do GitHub quebrado rastreado até uma demo upstream pausada, e, encontrado no caminho, um CSP fixado por hash silenciosamente invalidado por uma correção de acessibilidade de uma linha.</description><pubDate>Fri, 31 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>security</category><category>maintenance</category><category>dev-log</category><category>site</category></item><item><title>Sincronização via iCloud restrita ao Pro para a lista &quot;Não Interessado&quot;</title><link>https://imperfectsystems.com/pt/blog/pro-gated-icloud-sync/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/pro-gated-icloud-sync/</guid><description>Um blob no KVS com tombstones em vez de CloudKit-em-tudo, um decorator que mantém usuários free longe do iCloud por completo, e provar que a sincronização funciona com só um dispositivo.</description><pubDate>Thu, 30 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>icloud</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>O rastreador de syndication que não conseguia responder sua própria pergunta</title><link>https://imperfectsystems.com/pt/blog/syndication-tracker-couldnt-answer/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/syndication-tracker-couldnt-answer/</guid><description>Ausência codificada como pills faltando, becos sem saída no fluxo de publicação, um teste de sistema que teria mergeado vermelho em silêncio, e firewall que bloqueou toda saída dos containers.</description><pubDate>Wed, 29 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>infrastructure</category><category>dev-log</category><category>blog-manager</category></item><item><title>Rescue-or-Keep: construindo a zona de vault para o Greenhouse</title><link>https://imperfectsystems.com/pt/blog/rescue-or-keep-vault-zone/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/rescue-or-keep-vault-zone/</guid><description>Agora arquivar no vault realmente move seus arquivos, e um &quot;Keep Vaulted&quot; que não era um no-op de verdade - reagendar teria resetado o timestamp que a revisão diária usa para ordenar.</description><pubDate>Tue, 28 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>tauri</category><category>rust</category><category>svelte</category><category>dev-log</category><category>greenhouse</category></item><item><title>O CSP que só quebrou em produção</title><link>https://imperfectsystems.com/pt/blog/csp-only-broke-in-production/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/csp-only-broke-in-production/</guid><description>Quatro falhas atrás de um único header: middleware morto, regras de _headers que se combinam em vez de sobrescrever, um worker de blob URL sob script-src, e um script que só o edge injeta.</description><pubDate>Mon, 27 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>security</category><category>cloudflare</category><category>astro</category><category>dev-log</category><category>site</category></item><item><title>Entregando um recurso de pacote compartilhado em dois repositórios para uma única rota</title><link>https://imperfectsystems.com/pt/blog/shared-package-feature-two-repos/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/shared-package-feature-two-repos/</guid><description>Um feed RSS que se dividiu num helper puro no pacote compartilhado e numa rota local por site, além da disciplina de release que uma dependência de tarball fixada por tag exige.</description><pubDate>Sun, 26 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>astro</category><category>rss</category><category>dev-log</category><category>astro-tools</category></item><item><title>Construindo a tela de detalhes de projeto do Greenhouse</title><link>https://imperfectsystems.com/pt/blog/greenhouse-project-detail-view/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/greenhouse-project-detail-view/</guid><description>Avançar um estágio conta como um toque, o que acontece no último estágio, e uma tangente de cooldown-vs-rotação que acabou sendo uma pergunta só, não duas.</description><pubDate>Sat, 25 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>tauri</category><category>rust</category><category>svelte</category><category>dev-log</category><category>greenhouse</category></item><item><title>O 404 que já estava certo, e o robots.txt que não estava</title><link>https://imperfectsystems.com/pt/blog/404-correct-robots-txt-wasnt/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/404-correct-robots-txt-wasnt/</guid><description>Uma diretiva Sitemap que precisava apontar para o índice, um fix de 404 que quase foi construído a mais, e um comportamento documentado da Cloudflare que não se confirmou na prática.</description><pubDate>Fri, 24 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>astro</category><category>seo</category><category>cloudflare</category><category>dev-log</category><category>site</category></item><item><title>Reconciliando cross-posts do Medium que o blog-manager nunca tinha registrado</title><link>https://imperfectsystems.com/pt/blog/reconciling-medium-cross-posts/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/reconciling-medium-cross-posts/</guid><description>Um feed RSS que trava silenciosamente em 10 itens, um backfill com chave sintética e uma regra de precedência que só faz upgrade, e 76 de 78 títulos batendo sem nenhuma lógica difusa.</description><pubDate>Thu, 23 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>syndication</category><category>dev-log</category><category>blog-manager</category></item><item><title>Dando um rosto para cada link compartilhado</title><link>https://imperfectsystems.com/pt/blog/giving-every-share-link-a-face/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/giving-every-share-link-a-face/</guid><description>Uma proteção de og:image que nunca disparava, um valor padrão de uma linha que resolveu, um card de terminal feito sob medida, e uma pegadinha de retina no Chrome headless.</description><pubDate>Wed, 22 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>astro</category><category>seo</category><category>dev-log</category><category>site</category></item><item><title>Uma decisão de UX que errei na primeira tentativa</title><link>https://imperfectsystems.com/pt/blog/ux-decision-wrong-first-try/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/ux-decision-wrong-first-try/</guid><description>A ação de adicionar à playlist combinava com o gesto irmão no mesmo card, e brigava com o resto do app. Escolher o ponto de referência errado para «consistente».</description><pubDate>Tue, 21 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>ux</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Três vezes em que &quot;a spec dizia X&quot; estava errada</title><link>https://imperfectsystems.com/pt/blog/three-ways-the-spec-was-wrong/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/three-ways-the-spec-was-wrong/</guid><description>Um symlink apontando para lugar nenhum, uma correção já enfileirada pela automação, e docs descrevendo componentes que não existem, três fontes de verdade, a mesma lição em cada uma.</description><pubDate>Mon, 20 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>maintenance</category><category>documentation</category><category>dev-log</category><category>site</category></item><item><title>Provando que o backup realmente funciona</title><link>https://imperfectsystems.com/pt/blog/proving-the-backup-works/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/proving-the-backup-works/</guid><description>&quot;Temos backups&quot; e &quot;temos backups que funcionam&quot; são afirmações diferentes. Uma restauração a nível de arquivo, uma query contra os dados restaurados, e uma cópia perdida limpa pelo caminho.</description><pubDate>Sun, 19 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>backups</category><category>infrastructure</category><category>dev-log</category><category>blog-manager</category></item><item><title>Um gate de acessibilidade de dois segundos que roda a cada push</title><link>https://imperfectsystems.com/pt/blog/two-second-accessibility-gate/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/two-second-accessibility-gate/</guid><description>axe-core sobre o harness de testes de componente já existente, restrito às regras WCAG de verdade, e uma prestação de contas honesta sobre o que um gate em jsdom estruturalmente não consegue pegar.</description><pubDate>Sat, 18 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>accessibility</category><category>testing</category><category>svelte</category><category>dev-log</category><category>greenhouse</category></item><item><title>Três linhas de config, uma tarde de verificação</title><link>https://imperfectsystems.com/pt/blog/three-lines-config-afternoon-verification/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/three-lines-config-afternoon-verification/</guid><description>Descomentar flags de SSL do Rails levou dez minutos. Ler o código-fonte do framework, testar dois achados de revisão plausíveis mas errados, e provar o cookie em produção levou o resto do tempo.</description><pubDate>Fri, 17 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>security</category><category>dev-log</category><category>blog-manager</category></item><item><title>O favicon que ficou quebrado por meses e ninguém teria percebido</title><link>https://imperfectsystems.com/pt/blog/favicon-broken-for-months/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/favicon-broken-for-months/</guid><description>Um lote de otimização de performance com uma metade fácil (prerender, otimização de PNG) e uma falha silenciosa: um favicon SVG cuja referência de imagem externa os navegadores descartam sem avisar.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>astro</category><category>performance</category><category>dev-log</category><category>site</category></item><item><title>A aba Discover que ficou permanentemente presa cavando</title><link>https://imperfectsystems.com/pt/blog/discover-tab-stuck-digging/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/discover-tab-stuck-digging/</guid><description>Uma busca de artista que falhava nunca contava como checada, então um artista ruim se reselecionava para sempre - até um teste de várias rodadas achar a segunda proteção.</description><pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>musickit</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Testar um gate de deploy acabou fazendo o deploy da coisa que eu estava testando</title><link>https://imperfectsystems.com/pt/blog/deploy-gate-deployed-the-thing/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/deploy-gate-deployed-the-thing/</guid><description>Adicionando astro check e Prettier antes de cada deploy, um erro de tipo que o site irmão já tinha resolvido, e um gatilho manual de build sem nenhum conceito de dry run.</description><pubDate>Tue, 14 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>astro</category><category>cloudflare</category><category>ci</category><category>dev-log</category><category>site</category></item><item><title>Uma correção de desvio de documentação que não foi tão chata quanto parecia</title><link>https://imperfectsystems.com/pt/blog/doc-drift-fix-not-boring/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/doc-drift-fix-not-boring/</guid><description>Três itens da auditoria que cada um virou outra coisa: uma alegação meio corrigida, uma recuperação de senha silenciosamente morta, e um e-mail de staging que apontaria para produção.</description><pubDate>Mon, 13 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>dev-log</category><category>blog-manager</category></item><item><title>Uma varredura de documentação que encontrou duas alegações desatualizadas a mais do que o esperado</title><link>https://imperfectsystems.com/pt/blog/docs-sweep-two-more-stale-claims/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/docs-sweep-two-more-stale-claims/</guid><description>Seis itens de desvio já conhecidos, dois a mais encontrados ao rodar os comandos documentados, e uma correção de nome que a memória do projeto deixou mais restrita que um find-replace.</description><pubDate>Sun, 12 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>documentation</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Fixando a versão do SwiftLint na CI quando o Homebrew não deixa</title><link>https://imperfectsystems.com/pt/blog/pinning-swiftlint-ci-homebrew/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/pinning-swiftlint-ci-homebrew/</guid><description>brew install swiftlint quer dizer &quot;o que estiver estável hoje&quot;, e a execução de CI mais exposta a essa deriva é a tag de release. O ponto de fixação é o binário portátil, não uma formula.</description><pubDate>Sat, 11 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>ci</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Ensinando um agente a testar cliques no meu app Tauri</title><link>https://imperfectsystems.com/pt/blog/click-testing-tauri-app/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/click-testing-tauri-app/</guid><description>O macOS não tem um WebDriver oficial do Tauri, um plugin da comunidade preenche essa lacuna, e a unificação de features do Cargo quase compilou o servidor de teste inteiro nos builds de release.</description><pubDate>Fri, 10 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>tauri</category><category>rust</category><category>testing</category><category>dev-log</category><category>greenhouse</category></item><item><title>Escrevendo testes que checam a coisa certa</title><link>https://imperfectsystems.com/pt/blog/tests-that-check-the-right-thing/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/tests-that-check-the-right-thing/</guid><description>Duas lacunas de cobertura fechadas, e a pergunta mais útil que uma revisão fez depois: não «isso passa» mas «o que esse teste realmente pegaria».</description><pubDate>Thu, 09 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>testing</category><category>dev-log</category><category>blog-manager</category></item><item><title>Fechando as lacunas de teste: lógica pura, um branch de mock inalcançável, e uma virada para Swift 6</title><link>https://imperfectsystems.com/pt/blog/closing-test-gaps-swift-6-flip/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/closing-test-gaps-swift-6-flip/</guid><description>Extraindo algoritmos para fora do alcance do MusicKit, um parâmetro de mock que era silenciosamente ignorado, e dois testes que vinham passando pelo motivo errado o tempo todo.</description><pubDate>Wed, 08 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>testing</category><category>swift-concurrency</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Um segfault que não era um bug, e a API que eu finalmente apaguei</title><link>https://imperfectsystems.com/pt/blog/segfault-wasnt-a-bug/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/segfault-wasnt-a-bug/</guid><description>Uma limpeza da camada de serviço do MusicKit em que apagar métodos mortos travou todos os testes de uma vez, e a solução foi um build limpo, não um debugger.</description><pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>testing</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>O deploy do Cloudflare Workers Builds que falhou por causa de um arquivo de config discordando de si mesmo</title><link>https://imperfectsystems.com/pt/blog/cloudflare-workers-builds-config/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/cloudflare-workers-builds-config/</guid><description>Substituindo o GitHub Actions morto pelo Workers Builds, uma flag --config que faltava e que o workflow antigo sempre teve, e o tipo de token que a API do Builds do Cloudflare se recusa a aceitar.</description><pubDate>Mon, 06 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>cloudflare</category><category>ci</category><category>astro</category><category>dev-log</category><category>site</category></item><item><title>Consertando o load path da History, e me pegando comentando demais o ajuste</title><link>https://imperfectsystems.com/pt/blog/history-load-path-over-commenting/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/history-load-path-over-commenting/</guid><description>Três fetches sequenciais em que um nem era necessário de cara, dois recálculos quadráticos, e um linter que expôs por que eu estava realmente escrevendo todos aqueles comentários.</description><pubDate>Sun, 05 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>performance</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Consertando um redirect, e o caso extremo que uma linha deixou passar</title><link>https://imperfectsystems.com/pt/blog/fixing-redirect-edge-case/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/fixing-redirect-edge-case/</guid><description>Um fix de uma palavra no caminho de retorno do login que um scanner e uma revisão pegaram incompleto, cada um do seu jeito: requisições HEAD escapando, e uma URL guardada e nunca limpa.</description><pubDate>Sat, 04 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>security</category><category>dev-log</category><category>blog-manager</category></item><item><title>Um ticket de hardening que precisou ser re-derivado antes de eu poder implementá-lo</title><link>https://imperfectsystems.com/pt/blog/hardening-ticket-re-deriving/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/hardening-ticket-re-deriving/</guid><description>Uma tarefa desatualizada que desfaria a migração de CI, uma correção de master key que foi de encolher a janela a fechá-la de vez, e um parser que engole em silêncio sintaxe plausível.</description><pubDate>Fri, 03 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ci</category><category>security</category><category>kamal</category><category>dev-log</category><category>blog-manager</category></item><item><title>A armadilha do isolamento de actor em &quot;só tira isso da main thread&quot;</title><link>https://imperfectsystems.com/pt/blog/actor-isolation-trap-off-main-thread/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/actor-isolation-trap-off-main-thread/</guid><description>Conformidades a Codable sintetizadas pelo compilador também herdam o isolamento padrão em MainActor, e async let tem exigências mais rígidas que a task que você já tinha.</description><pubDate>Thu, 02 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>swift-concurrency</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Um 500 escondido dentro das rotas isoladas de uma engine montada</title><link>https://imperfectsystems.com/pt/blog/500-hiding-mounted-engine-routes/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/500-hiding-mounted-engine-routes/</guid><description>O painel de jobs retornava um 500 em vez de uma página de login: helpers de rota sem qualificação resolvem contra a engine, não contra a aplicação. Uma linha, mais o gêmeo dormente dela.</description><pubDate>Wed, 01 Jul 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>dev-log</category><category>blog-manager</category></item><item><title>Um teste que não provou nada, e o bug que ele deveria pegar</title><link>https://imperfectsystems.com/pt/blog/test-that-proved-nothing/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/test-that-proved-nothing/</guid><description>Um lote de limpeza com cinco descobertas, onde o menor item foi o que mais importou: um teste de regressão que falhou porque o bug que ele mirava é estruturalmente inalcançável.</description><pubDate>Tue, 30 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rust</category><category>sqlite</category><category>testing</category><category>dev-log</category><category>greenhouse</category></item><item><title>Apagando código morto, e pegando um motivo errado para uma resposta certa</title><link>https://imperfectsystems.com/pt/blog/deleting-dead-code-wrong-reason/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/deleting-dead-code-wrong-reason/</guid><description>Uma issue de limpeza com uma justificativa errada, uma varredura de documentação que não era necessária, e a credencial órfã que uma revisão pegou.</description><pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>dev-log</category><category>blog-manager</category></item><item><title>O scan da biblioteca inteira que eu achava que já tinha corrigido</title><link>https://imperfectsystems.com/pt/blog/whole-library-scan-thought-fixed/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/whole-library-scan-thought-fixed/</guid><description>Um padrão não se corrige de uma vez só. Mais um scan de biblioteca no main actor escondido num caminho de escrita, e a API em lote que só tinha sido conectada numa direção.</description><pubDate>Sun, 28 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>musickit</category><category>performance</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Lendo changelogs antes de atualizar três dependências desatualizadas</title><link>https://imperfectsystems.com/pt/blog/reading-changelogs-before-bumping/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/reading-changelogs-before-bumping/</guid><description>Um crate de YAML arquivado, nove versões menores de deriva no rusqlite, e uma major duplicada do thiserror. O trabalho foi a leitura, não a escrita.</description><pubDate>Sat, 27 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rust</category><category>dependencies</category><category>dev-log</category><category>greenhouse</category></item><item><title>Movendo o CI para um runner self-hosted depois que o GitHub quebrou nosso billing</title><link>https://imperfectsystems.com/pt/blog/ci-self-hosted-runner-after-billing/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/ci-self-hosted-runner-after-billing/</guid><description>CI morto, deploys ao vivo: dobrando todo job no runner do homelab, apagando a maquinaria de compensação de runner hospedado, e o backlog de CVEs esperando atrás do gate.</description><pubDate>Fri, 26 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ci</category><category>github-actions</category><category>dev-log</category><category>blog-manager</category></item><item><title>Adicionando o Dependabot ao Greenhouse (e a pegadinha do workspace Rust que ele revelou)</title><link>https://imperfectsystems.com/pt/blog/dependabot-greenhouse-rust-workspace/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/dependabot-greenhouse-rust-workspace/</guid><description>Escaneamento de dependências sem um novo job de CI, PRs de atualização agrupados, e o detalhe do workspace virtual que faz o cargo apontar para o diretório errado.</description><pubDate>Thu, 25 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rust</category><category>dependabot</category><category>ci</category><category>dev-log</category><category>greenhouse</category></item><item><title>Impedindo que a lacuna de posts sem imagem de destaque volte (uma trava, não um lembrete)</title><link>https://imperfectsystems.com/pt/blog/stopping-heroless-post-gap/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/stopping-heroless-post-gap/</guid><description>Uma limpeza pontual corrigiu 80 posts e não garantiu nada para o futuro. A segunda correção são doze linhas que quebram o build, sem exceções.</description><pubDate>Wed, 24 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>astro</category><category>ci</category><category>tooling</category><category>dev-log</category><category>blog-manager</category></item><item><title>Minha aba Discover estava vazia porque fiz a pergunta errada para o Apple Music</title><link>https://imperfectsystems.com/pt/blog/discover-tab-empty-wrong-question/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/discover-tab-empty-wrong-question/</guid><description>IDs de biblioteca usados em requisições de catálogo: dois sintomas, um bug só, uma correção verificada no dispositivo, e o número de 1.610 artistas que forçou um redesenho.</description><pubDate>Tue, 23 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>musickit</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Quando um conjunto de filtros silenciosamente vira uma funcionalidade</title><link>https://imperfectsystems.com/pt/blog/filter-set-becomes-a-feature/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/filter-set-becomes-a-feature/</guid><description>O armazenamento de &apos;Não Tenho Interesse&apos; só guardava chaves. Depois ele precisou virar uma tela, e o modelo precisou carregar sua própria descrição.</description><pubDate>Mon, 22 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>swiftdata</category><category>cloudkit</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Construindo o Greenhouse: as primeiras telas</title><link>https://imperfectsystems.com/pt/blog/building-greenhouse-first-screens/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/building-greenhouse-first-screens/</guid><description>O arco da UI: uma shell de assistente construída antes de suas paredes existirem, um fluxo de captura removido por estar errado, e os buracos entre marcações verdes e a verdade.</description><pubDate>Sun, 21 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rust</category><category>tauri</category><category>svelte</category><category>dev-log</category><category>greenhouse</category></item><item><title>Os botões não estavam quebrados: a main thread estava ocupada</title><link>https://imperfectsystems.com/pt/blog/buttons-werent-broken-main-thread-busy/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/buttons-werent-broken-main-thread-busy/</guid><description>118 testes verdes, uma passada limpa no simulador, e botões mortos num telefone de verdade. O bug era um serviço @MainActor fazendo trabalho síncrono entre awaits.</description><pubDate>Sat, 20 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>swiftui</category><category>performance</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Construindo o Greenhouse: o vault em disco</title><link>https://imperfectsystems.com/pt/blog/building-greenhouse-vault-on-disk/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/building-greenhouse-vault-on-disk/</guid><description>O layout de pastas que sobrevive ao app: zonas versus estágios, uma config que se recusa a sobrescrever, um arquivo retrato do banco de dados, e o parâmetro que não fazia nada.</description><pubDate>Fri, 19 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rust</category><category>tauri</category><category>sqlite</category><category>dev-log</category><category>greenhouse</category></item><item><title>Construindo o Greenhouse: o motor de regras que veio antes de o app existir</title><link>https://imperfectsystems.com/pt/blog/building-greenhouse-the-rules-engine-that-came-before-the-app-existed/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/building-greenhouse-the-rules-engine-that-came-before-the-app-existed/</guid><description>Escrevendo um motor de regras completo em Rust e 22 testes antes de o Greenhouse ter uma UI, ou até um toolchain Rust funcionando na máquina, e o que quebrou assim que ele finalmente compilou.</description><pubDate>Thu, 18 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rust</category><category>tauri</category><category>sqlite</category><category>dev-log</category><category>greenhouse</category></item><item><title>Começando um dev log</title><link>https://imperfectsystems.com/pt/blog/hello-dev-log/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/hello-dev-log/</guid><description>Por que a Imperfect Systems mantém um dev log público, e como o blog funciona por baixo dos panos.</description><pubDate>Wed, 17 Jun 2026 00:00:00 GMT</pubDate><category>Meta</category><category>astro</category><category>dev-log</category><category>meta</category><category>site</category></item><item><title>Compartilhando um blog Astro entre dois sites</title><link>https://imperfectsystems.com/pt/blog/sharing-astro-blog-across-two-sites/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/sharing-astro-blog-across-two-sites/</guid><description>Você não consegue extrair um blog, mas consegue extrair seus componentes: um contrato de tokens para duas paletas, e as duas mordidas de CI que nunca acontecem num notebook.</description><pubDate>Tue, 16 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>astro</category><category>npm</category><category>ci</category><category>dev-log</category><category>astro-tools</category></item><item><title>O status que nada nunca escreveu (dev log do motor do Greenhouse)</title><link>https://imperfectsystems.com/pt/blog/the-status-that-nothing-ever-wrote/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/the-status-that-nothing-ever-wrote/</guid><description>Um status que nenhum código definia, um parser que chutava, e uma revisão que achou mais: ordenações ao contrário, uma restrição não aplicada, e um config que podia quebrar o app.</description><pubDate>Mon, 15 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rust</category><category>sqlite</category><category>tauri</category><category>dev-log</category><category>greenhouse</category></item><item><title>O último publisher nativo: fechando a consolidação do Postiz</title><link>https://imperfectsystems.com/pt/blog/last-native-publisher-postiz-consolidation/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/last-native-publisher-postiz-consolidation/</guid><description>A integração nativa do Medium era uma peça de museu. Uma ponte de navegador, um artigo cujo corpo é uma URL, e menos 1.603 linhas.</description><pubDate>Sat, 13 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>postiz</category><category>medium</category><category>dev-log</category><category>blog-manager</category></item><item><title>Correndo contra a main actor: quando o await é a condição de corrida</title><link>https://imperfectsystems.com/pt/blog/racing-the-main-actor-await/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/racing-the-main-actor-await/</guid><description>@MainActor elimina data races, não races de interleaving. Um token de geração, uma guarda contra falha desatualizada, e um teste de race determinístico sem sleeps.</description><pubDate>Fri, 12 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>swift-concurrency</category><category>swift-testing</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Dark mode numa tarde quando seu CSS já é tokens (e o falso alarme que não era)</title><link>https://imperfectsystems.com/pt/blog/dark-mode-afternoon-css-tokens/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/dark-mode-afternoon-css-tokens/</guid><description>Um tema dark inteiro redefinindo variáveis CSS sob uma classe, e 45 minutos gastos provando a inocência de um toggle de cinco linhas.</description><pubDate>Thu, 11 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>css</category><category>tailwind</category><category>dev-log</category><category>blog-manager</category></item><item><title>&quot;Looks the same to me&quot;</title><link>https://imperfectsystems.com/pt/blog/looks-the-same-to-me/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/looks-the-same-to-me/</guid><description>A UI redesign, a review comment that named the exact property I never touched, and what it takes to actually fix what someone reports instead of what&apos;s around it.</description><pubDate>Wed, 10 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>tailwind</category><category>dev-log</category><category>blog-manager</category></item><item><title>Meus mocks não conseguiam falhar: injeção de erro e um crash de isolamento no Swift 6</title><link>https://imperfectsystems.com/pt/blog/mocks-couldnt-fail-error-injection/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/mocks-couldnt-fail-error-injection/</guid><description>Todo branch de catch era código morto nos testes. Uma costura de falha de 15 linhas resolveu isso, e depois uma suíte de testes sem anotação derrubou o runner inteiro.</description><pubDate>Tue, 09 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>swift-testing</category><category>testing</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Add a feature, or move a responsibility?</title><link>https://imperfectsystems.com/pt/blog/add-a-feature-or-move-a-responsibility/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/add-a-feature-or-move-a-responsibility/</guid><description>Adding Postiz social cross-posting looked done until a blunt question exposed a double-post bug, and a full audit of every posting path in the app found two more like it.</description><pubDate>Mon, 08 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>postiz</category><category>dev-log</category><category>blog-manager</category></item><item><title>Revisei meu próprio app iOS com cinco agentes em paralelo: veja o que eles encontraram</title><link>https://imperfectsystems.com/pt/blog/five-parallel-agents-ios-review/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/five-parallel-agents-ios-review/</guid><description>Cinco fatias de ~700 linhas, briefings que também perguntam o que está bem feito, e a etapa de verificação que separou bugs reais dos só plausíveis.</description><pubDate>Sun, 07 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>claude-code</category><category>code-review</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Apagando uma integração ao migrar ela para o Postiz</title><link>https://imperfectsystems.com/pt/blog/deleting-devto-integration-moving-to-postiz/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/deleting-devto-integration-moving-to-postiz/</guid><description>Roteando a publicação no Dev.to pelo Postiz e apagando o cliente nativo: o DTO que valida mais rígido que o runtime, o rascunho que não é rascunho, e uma capa perdida no storage local.</description><pubDate>Sat, 06 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>postiz</category><category>devto</category><category>dev-log</category><category>blog-manager</category></item><item><title>Configurando SwiftLint e CI do GitHub Actions para um app iOS (e o runner que mentiu)</title><link>https://imperfectsystems.com/pt/blog/swiftlint-github-actions-ci-ios/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/swiftlint-github-actions-ci-ios/</guid><description>Adotando um linter em um código que nunca teve um, um hook de pre-commit sem framework, e três coisas que o runner macOS fez que a documentação não mencionava.</description><pubDate>Fri, 05 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>swiftlint</category><category>github-actions</category><category>ci</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Desbloqueio vitalício com StoreKit 2 num app SwiftUI em Swift 6: três coisas que me pegaram</title><link>https://imperfectsystems.com/pt/blog/storekit-2-lifetime-unlock-three-things/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/storekit-2-lifetime-unlock-three-things/</guid><description>A API de compra é a parte fácil. As junções entre StoreKit 2, isolamento do Swift 6 e observação do SwiftUI foram onde o tempo foi.</description><pubDate>Thu, 04 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>storekit</category><category>swiftui</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Apagando uma integração de publicação que eu tinha acabado de construir</title><link>https://imperfectsystems.com/pt/blog/deleting-publishing-integration-hashnode-postiz/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/deleting-publishing-integration-hashnode-postiz/</guid><description>Removendo a integração nativa com o Hashnode que nunca foi usada: 31 arquivos, +14/-1126, um grep que mentiu um pouco, e a pergunta de arquitetura que a remoção forçou.</description><pubDate>Wed, 03 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>hashnode</category><category>postiz</category><category>dev-log</category><category>blog-manager</category></item><item><title>O webhook do Postiz que eu não consegui construir, e o polling em vez dele</title><link>https://imperfectsystems.com/pt/blog/postiz-webhook-polling-instead/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/postiz-webhook-polling-instead/</guid><description>Um spike que terminou em &quot;não construa isso&quot;: rejeição de IP privado, um payload vazio sem autenticação, e a pull API que tinha tudo que a push API não tinha.</description><pubDate>Tue, 02 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>postiz</category><category>dev-log</category><category>blog-manager</category></item><item><title>Construindo um player de música que eu não consigo ouvir</title><link>https://imperfectsystems.com/pt/blog/building-music-player-i-cant-hear/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/building-music-player-i-cant-hear/</guid><description>Um mini-player inline para quando o playback do MusicKit fica mudo no simulador: um protocolo de dois métodos, um indicador que mente de forma honesta, e um bug deixado de propósito.</description><pubDate>Mon, 01 Jun 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>musickit</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>O teste do SwiftData que falhou sem nenhuma mensagem de erro</title><link>https://imperfectsystems.com/pt/blog/swiftdata-test-crashed-no-error-message/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/swiftdata-test-crashed-no-error-message/</guid><description>Cinco testes reportando um «Crash» genérico: um helper bem-intencionado deixou o ModelContainer ser desalocado enquanto o store manteve seu context. Um context é algo emprestado.</description><pubDate>Sun, 31 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>swiftdata</category><category>swift-testing</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Quando @MainActor e TaskGroup não combinam no Swift 6</title><link>https://imperfectsystems.com/pt/blog/mainactor-taskgroup-swift-6/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/mainactor-taskgroup-swift-6/</guid><description>O checker de isolamento baseado em regiões manda eu abrir um bug, e a Task não estruturada, hoje fora de moda, acaba sendo a ferramenta certa.</description><pubDate>Sat, 30 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>swift-concurrency</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Agendamento e compartilhamento de link mais inteligente no meu cross-poster do Postiz</title><link>https://imperfectsystems.com/pt/blog/postiz-scheduling-link-sharing/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/postiz-scheduling-link-sharing/</guid><description>Agendamento para o futuro, blurbs mais ricos com thumbnails, um seletor de qual URL usar, além do bug de timezone no horário de parede e a importação que copiou a coluna errada.</description><pubDate>Fri, 29 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>postiz</category><category>dev-log</category><category>blog-manager</category></item><item><title>O Apple Music dá dois IDs diferentes para o mesmo álbum</title><link>https://imperfectsystems.com/pt/blog/apple-music-same-album-two-ids/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/apple-music-same-album-two-ids/</guid><description>Construindo o fluxo de adicionar à biblioteca e aprendendo que as cópias de biblioteca e de catálogo do MusicKit para um mesmo álbum são objetos sem relação nenhuma, no que diz respeito aos IDs.</description><pubDate>Thu, 28 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>musickit</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Construindo uma interface para dados que ainda não consigo ver (agrupando por álbum uma playlist do MusicKit)</title><link>https://imperfectsystems.com/pt/blog/building-ui-for-data-i-cant-see-yet/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/building-ui-for-data-i-cant-see-yet/</guid><description>Lançando uma tela de playlist agrupada por álbum contra dados falsos: a flag de EP que não existe, os campos que moram em Album e não em Track, e o teste desatualizado que provou seu valor.</description><pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>musickit</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Construindo um app com MusicKit quando o MusicKit não roda no simulador</title><link>https://imperfectsystems.com/pt/blog/musickit-app-simulator-mock-service/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/musickit-app-simulator-mock-service/</guid><description>Um protocolo, um serviço real e um mock que registra suas escritas: tornando o simulador útil de novo, além do imprevisto com worktree e a armadilha do target recém-criado.</description><pubDate>Mon, 25 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>musickit</category><category>swift-testing</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>A mudança de config que já estava feita (API pública do Postiz)</title><link>https://imperfectsystems.com/pt/blog/config-change-already-done-postiz/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/config-change-already-done-postiz/</guid><description>Um ticket pré-requisito dizia para ativar uma flag que já estava ligada. Ler o código-fonte na tag em produção transformou um no-op em três correções.</description><pubDate>Sun, 24 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>postiz</category><category>self-hosting</category><category>ruby</category><category>dev-log</category><category>blog-manager</category></item><item><title>Deixando o Claude Code dirigir o Xcode: o truque dos synchronized groups</title><link>https://imperfectsystems.com/pt/blog/claude-code-xcode-synchronized-groups/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/claude-code-xcode-synchronized-groups/</guid><description>Um agente não consegue clicar no assistente de New Project. Os file-system synchronized groups do Xcode 16 são a costura que permite a ele dominar cada arquivo de código-fonte mesmo assim.</description><pubDate>Sat, 23 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>xcode</category><category>claude-code</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Configurando o Claude Code para um projeto iOS</title><link>https://imperfectsystems.com/pt/blog/setting-up-claude-code-for-an-ios-project/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/setting-up-claude-code-for-an-ios-project/</guid><description>Escrevendo o CLAUDE.md de um app iOS antes de existir Swift: a armadilha do MusicKit no simulador, as regras do CloudKit para SwiftData, e o enquadramento de aprendizado que veio primeiro.</description><pubDate>Fri, 22 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>ios</category><category>swift</category><category>musickit</category><category>claude-code</category><category>dev-log</category><category>deep-cut-atlas</category></item><item><title>Cross-posting no Hashnode no blog manager</title><link>https://imperfectsystems.com/pt/blog/hashnode-cross-posting-blog-manager/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/hashnode-cross-posting-blog-manager/</guid><description>Um terceiro alvo de sindicação, o primeiro em GraphQL: sem gem de cliente, publicação em duas etapas, sincronização por slug, e três colunas de credenciais que fazem jus ao espaço.</description><pubDate>Thu, 21 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>hashnode</category><category>graphql</category><category>dev-log</category><category>blog-manager</category></item><item><title>Adicionando o Dev.to como um alvo de syndication</title><link>https://imperfectsystems.com/pt/blog/adding-devto-syndication-target/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/adding-devto-syndication-target/</guid><description>A API do Forem como o anti-Medium, um serviço compartilhado de anúncio no LinkedIn com idempotência, e a armadilha do acrônimo no Zeitwerk que pegou duas vezes.</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>devto</category><category>dev-log</category><category>blog-manager</category></item><item><title>Construindo um backfill de sindicação de blog</title><link>https://imperfectsystems.com/pt/blog/blog-syndication-backfill/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/blog-syndication-backfill/</guid><description>72 posts no Medium que meu banco de dados não conhecia: o limite do RSS, um workaround não documentado em GraphQL, apóstrofos Unicode, e a armadilha do stdin do kamal.</description><pubDate>Tue, 19 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>medium</category><category>dev-log</category><category>blog-manager</category></item><item><title>Desembaraçando a dependência do Colima nos deploys do Kamal</title><link>https://imperfectsystems.com/pt/blog/untangling-colima-dependency-kamal-deploys/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/untangling-colima-dependency-kamal-deploys/</guid><description>O daemon Docker do meu Mac era uma peça estrutural dos deploys de produção. Build-once-deploy-many com o Kamal 2, e as três suposições da pesquisa que estavam erradas.</description><pubDate>Mon, 18 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>kamal</category><category>docker</category><category>ci</category><category>github-actions</category><category>dev-log</category><category>blog-manager</category></item><item><title>Quando o Medium não tem API: polling de RSS e cross-posting pro LinkedIn</title><link>https://imperfectsystems.com/pt/blog/medium-rss-polling-linkedin-cross-posting/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/medium-rss-polling-linkedin-cross-posting/</guid><description>Detectando publicações no Medium via polling do feed RSS, os quatro headers obrigatórios do LinkedIn, e a regra de acrônimo do Zeitwerk que quebrou o rollback de migration no CI.</description><pubDate>Sun, 10 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>medium</category><category>linkedin</category><category>dev-log</category><category>blog-manager</category></item><item><title>Adicionando links dos posts ao vivo no painel</title><link>https://imperfectsystems.com/pt/blog/live-blog-url-links-post-dashboard/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/live-blog-url-links-post-dashboard/</guid><description>Fazendo os títulos do painel linkarem para os posts ao vivo: um prefixo de caminho configurável, uma trava por pub_date contra links quebrados, e uma coluna do spec que descartei.</description><pubDate>Sat, 09 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>dev-log</category><category>blog-manager</category></item><item><title>Adicionando busca de imagens do Pexels ao meu gerenciador de blog</title><link>https://imperfectsystems.com/pt/blog/pexels-image-search-blog-manager/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/pexels-image-search-blog-manager/</guid><description>Busca do Pexels na própria página com Turbo Frames, a pegadinha do cabeçalho de autenticação que dá 401 em tokens Bearer, e um model singleton de configurações pra chave de API.</description><pubDate>Fri, 08 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>pexels</category><category>dev-log</category><category>blog-manager</category></item><item><title>Construindo o cross-posting pro Medium no blog-manager</title><link>https://imperfectsystems.com/pt/blog/building-medium-cross-posting/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/building-medium-cross-posting/</guid><description>Um botão de publicar no Medium sobre uma API descontinuada mas funcional: Net::HTTP injetável, renderização de markdown sob demanda, e uma máquina de estados dividida entre job e service.</description><pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>medium</category><category>dev-log</category><category>blog-manager</category></item><item><title>Atualizações ao vivo de jobs em background no Rails 8 com Turbo Streams</title><link>https://imperfectsystems.com/pt/blog/live-updates-background-jobs-turbo-streams/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/live-updates-background-jobs-turbo-streams/</guid><description>Conectando o Turbo Streams para que os jobs de scan atualizem a página enquanto rodam, e a pegadinha do adapter async no cable.yml que engolia todo broadcast vindo do worker.</description><pubDate>Tue, 05 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>turbo</category><category>hotwire</category><category>dev-log</category><category>blog-manager</category></item><item><title>Tornando os scans do blog assíncronos com Solid Queue (e uma pegadinha do Rails)</title><link>https://imperfectsystems.com/pt/blog/async-blog-scans-solid-queue/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/async-blog-scans-solid-queue/</guid><description>Movendo o scan do GitHub para um job em segundo plano depois que ele ultrapassou o timeout do proxy, e a pegadinha da ordem LIFO do rescue_from que quebrou meu caminho de descarte.</description><pubDate>Mon, 04 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>solid-queue</category><category>activejob</category><category>dev-log</category><category>blog-manager</category></item><item><title>Deploy automático do Rails 8 para staging com Kamal e um runner self-hosted do GitHub Actions</title><link>https://imperfectsystems.com/pt/blog/auto-deploy-staging-kamal-self-hosted-runner/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/auto-deploy-staging-kamal-self-hosted-runner/</guid><description>Fazendo todo merge disparar deploy automático para staging: um runner self-hosted, quatro paredes seguidas, e a pegadinha dos secrets do Kamal que demorou mais para ser decifrada.</description><pubDate>Sun, 03 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>kamal</category><category>github-actions</category><category>ci</category><category>dev-log</category><category>blog-manager</category></item><item><title>Um playbook de falhas de CI para um projeto Rails de uma pessoa só</title><link>https://imperfectsystems.com/pt/blog/ci-failure-playbook-for-a-one-person-rails-project/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/ci-failure-playbook-for-a-one-person-rails-project/</guid><description>Escrevendo as regras do que fazer quando o CI fica vermelho num projeto Rails solo, e a limitação do GitHub que transformou o gate de merge num comentário estrutural.</description><pubDate>Sat, 02 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>ci</category><category>rails</category><category>github-actions</category><category>dev-log</category><category>blog-manager</category></item><item><title>Construindo uma extensão de Firefox para sincronizar posts agendados do Medium</title><link>https://imperfectsystems.com/pt/blog/firefox-extension-medium-scheduled-posts/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/firefox-extension-medium-scheduled-posts/</guid><description>A requisição GraphQL que eu planejava interceptar nunca dispara: o Medium renderiza seu estado Apollo no servidor. Três becos sem saída e a correção com wrappedJSObject que foi para produção.</description><pubDate>Fri, 01 May 2026 00:00:00 GMT</pubDate><category>Development</category><category>firefox</category><category>webextensions</category><category>rails</category><category>dev-log</category><category>blog-manager</category></item><item><title>Rastreando posts agendados do Medium sem uma extensão de navegador</title><link>https://imperfectsystems.com/pt/blog/tracking-scheduled-medium-posts/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/tracking-scheduled-medium-posts/</guid><description>A API do Medium não tem o conceito de post agendado. Fase 1: modelar o estado manualmente com um enum append-only, e ver se a fricção justifica a automação.</description><pubDate>Thu, 30 Apr 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>medium</category><category>dev-log</category><category>blog-manager</category></item><item><title>Um painel para posts que eu ainda não publiquei</title><link>https://imperfectsystems.com/pt/blog/post-dashboard-rails-enums-filter-allowlist/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/post-dashboard-rails-enums-filter-allowlist/</guid><description>Construindo a lista de posts entre blogs no blog-manager. Enums do SQLite, formulários de filtro e um truque para manter os query params honestos.</description><pubDate>Tue, 28 Apr 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>dev-log</category><category>blog-manager</category></item><item><title>Scanning de posts pela API do GitHub: o que permissão mínima realmente significa</title><link>https://imperfectsystems.com/pt/blog/post-scanning-github-api-minimum-permission/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/post-scanning-github-api-minimum-permission/</guid><description>Construindo o motor de sincronização de posts do blog-manager. Net::HTTP, PATs de granularidade fina e uma investigação no __NEXT_DATA__ para verificar a resposta.</description><pubDate>Mon, 27 Apr 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>ruby</category><category>github-api</category><category>dev-log</category><category>blog-manager</category></item><item><title>Construindo o blog-manager: um model Blog com Active Record Encryption</title><link>https://imperfectsystems.com/pt/blog/building-blog-manager-part-1/</link><guid isPermaLink="true">https://imperfectsystems.com/pt/blog/building-blog-manager-part-1/</guid><description>Começando o blog-manager: um model Blog em Rails com Active Record Encryption para credenciais por blog, e uma UI de CRUD que eu realmente gostaria de usar.</description><pubDate>Sun, 26 Apr 2026 00:00:00 GMT</pubDate><category>Development</category><category>rails</category><category>blog-manager</category><category>dev-log</category><category>active-record-encryption</category></item></channel></rss>