<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ghpending | AkitaOnRails.com</title><link>https://akitaonrails.github.io/tags/ghpending/</link><description>Blog do Fabio Akita do Canal do YouTube 'Akitando' falando sobre tecnologia, carreira e coisas geek.</description><generator>Hugo -- gohugo.io</generator><language>pt-BR</language><lastBuildDate>Mon, 19 Oct 2026 23:20:48 +0000</lastBuildDate><atom:link href="https://akitaonrails.github.io/tags/ghpending/index.xml" rel="self" type="application/rss+xml"/><item><title>Burlando o bloqueio à API do GitHub no Brasil</title><link>https://akitaonrails.github.io/2026/06/11/burlando-bloqueio-api-github-brasil/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/06/11/burlando-bloqueio-api-github-brasil/</guid><pubDate>Thu, 11 Jun 2026 20:00:00 -0300</pubDate><description>&lt;p&gt;Hoje apareceu um problema daqueles que parecem piada, mas não são: &lt;code&gt;api.github.com&lt;/code&gt; começou a dar timeout no Brasil. O site &lt;code&gt;github.com&lt;/code&gt; abre. Clonar via SSH pode continuar funcionando. Mas as ferramentas que dependem da API do GitHub, como &lt;code&gt;gh&lt;/code&gt;, automações de CI, scripts pessoais, bots, CLIs, dashboards e tudo que consulta issues e pull requests, começam a travar.&lt;/p&gt;
&lt;p&gt;O &lt;a href="https://x.com/ayubio/status/2064878070394183955"target="_blank" rel="noopener"&gt;Ayub comentou no X&lt;/a&gt; que há todos os indícios típicos de bloqueio nacional determinado pela Anatel contra &lt;code&gt;api.github.com&lt;/code&gt;. No mesmo contexto, o tweet citado por ele mostrava &lt;code&gt;api.github.com&lt;/code&gt; resolvendo para &lt;code&gt;4.228.31.149&lt;/code&gt;, mas sem rota funcionando. O autor dizia ter testado por VIVO, Claro e Oracle, e que só funcionava via VPN de Miami. Ou seja: não parece &amp;ldquo;meu Wi-Fi caiu&amp;rdquo;. Parece bloqueio no caminho.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Hoje apareceu um problema daqueles que parecem piada, mas não são: <code>api.github.com</code> começou a dar timeout no Brasil. O site <code>github.com</code> abre. Clonar via SSH pode continuar funcionando. Mas as ferramentas que dependem da API do GitHub, como <code>gh</code>, automações de CI, scripts pessoais, bots, CLIs, dashboards e tudo que consulta issues e pull requests, começam a travar.</p>
<p>O <a href="https://x.com/ayubio/status/2064878070394183955"target="_blank" rel="noopener">Ayub comentou no X</a> que há todos os indícios típicos de bloqueio nacional determinado pela Anatel contra <code>api.github.com</code>. No mesmo contexto, o tweet citado por ele mostrava <code>api.github.com</code> resolvendo para <code>4.228.31.149</code>, mas sem rota funcionando. O autor dizia ter testado por VIVO, Claro e Oracle, e que só funcionava via VPN de Miami. Ou seja: não parece &ldquo;meu Wi-Fi caiu&rdquo;. Parece bloqueio no caminho.</p>
<p>Segundo o Ayub, esse tipo de coisa costuma acontecer em ondas de bloqueios, muitas vezes em reuniões de quarta-feira com grandes operadoras, dentro desse mecanismo brasileiro de bloquear endereços sob pretexto de combater pirataria. O problema é o efeito colateral: em vez de derrubar só o alvo, derruba pedaço legítimo de infraestrutura. Hoje foi a API do GitHub. Amanhã pode ser qualquer outra coisa que seu trabalho depende.</p>
<p>E sim, eu confirmei daqui.</p>
<h2>Como saber se você foi afetado<span class="hx:absolute hx:-mt-20" id="como-saber-se-você-foi-afetado"></span>
    <a href="#como-saber-se-voc%c3%aa-foi-afetado" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Primeiro, teste se o site principal abre:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -4 -I --connect-timeout <span class="m">8</span> --max-time <span class="m">12</span> https://github.com/</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Aqui funcionou. Depois teste a API:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -4 -I --connect-timeout <span class="m">8</span> --max-time <span class="m">12</span> https://api.github.com/</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Aqui deu:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">curl: (28) Connection timed out after 8002 milliseconds</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Agora veja pra qual IP seu sistema está resolvendo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">getent ahostsv4 api.github.com</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>No meu caso:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">4.228.31.149    STREAM api.github.com
</span></span><span class="line"><span class="cl">4.228.31.149    DGRAM
</span></span><span class="line"><span class="cl">4.228.31.149    RAW</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E o <code>gh</code> também depende dessa API. Então comandos como estes podem travar:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">gh api rate_limit
</span></span><span class="line"><span class="cl">gh pr list
</span></span><span class="line"><span class="cl">gh issue list</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se você é desenvolvedor e de repente <code>gh</code> parou, seus scripts de release pararam, seu bot que lista PRs parou, ou aquele CLI que consulta issues começou a ficar pendurado, pode ser isso. Não é bug seu. É a sua rota até <code>api.github.com</code> sendo jogada no buraco.</p>
<h2>Primeiro tente DNS 9.9.9.9<span class="hx:absolute hx:-mt-20" id="primeiro-tente-dns-9999"></span>
    <a href="#primeiro-tente-dns-9999" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Algumas pessoas comentaram que trocar o DNS para <a href="https://www.quad9.net/"target="_blank" rel="noopener">Quad9</a>, <code>9.9.9.9</code>, poderia contornar. Faz sentido testar, porque alguns bloqueios são feitos via DNS: o provedor responde um IP errado, NXDOMAIN, ou manda para um buraco. Se o problema for só o DNS do seu provedor, trocar de DNS resolve.</p>
<p>Teste sem mudar nada no sistema:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dig @9.9.9.9 +short api.github.com A</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>No meu caso, não resolveu. O Quad9 também retornou:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">4.228.31.149</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E forçar esse IP no <code>curl</code> continuou dando timeout:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -4 -I --connect-timeout <span class="m">8</span> --max-time <span class="m">12</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  --resolve api.github.com:443:4.228.31.149 <span class="se">\
</span></span></span><span class="line"><span class="cl">  https://api.github.com/</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Resultado:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">curl: (28) Connection timed out after 8002 milliseconds</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Então, no meu link, 9.9.9.9 não resolveu. Mas teste no seu. Se o seu provedor está apenas envenenando DNS, pode funcionar.</p>
<p>No Arch com NetworkManager, seria algo assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S bind-tools curl
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">nmcli con show --active
</span></span><span class="line"><span class="cl">sudo nmcli con mod <span class="s2">&#34;NOME DA SUA CONEXÃO&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  ipv4.ignore-auto-dns yes <span class="se">\
</span></span></span><span class="line"><span class="cl">  ipv4.dns <span class="s2">&#34;9.9.9.9 149.112.112.112&#34;</span>
</span></span><span class="line"><span class="cl">sudo nmcli con down <span class="s2">&#34;NOME DA SUA CONEXÃO&#34;</span>
</span></span><span class="line"><span class="cl">sudo nmcli con up <span class="s2">&#34;NOME DA SUA CONEXÃO&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>No Ubuntu, a ideia é a mesma. Instale as ferramentas e ajuste pelo NetworkManager:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt install dnsutils curl
</span></span><span class="line"><span class="cl">nmcli con show --active</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Ou use a tela de rede do GNOME/KDE e coloque DNS manual <code>9.9.9.9</code> e <code>149.112.112.112</code> na conexão. Depois desconecte e conecte de novo.</p>
<p>Teste de novo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dig +short api.github.com A
</span></span><span class="line"><span class="cl">curl -4 -I --connect-timeout <span class="m">8</span> --max-time <span class="m">12</span> https://api.github.com/</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se funcionar, ótimo. Você terminou aqui.</p>
<p>Se continuar dando timeout, o bloqueio não está só no DNS. Aí precisa rotear a conexão por outro caminho.</p>
<h2>Por que eu não gosto da gambiarra de IP fixo<span class="hx:absolute hx:-mt-20" id="por-que-eu-não-gosto-da-gambiarra-de-ip-fixo"></span>
    <a href="#por-que-eu-n%c3%a3o-gosto-da-gambiarra-de-ip-fixo" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Outra sugestão que vi foi colocar IPs manualmente no DNS local, tipo Pi-hole, Unbound, <code>/etc/hosts</code>, dnsmasq, essas coisas. Exemplo: &ldquo;resolve <code>api.github.com</code> pra tal IP que funciona&rdquo;.</p>
<p>Isso pode funcionar por algumas horas. Eu não gosto.</p>
<p>GitHub é infraestrutura grande. IP muda. Rota muda. Balanceamento muda. Região muda. O IP que funciona pra uma pessoa em Miami pode ser ruim pra você em São Paulo. O IP que funciona hoje pode cair amanhã. E se o bloqueio for por rota blackhole no provedor, trocar DNS para outro IP pode só trocar um buraco por outro.</p>
<p>Pi-hole é ótimo pra rede doméstica. Unbound é ótimo. <code>/etc/hosts</code> salva em emergência. Mas fixar IP de serviço grande como GitHub é pedir pra esquecer uma gambiarra invisível e perder duas horas daqui a um mês tentando entender por que só a sua máquina não funciona.</p>
<p>Use DNS alternativo como teste. Use IP fixo só como curativo temporário e documente onde mexeu.</p>
<h2>Fallback: proxy SOCKS só para ferramentas do GitHub<span class="hx:absolute hx:-mt-20" id="fallback-proxy-socks-só-para-ferramentas-do-github"></span>
    <a href="#fallback-proxy-socks-s%c3%b3-para-ferramentas-do-github" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Minha solução foi fazer o mínimo invasivo: um wrapper que sobe um SOCKS local via Tor e executa só o comando que eu quero por ele. Não roteia o sistema inteiro. Não mexe no navegador. Não altera pacote, Steam, banco, nada. Só <code>gh</code>, ou qualquer ferramenta que eu chamar explicitamente.</p>
<p>No meu caso, o wrapper está em <code>~/.config/zsh/bin/github-proxy</code> e o alias em <code>~/.config/zsh/aliases</code> faz:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">alias</span> <span class="nv">gh</span><span class="o">=</span><span class="s1">&#39;$HOME/.config/zsh/bin/github-proxy gh&#39;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O wrapper é este:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">proxy_host</span><span class="o">=</span><span class="s2">&#34;127.0.0.1&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">proxy_port</span><span class="o">=</span><span class="s2">&#34;9050&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">tor_dir</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">XDG_RUNTIME_DIR</span><span class="k">:-</span><span class="p">/tmp</span><span class="si">}</span><span class="s2">/github-proxy-tor&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">tor_rc</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$tor_dir</span><span class="s2">/torrc&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">tor_log</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$tor_dir</span><span class="s2">/tor.log&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> <span class="nv">$#</span> -eq <span class="m">0</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;usage: github-proxy &lt;command&gt; [args...]&#34;</span> &gt;<span class="p">&amp;</span><span class="m">2</span>
</span></span><span class="line"><span class="cl">  <span class="nb">exit</span> <span class="m">2</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> ! ss -ltn <span class="s2">&#34;sport = :</span><span class="nv">$proxy_port</span><span class="s2">&#34;</span> <span class="p">|</span> grep -q <span class="s2">&#34;</span><span class="nv">$proxy_host</span><span class="s2">:</span><span class="nv">$proxy_port</span><span class="s2">&#34;</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  mkdir -p <span class="s2">&#34;</span><span class="nv">$tor_dir</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  : &gt;<span class="s2">&#34;</span><span class="nv">$tor_rc</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  tor -f <span class="s2">&#34;</span><span class="nv">$tor_rc</span><span class="s2">&#34;</span> --SocksPort <span class="s2">&#34;</span><span class="nv">$proxy_host</span><span class="s2">:</span><span class="nv">$proxy_port</span><span class="s2">&#34;</span> --DataDirectory <span class="s2">&#34;</span><span class="nv">$tor_dir</span><span class="s2">/data&#34;</span> &gt;<span class="s2">&#34;</span><span class="nv">$tor_log</span><span class="s2">&#34;</span> 2&gt;<span class="p">&amp;</span><span class="m">1</span> <span class="p">&amp;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">for</span> _ in <span class="o">{</span>1..60<span class="o">}</span><span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> grep -q <span class="s1">&#39;Bootstrapped 100%&#39;</span> <span class="s2">&#34;</span><span class="nv">$tor_log</span><span class="s2">&#34;</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">      <span class="nb">break</span>
</span></span><span class="line"><span class="cl">    <span class="k">fi</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> ! <span class="nb">kill</span> -0 <span class="s2">&#34;</span><span class="nv">$!</span><span class="s2">&#34;</span> 2&gt;/dev/null<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">      <span class="nb">echo</span> <span class="s2">&#34;github-proxy: tor exited before bootstrap; see </span><span class="nv">$tor_log</span><span class="s2">&#34;</span> &gt;<span class="p">&amp;</span><span class="m">2</span>
</span></span><span class="line"><span class="cl">      <span class="nb">exit</span> <span class="m">1</span>
</span></span><span class="line"><span class="cl">    <span class="k">fi</span>
</span></span><span class="line"><span class="cl">    sleep <span class="m">1</span>
</span></span><span class="line"><span class="cl">  <span class="k">done</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">if</span> ! grep -q <span class="s1">&#39;Bootstrapped 100%&#39;</span> <span class="s2">&#34;</span><span class="nv">$tor_log</span><span class="s2">&#34;</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;github-proxy: timed out waiting for tor bootstrap; see </span><span class="nv">$tor_log</span><span class="s2">&#34;</span> &gt;<span class="p">&amp;</span><span class="m">2</span>
</span></span><span class="line"><span class="cl">    <span class="nb">exit</span> <span class="m">1</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">HTTPS_PROXY</span><span class="o">=</span><span class="s2">&#34;socks5h://</span><span class="nv">$proxy_host</span><span class="s2">:</span><span class="nv">$proxy_port</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">HTTP_PROXY</span><span class="o">=</span><span class="s2">&#34;socks5h://</span><span class="nv">$proxy_host</span><span class="s2">:</span><span class="nv">$proxy_port</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">ALL_PROXY</span><span class="o">=</span><span class="s2">&#34;socks5h://</span><span class="nv">$proxy_host</span><span class="s2">:</span><span class="nv">$proxy_port</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">exec</span> <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Repare no <code>socks5h</code>. Esse <code>h</code> importa. Ele faz a resolução DNS pelo proxy, não pela sua rede local. Se você usa <code>socks5://</code> normal, dependendo da biblioteca, o DNS ainda pode acontecer localmente antes de passar pelo proxy. Com <code>socks5h://</code>, a ideia é: &ldquo;leva o hostname até o outro lado e resolve lá&rdquo;.</p>
<h2>Instalando no Arch<span class="hx:absolute hx:-mt-20" id="instalando-no-arch"></span>
    <a href="#instalando-no-arch" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>No Arch:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S tor github-cli iproute2
</span></span><span class="line"><span class="cl">mkdir -p ~/.local/bin</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Crie o script:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">nano ~/.local/bin/github-proxy</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Cole o wrapper acima e dê permissão:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">chmod +x ~/.local/bin/github-proxy</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Teste direto:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">~/.local/bin/github-proxy gh api rate_limit --jq .resources.core.limit</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Conta autenticada normalmente retorna:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">5000</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Foi o que aconteceu aqui. Direto dava timeout. Pelo wrapper, <code>gh api rate_limit --jq .resources.core.limit</code> retornou <code>5000</code>.</p>
<p>Agora adicione um alias no seu shell.</p>
<p>ZSH:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;alias gh=&#39;</span><span class="nv">$HOME</span><span class="s2">/.local/bin/github-proxy gh&#39;&#34;</span> &gt;&gt; ~/.zshrc
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.zshrc</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Bash:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;alias gh=&#39;</span><span class="nv">$HOME</span><span class="s2">/.local/bin/github-proxy gh&#39;&#34;</span> &gt;&gt; ~/.bashrc
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.bashrc</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Teste:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">gh api rate_limit --jq .resources.core.limit
</span></span><span class="line"><span class="cl">gh pr list</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h2>Ubuntu<span class="hx:absolute hx:-mt-20" id="ubuntu"></span>
    <a href="#ubuntu" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>No Ubuntu, o pacote do Tor é fácil:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt update
</span></span><span class="line"><span class="cl">sudo apt install tor iproute2 curl</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Para o GitHub CLI, se o pacote <code>gh</code> estiver disponível na sua versão:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt install gh</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se não estiver, siga a instalação oficial do GitHub CLI para Ubuntu/Debian. O resto é igual: crie <code>~/.local/bin/github-proxy</code>, dê <code>chmod +x</code>, e coloque o alias no <code>.bashrc</code> ou <code>.zshrc</code>.</p>
<h2>Alternativas melhores que Tor<span class="hx:absolute hx:-mt-20" id="alternativas-melhores-que-tor"></span>
    <a href="#alternativas-melhores-que-tor" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Tor funcionou e é conveniente, mas não é a única opção. Às vezes é lento. Às vezes algum serviço encrenca com saída Tor. Para <code>gh api</code> e listar PR, tudo bem. Para uso pesado, talvez você queira algo mais previsível.</p>
<p>Opções razoáveis:</p>
<ul>
<li>VPN normal: Proton, Mullvad, IVPN, WireGuard próprio. Roteia tudo ou usa split tunneling se você souber configurar.</li>
<li>Tailscale com exit node fora do Brasil: limpo, se você tiver uma máquina confiável fora ou uma VPS.</li>
<li>SSH SOCKS para uma VPS: <code>ssh -N -D 127.0.0.1:9050 usuario@seu-vps</code>. Depois use o mesmo <code>HTTPS_PROXY=socks5h://127.0.0.1:9050</code>.</li>
<li>Proxy corporativo: se sua empresa tem saída fora do Brasil, configure só as ferramentas que precisam.</li>
</ul>
<p>O cuidado aqui é não sair mexendo em tudo ao mesmo tempo. Primeiro prove que <code>api.github.com</code> direto falha. Depois prove que via outro caminho funciona. Só então automatize.</p>
<h2>Ajustando ferramentas próprias: ghpending<span class="hx:absolute hx:-mt-20" id="ajustando-ferramentas-próprias-ghpending"></span>
    <a href="#ajustando-ferramentas-pr%c3%b3prias-ghpending" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Esse bloqueio me pegou também num utilitário meu: <a href="https://github.com/akitaonrails/ghpending"target="_blank" rel="noopener">ghpending</a>. Eu já falei dele no post <a href="/2026/05/23/criei-cli-pra-checar-pendencias-github-ghpending/">&ldquo;Criei um CLI pra Checar Pendências no Meu GitHub: ghpending&rdquo;</a>. Ele lista issues e pull requests abertos nos meus repositórios, pra eu saber onde tem gente esperando resposta.</p>
<p>O problema é óbvio: ele usa a API do GitHub. Se <code>api.github.com</code> cai no buraco, ele cai junto.</p>
<p>Então adicionei fallback de proxy. O <code>ghpending</code> agora lê <code>GITHUB_TOKEN</code> como antes, mas também tenta usar proxy SOCKS nesta ordem:</p>
<ol>
<li><code>GHPENDING_GITHUB_PROXY</code>, se você quiser forçar um proxy específico.</li>
<li><code>HTTPS_PROXY</code>, <code>https_proxy</code>, <code>ALL_PROXY</code> ou <code>all_proxy</code>, se forem <code>socks5://</code> ou <code>socks5h://</code>.</li>
<li>Um SOCKS local em <code>127.0.0.1:9050</code>, se estiver escutando.</li>
<li>Se nada disso existir, tenta direto.</li>
</ol>
<p>No README ficou assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">GITHUB_TOKEN</span><span class="o">=</span><span class="k">$(</span>gh auth token<span class="k">)</span> ghpending</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E, para proxy:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">GHPENDING_GITHUB_PROXY</span><span class="o">=</span>socks5h://127.0.0.1:9050 ghpending</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Ou simplesmente rode pelo wrapper:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">~/.local/bin/github-proxy ghpending</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Meu wrapper sobe Tor em <code>127.0.0.1:9050</code>; o <code>ghpending</code> detecta esse proxy e usa para chamadas à API. Se você não está bloqueado, ele continua funcionando direto. Se você está bloqueado, ele tem um caminho de fuga.</p>
<p>Isso é o tipo de fallback que agora todo dev brasileiro deveria considerar para ferramenta que depende de API estrangeira. Não porque é bonito. Porque a internet brasileira está ficando imprevisível.</p>
<h2>O problema político<span class="hx:absolute hx:-mt-20" id="o-problema-político"></span>
    <a href="#o-problema-pol%c3%adtico" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>No fim da thread, o <a href="https://x.com/ayubio/status/2064880160893968643"target="_blank" rel="noopener">Ayub lembrou</a> que, por causa desses bloqueios colaterais sigilosos, já haveria cerca de 250 milhões de endereços bloqueados na internet brasileira. Ele também linkou uma apresentação sobre o panorama dos bloqueios no Brasil. Em outro tweet do mesmo fio, ele diz que autoridades defendem sigilo como única alternativa para combater crimes.</p>
<p>Eu não compro essa desculpa.</p>
<p>Bloqueio sigiloso de infraestrutura crítica, sem transparência, sem contraditório público, sem lista auditável, sem explicação de escopo, é censura operacional. Na minha leitura, é ilegal justamente por fugir do rito público e auditável que deveria existir quando o Estado manda quebrar acesso à internet. Pode ter começado com pirataria de TV box. Pode ter discurso bonito. Mas o mecanismo está aí: alguém aperta botão, operadoras aplicam bloqueio, usuários legítimos descobrem só quando ferramenta de trabalho para.</p>
<p>Hoje, o efeito colateral bateu em desenvolvedor honesto tentando trabalhar com GitHub. Amanhã bate em pacote de Linux, registry de container, CDN, API de pagamento, serviço de autenticação. Aí todo mundo corre pra VPN, Tor, proxy, DNS alternativo, <code>/etc/hosts</code>, Pi-hole. Parabéns: estamos recriando, aos poucos, o manual de sobrevivência de uma internet censurada.</p>
<p>Não precisa exagerar na metáfora. Ainda não somos a China. Mas o cheiro é o mesmo: bloqueio centralizado, opaco, com dano colateral, e usuário comum tendo que aprender bypass pra trabalhar.</p>
<p>Se você foi afetado, documente. Rode os comandos. Salve outputs. Abra issue no seu provedor. Reclame com dados. Compartilhe workaround, mas não normalize. Bypass é curativo. O problema real é um Estado que se dá o poder de quebrar pedaços da internet em silêncio.</p>
<p>E se você só queria rodar <code>gh pr list</code> pra revisar um pull request: bem-vindo à infraestrutura brasileira de 2026.</p>
]]></content:encoded><category>ghpending</category><category>redes</category><category>seguranca</category><category>linux</category></item><item><title>Dicas e Toolkit de IA do Akita: ai-jail, ai-memory, ai-usagebar</title><link>https://akitaonrails.github.io/2026/05/24/dicas-e-toolkit-de-ia-do-akita-ai-jail-ai-memory-ai-usagebar/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/05/24/dicas-e-toolkit-de-ia-do-akita-ai-jail-ai-memory-ai-usagebar/</guid><pubDate>Sun, 24 May 2026 10:30:00 -0300</pubDate><description>&lt;p&gt;No post da semana passada, &lt;a href="https://akitaonrails.github.io/2026/05/14/terminando-maratona-ia-sucesso-ou-fracasso/"&gt;&amp;ldquo;Terminando a Maratona de IA: Sucesso ou Fracasso?&amp;rdquo;&lt;/a&gt;, eu encerrei a primeira fase da minha maratona. Mais de 600 horas de uso intenso de agentes de código, dezenas de projetos, centenas de milhares de linhas de código e documentação, e uma pilha de conclusões práticas. Não de marketing. Práticas.&lt;/p&gt;
&lt;p&gt;Vou repetir uma coisa importante antes que alguém saia clonando todos os meus repositórios achando que virou produto 1.0: a maior parte dos projetos &lt;code&gt;frank-*&lt;/code&gt; no meu GitHub são provas de conceito. São experimentos. Alguns funcionam bem pra mim, no meu ambiente, no meu fluxo. Isso não quer dizer que estão prontos pra virar dependência crítica da sua empresa amanhã de manhã. Quer brincar, contribuir, estudar, ótimo. Só não confunda &amp;ldquo;publiquei no GitHub&amp;rdquo; com &amp;ldquo;está production ready&amp;rdquo;.&lt;/p&gt;</description><content:encoded><![CDATA[<p>No post da semana passada, <a href="/2026/05/14/terminando-maratona-ia-sucesso-ou-fracasso/">&ldquo;Terminando a Maratona de IA: Sucesso ou Fracasso?&rdquo;</a>, eu encerrei a primeira fase da minha maratona. Mais de 600 horas de uso intenso de agentes de código, dezenas de projetos, centenas de milhares de linhas de código e documentação, e uma pilha de conclusões práticas. Não de marketing. Práticas.</p>
<p>Vou repetir uma coisa importante antes que alguém saia clonando todos os meus repositórios achando que virou produto 1.0: a maior parte dos projetos <code>frank-*</code> no meu GitHub são provas de conceito. São experimentos. Alguns funcionam bem pra mim, no meu ambiente, no meu fluxo. Isso não quer dizer que estão prontos pra virar dependência crítica da sua empresa amanhã de manhã. Quer brincar, contribuir, estudar, ótimo. Só não confunda &ldquo;publiquei no GitHub&rdquo; com &ldquo;está production ready&rdquo;.</p>
<p>Existem exceções. O <a href="https://github.com/akitaonrails/frankmd"target="_blank" rel="noopener">FrankMD</a>, por exemplo, recebeu uma quantidade decente de contribuições, testes, lapidação, correções de bugs reais, uso real. Hoje ele já é bem mais estável do que era no primeiro post. Ainda assim, o ponto continua: esses projetos nasceram como laboratório de vibe coding, não como plano de produto de 3 anos com roadmap, suporte enterprise e SLA.</p>
<p>Este post é um apanhado do que aprendi nesse laboratório. Algumas ferramentas minhas, alguns hábitos, algumas recomendações. Nada místico. Nenhuma &ldquo;nova forma revolucionária de programar&rdquo;. É engenharia velha com ferramenta nova.</p>
<h2>Primeiro: pare de colecionar agente<span class="hx:absolute hx:-mt-20" id="primeiro-pare-de-colecionar-agente"></span>
    <a href="#primeiro-pare-de-colecionar-agente" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se você é desenvolvedor normal, você não precisa de 12 agentes, 40 wrappers, 7 orquestradores e um diagrama de Kubernetes pra escolher quem vai escrever um <code>if</code>.</p>
<p>Na prática, foque em <strong>Claude Code</strong>, <strong>Codex</strong> ou <strong>opencode</strong>. Só isso.</p>
<p>Sim, existe Gemini CLI. Sim, existe Cursor. Sim, existe Windsurf, Crush, OpenClaw, Pi, Aider, e amanhã vai aparecer mais meia dúzia. Eu testei um monte. Leia meus posts de benchmark de LLMs, especialmente o <a href="/2026/04/24/llm-benchmarks-parte-3-deepseek-kimi-mimo/">&ldquo;LLM Benchmarks Parte 3: DeepSeek, Kimi, MiMo&rdquo;</a>. A conclusão é chata e óbvia: hoje, as melhores opções de custo-benefício pra programação pesada são <strong>Opus 4.7</strong> e <strong>GPT 5.5</strong> nos planos Pro/Plus/Max subsidiados. Nada chega perto quando o assunto é trabalhar várias horas por dia com agente de código de verdade.</p>
<p>Pagar token direto é caro. Pagar plano mensal subsidiado sai muito mais barato. É por isso que eu vivo alternando entre Claude Code e Codex: não porque eu quero &ldquo;multi-agent architecture&rdquo;, mas porque os planos têm limites e eu trabalho muitas horas seguidas.</p>
<p>DeepSeek v4 e Kimi 2.6 são mais baratos? Sim. São usáveis? Sim. Eu gosto deles pra vários casos. Mas pra <strong>Agile Vibe Coding</strong> do jeito que venho defendendo desde o post <a href="/2026/02/20/do-zero-a-pos-producao-em-1-semana-como-usar-ia-em-projetos-de-verdade-bastidores-do-the-m-akita-chronicles/">&ldquo;Do Zero à Pós-Produção em 1 Semana&rdquo;</a>, ainda falta. Eles tropeçam mais em continuidade, em refatoração longa, em testes, em entender o projeto inteiro. Dá pra usar? Dá. Mas se o objetivo é produtividade consistente, Opus e GPT ainda são a régua.</p>
<p>Rodar modelo open source local é legal. Eu mesmo brinquei bastante com isso no review do <a href="/2026/03/31/review-minisforum-ms-s1-max-amd-ai-max-395/">Minisforum MS-S1 Max com AMD AI Max+ 395</a>. Pra one-shot, pra estudar, pra brincar com inferência local, é divertido. Pra Agile Vibe Coding o dia inteiro, todo dia, ainda não é prático. Latência, contexto, qualidade, manutenção do setup, VRAM, tudo cobra imposto.</p>
<p>Também não é prático ficar rodando múltiplos LLMs em paralelo, tipo &ldquo;planner + executor + reviewer + juiz&rdquo;. Eu testei isso no post <a href="/2026/04/25/llm-benchmarks-vale-a-pena-misturar-2-modelos/">&ldquo;LLM Benchmarks: Vale a Pena Misturar 2 Modelos?&rdquo;</a>. A ideia é bonita no papel. Na prática, aumenta custo, aumenta latência, aumenta superfície de erro, e o ganho não paga a complexidade.</p>
<p>O segredo não é ter um monte de agentes. Esquece OpenClaw ou Pi pra programação do dia a dia. O segredo é processo de engenharia. XP. Testes. <a href="/2026/04/20/clean-code-para-agentes-de-ia/">Clean Code pra agentes de IA</a>. CI. Pair programming. Refatoração constante. Código pequeno. Deploy automatizado. Feedback rápido.</p>
<p>Ferramenta ajuda. Engenharia ganha.</p>
<h2>ai-jail: autonomia com cerca<span class="hx:absolute hx:-mt-20" id="ai-jail-autonomia-com-cerca"></span>
    <a href="#ai-jail-autonomia-com-cerca" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O primeiro projeto que quero destacar é o <a href="https://github.com/akitaonrails/ai-jail"target="_blank" rel="noopener">ai-jail</a>. Ele é um wrapper de sandbox pra rodar agentes de IA com acesso restrito ao sistema. No Linux usa <code>bubblewrap</code> (<code>bwrap</code>) e Landlock. No macOS usa <code>sandbox-exec</code>. A ideia é simples: o agente enxerga o ambiente que precisa pra trabalhar, mas não sai fuçando seu sistema inteiro.</p>
<p>Uso todo dia? Sim. Uso sempre? Não.</p>
<p>Quando sei que não vou fazer nada arriscado, abro <code>claude</code> ou <code>codex</code> direto. Se vou mexer num projeto simples, só rodar testes, editar markdown, refatorar coisa local, muitas vezes nem me preocupo. Em mais de 600 horas de Agile Vibe Coding intenso, mais de meio milhão de linhas de código e documentação, nunca tive um caso desses folclóricos de LLM destruindo meu sistema host de um jeito irrecuperável.</p>
<p>E olha que eu usei agentes explicitamente pra configurar meu Omarchy. ZSH, Hyprland, Waybar, configs de terminal, scripts de login, tudo. Nunca fizeram nada que eu não pedi.</p>
<p>Essas histórias de &ldquo;o agente deletou meu home inteiro sozinho&rdquo; eu leio com um pé atrás. Na minha experiência, quando você pede pra deletar algo perigoso, Claude e Codex perguntam confirmação. Você precisa dizer sim. Se você disse sim sem ler, a culpa não é mágica negra do LLM. É usuário no modo zumbi.</p>
<p>Dito isso: nada é garantido. Daí o ai-jail.</p>
<p>Meu uso preferido é combinar <code>ai-jail</code> com o modo sem freio do harness:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ai-jail claude --dangerously-allow-permissions
</span></span><span class="line"><span class="cl">ai-jail codex --dangerously-bypass-approvals-and-sandbox</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Parece contraditório, mas faz sentido. Eu tiro a fricção de confirmação dentro do agente, mas coloco uma cerca no nível do sistema operacional. O agente pode trabalhar rápido dentro do projeto, mas o filesystem do host fica essencialmente read-only. O diretório atual fica read-write. O que eu mapear explicitamente com <code>--rw-map</code> também fica read-write. O resto não é pra tocar.</p>
<p>O README do ai-jail resume bem: é um sandbox wrapper pra agentes como Claude Code, GPT Codex, OpenCode e Crush. No primeiro run ele cria um <code>.ai-jail</code> no projeto, que pode ser commitado. Suporta <code>--dry-run</code> pra ver os mounts antes de executar, <code>--lockdown</code> pra modo mais restritivo, <code>--private-home</code> pra esconder dotfiles reais, <code>--mask .env</code> pra esconder arquivos sensíveis dentro do próprio projeto, e perfis de navegador isolado pra Chromium/Firefox.</p>
<p>O ponto importante: não venda isso como segurança absoluta. Processo sandbox não é VM. Kernel bug existe. Side channel existe. macOS tem limitações. O próprio README é claro: se você precisa isolar workload hostil de verdade, use uma VM descartável. Eu não uso ai-jail como &ldquo;blindagem militar&rdquo;. Uso como mais uma camada, boa o suficiente pro fluxo de desenvolvimento.</p>
<p>E mesmo dentro do projeto, tudo é Git. Eu faço push frequente pro GitHub ou pro meu Gitea privado. Então o pior caso realista é o agente destruir o diretório do projeto. Chato? Sim. Catastrófico? Não. Clono de novo. Volto do remote. Refaço o que estava local. Se o <code>.git</code> corromper, apago tudo e clono de novo.</p>
<p>Secrets também têm cópia fora. <code>.env</code>, tokens, keys, tudo que importa fica no Bitwarden. <a href="/2025/09/10/omarchy-2-0-bitwarden-self-hosted-vaultwarden/">Self-hosted em Vaultwarden</a>, claro. Então se eu perder o diretório local, não perdi a chave do reino.</p>
<p>O risco mais comum não é o agente deletar tudo. É você vazar segredo no Git. Isso aconteceu comigo mais de uma vez. Você dá <code>git add .</code>, esquece um <code>.env</code>, empurra pro remote, parabéns. Acontece. Por isso tem que olhar <code>git status</code>, <code>git diff --cached</code>, e pensar antes de dar push.</p>
<p>Mesmo quando acontece, os LLMs são muito competentes pra ajudar a reescrever histórico. Peço pra limpar o segredo do Git, forçar push, revisar se sumiu, e depois eu rotaciono a key. Não é bonito, mas é administrável.</p>
<p>Então sim, recomendo usar Claude/Codex com permissões perigosas <strong>dentro</strong> do ai-jail. Existe a chance de 0,001% de acidente irrecuperável? Existe. Mas se você é bom engenheiro, isso não deveria te matar. Eu tenho camadas: snapshots automáticos em Btrfs, restic pro NAS, NAS arquivando offsite em AWS Glacier, Git remoto, Bitwarden. Ferramenta nenhuma substitui backup.</p>
<h2>ai-memory: contexto que sobrevive ao harness<span class="hx:absolute hx:-mt-20" id="ai-memory-contexto-que-sobrevive-ao-harness"></span>
    <a href="#ai-memory-contexto-que-sobrevive-ao-harness" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O segundo é o <a href="https://github.com/akitaonrails/ai-memory"target="_blank" rel="noopener">ai-memory</a>, que expliquei em detalhes no post <a href="/2026/05/23/criei-sistema-memoria-agentes-codigo-ai-memory/">&ldquo;Criei um Sistema de Memória pra Agentes de Código: ai-memory&rdquo;</a>.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/23/ai-memory/ai-memory-logo.png" alt="Logo do projeto ai-memory: pictograma circular com um chip estilizado abrindo “asas” tipo bibliotecas/páginas pra cada lado, ao lado do texto ai-memory em itálico."  loading="lazy" /></p>
<p>A motivação é simples: harnesses perdem contexto. Claude Code compacta. Codex compacta. opencode compacta. Sessão acaba. Você abre outro agente e ele não sabe o que aconteceu nas últimas 4 horas. Se você usa só um harness, talvez isso não incomode tanto. Se você alterna entre Claude e Codex como eu, incomoda rápido.</p>
<p>Eu queria um consolidador de memória de longo prazo que funcionasse atravessando harnesses diferentes. Algo que permitisse handoff entre Claude, Codex e opencode sem eu ficar escrevendo <code>HANDOFF.md</code> manual toda vez. Algo que capturasse prompts, tool calls e eventos de sessão via hooks, consolidasse em páginas markdown, indexasse com SQLite/FTS5, e expusesse tudo via MCP quando o agente precisasse consultar.</p>
<p>Outro motivador foi o que expliquei no post <a href="/2026/04/06/rag-esta-morto-contexto-longo/">&ldquo;RAG Está Morto? Contexto Longo, Grep e o Fim do Vector DB Obrigatório&rdquo;</a>. Pra projeto de código, quase sempre texto simples resolve mais do que arquitetura afetada de vector DB. Markdown, <code>grep</code>, SQLite FTS5, contexto longo e bons arquivos em <code>docs/</code> já levam você longe. O ai-memory segue essa linha: compila memória em texto, deixa no disco, indexa simples, e só chama LLM quando vale consolidar.</p>
<p>O ai-memory não foi feito pra ser uma knowledge base navegável por usuário final. Ele tem uma UI web read-only, sim, mas isso é pra auditoria e inspeção. A memória é otimizada pra LLM consumir. É um wiki interno que o harness pode consultar quando acha que precisa. É um lugar onde posso pedir explicitamente &ldquo;salva isso pra próxima sessão&rdquo; e esperar que sobreviva mais do que a compactação padrão do Claude ou do Codex.</p>
<p><img src="https://raw.githubusercontent.com/akitaonrails/ai-memory/main/docs/web-projects-home.png" alt="Homepage da UI web do ai-memory mostrando projetos detectados, contagem de páginas, última atividade e o aviso de que a memória é otimizada pra consumo por LLM, não documentação curada por humanos."  loading="lazy" /></p>
<p>O README resume bem: agentes de código perdem todo contexto quando a sessão termina; o ai-memory dá a eles um wiki persistente compartilhado. Cada prompt, tool call e decisão pode ser capturado automaticamente. No fim da sessão, páginas relevantes são reescritas como narrativa coerente. Na próxima sessão, outro agente pode receber um handoff já prepended no contexto.</p>
<p>Isso é útil quando você fecha Claude às 18h, abre Codex no dia seguinte no mesmo diretório, e quer que ele saiba que você estava testando session cookies porque rotação de JWT tinha dado problema. Ou quando você volta a um projeto seis semanas depois e não lembra por que descartou Redis.</p>
<p>Mas não confunda com documentação canônica. Se você fez uma pesquisa importante que não quer perder, peça pro agente escrever um markdown em <code>docs/</code> dentro do projeto. Decisão arquitetural, benchmark, análise de biblioteca, runbook de deploy, tudo que precisa sobreviver com garantia deve virar arquivo explícito no repo. Isso é mais simples, auditável e versionado.</p>
<p>O ai-memory cobre a faixa intermediária: informação transitória que talvez importe depois. Um bug estranho que apareceu. Um raciocínio que levou a uma decisão. Um gotcha de ambiente. Um resumo de sessão. Coisas que você não quer transformar em doc oficial ainda, mas também não quer jogar fora.</p>
<p>Ele ainda é beta. Eu uso em produção pessoal, mas precisa de muito mais gente batendo nele. Tem integração com Claude Code, Codex e opencode mais polida. Gemini CLI, OpenClaw e clientes MCP exóticos ainda precisam de mais teste. PRs são bem-vindos. Bug report também. &ldquo;Instalei e quebrou no meu setup&rdquo; é exatamente o tipo de feedback que revela suposição errada.</p>
<h2>ai-usagebar: saber quando trocar de cavalo<span class="hx:absolute hx:-mt-20" id="ai-usagebar-saber-quando-trocar-de-cavalo"></span>
    <a href="#ai-usagebar-saber-quando-trocar-de-cavalo" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Como falei acima, eu prefiro usar os planos subsidiados da Anthropic e da OpenAI. O problema é que, se você faz Agile Vibe Coding de verdade, você bate limite. Limite diário. Limite semanal. Limite de sessão. Limite que muda. Limite que não aparece direito em lugar nenhum.</p>
<p>Eu usava o <a href="https://github.com/mryll/claudebar"target="_blank" rel="noopener">claudebar</a>, que é bom, mas só cobre Claude. Eu queria ver os principais vendors num lugar só. Daí nasceu o <a href="https://github.com/akitaonrails/ai-usagebar"target="_blank" rel="noopener">ai-usagebar</a>, que apresentei no post <a href="/2026/05/24/criei-widget-waybar-omarchy-monitorar-uso-llms-ai-usagebar/">&ldquo;Criei um Widget de Waybar pra Omarchy pra Monitorar Uso de Planos de LLM: ai-usagebar&rdquo;</a>.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/24/ai-usagebar/ai-usagebar-waybar.png" alt="Widget na Waybar mostrando “cld 29% · 1h 12m” no canto superior direito, com tooltip aberto exibindo o plano Claude Max 20x: Session 29%, Weekly 47%, Sonnet only 0%, Extra usage $0.00 sobre limite de $1100, e horário da última atualização."  loading="lazy" /></p>
<p>É um widget de Waybar e uma TUI em Rust pra monitorar uso de Anthropic Claude, OpenAI Codex/ChatGPT, Z.AI GLM e OpenRouter. Pra Claude e OpenAI, ele lê as credenciais OAuth que os CLIs oficiais já gravaram. Pra Z.AI e OpenRouter, usa API key. Mostra porcentagem da sessão, reset, limites, saldo, e permite trocar o vendor principal.</p>
<p>O valor disso é banal e por isso mesmo útil: bato o olho na barra e sei se devo continuar no Claude, fazer handoff pro Codex, ou recarregar crédito no OpenRouter. Não quero descobrir que cheguei no limite semanal no meio de uma refatoração grande.</p>
<p>Também tem a TUI standalone:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/24/ai-usagebar/ai-usagebar-tui-openai.png" alt="ai-usagebar-tui na aba OpenAI rodando num terminal: gauges de Codex 5h e semanal, bloco de Credits com faixas de contagem de mensagens, abas Claude / OpenAI / GLM (Z.AI) / OpenRouter no topo, atalhos de tecla no rodapé."  loading="lazy" /></p>
<p>Se você não usa Omarchy, Hyprland ou Waybar, ainda dá pra rodar <code>ai-usagebar-tui</code> em qualquer terminal. SSH, tmux, terminal normal, tanto faz. A barra é conveniência. A TUI é a forma universal.</p>
<h2>ghpending: pendência de GitHub sem ritual<span class="hx:absolute hx:-mt-20" id="ghpending-pendência-de-github-sem-ritual"></span>
    <a href="#ghpending-pend%c3%aancia-de-github-sem-ritual" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Depois da maratona, fiquei com dezenas de <code>ai-*</code> e <code>frank-*</code> no GitHub. Isso cria um problema chato: issues e pull requests começam a aparecer. Contribuidor abre PR. Alguém reporta bug. Outro manda sugestão. Se eu tiver que abrir o navegador, entrar repo por repo, filtrar aba por aba, eu vou adiar. E se eu adiar, fico semanas sem responder.</p>
<p>Sim, eu poderia usar <code>gh</code>, a CLI oficial do GitHub. Aliás, uso. Mas eu queria uma coisa mais burra e mais rápida: um comando curto pra imprimir um digest de tudo que está pendente nos repos que eu escolhi monitorar. Nasceu o <a href="https://github.com/akitaonrails/ghpending"target="_blank" rel="noopener">ghpending</a>, que descrevi no post <a href="/2026/05/23/criei-cli-pra-checar-pendencias-github-ghpending/">&ldquo;Criei um CLI pra Checar Pendências no Meu GitHub: ghpending&rdquo;</a>.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/23/ghpending/ghpending-screenshot.png" alt="Saída do ghpending no terminal: tabela compacta listando cada repo monitorado com contagem de issues e pull requests abertos, autor da última atividade e há quanto tempo."  loading="lazy" /></p>
<p>É só isso: <code>ghpending add</code> pra escolher repos, <code>ghpending</code> pra ver o digest, <code>ghpending list</code>, <code>ghpending rm</code>. Sem autenticação funciona com limite de 60 req/h do GitHub. Com <code>GITHUB_TOKEN=$(gh auth token) ghpending</code>, sobe pra 5.000 req/h.</p>
<p>O ponto não é substituir o GitHub. É reduzir atrito. Se eu consigo rodar um comando no terminal e ver &ldquo;tem 3 PRs e 2 issues pra olhar&rdquo;, eu olho. Se depende de ritual de navegador, notificações e abas, fica pra depois.</p>
<p>E Claude/Codex são muito bons nesse tipo de trabalho. Dá pra pedir:</p>
<blockquote>
  <p>&ldquo;Checa os pull requests abertos, revisa o código, vê se compila, roda os testes, adiciona teste se faltar, faz rebase de master se precisar, mergeia e fecha.&rdquo;</p>

</blockquote>
<p>Ou:</p>
<blockquote>
  <p>&ldquo;Checa as issues abertas, avalia se tem bug real, reproduz se der, propõe correção, responde o usuário.&rdquo;</p>

</blockquote>
<p>Eles leem o PR, entendem o diff, rodam teste, fazem rebase, resolvem conflito simples, escrevem resposta pro contribuidor. Não é pra desligar o cérebro. É pra terceirizar o trabalho mecânico que você já sabe fazer.</p>
<h2>Refatoração: peça explicitamente, várias vezes<span class="hx:absolute hx:-mt-20" id="refatoração-peça-explicitamente-várias-vezes"></span>
    <a href="#refatora%c3%a7%c3%a3o-pe%c3%a7a-explicitamente-v%c3%a1rias-vezes" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Claude e Codex são muito bons em refatorar, mas não presuma que vão fazer isso automaticamente do jeito que você faria. Eu costumo começar projetos ou features com instruções explícitas:</p>
<blockquote>
  <p>&ldquo;Use as melhores práticas de Rust. Evite duplicação desnecessária. Modularize só onde fizer sentido. Adicione unit tests pra toda feature nova. Siga princípios de <a href="/2026/04/20/clean-code-para-agentes-de-ia/">Clean Code</a>. Não crie abstração antes de precisar.&rdquo;</p>

</blockquote>
<p>Depois de uma feature grande, uma correção grande, ou algumas horas de desenvolvimento, paro e peço:</p>
<blockquote>
  <p>&ldquo;Agora que mexemos bastante no código, reavalie com calma. Delete código morto. Refatore duplicações óbvias. Adicione testes faltantes. Remova magic numbers. Veja se tem módulos grandes demais. Não mude comportamento sem teste.&rdquo;</p>

</blockquote>
<p>Antes de release:</p>
<blockquote>
  <p>&ldquo;Antes de publicar essa versão, faça uma auditoria de sanidade. Procure vazamento de secrets, permissões perigosas, comandos destrutivos, path traversal, unwraps desnecessários, falta de validação, e qualquer coisa que pareça vulnerabilidade óbvia.&rdquo;</p>

</blockquote>
<p>Isso garante segurança? Claro que não. Nem perto. Mas remove muito erro besta. É mais uma camada. Eu gosto de rodar essa auditoria com Claude e depois com Codex, porque cada um acha coisas diferentes. Mesmo assim, bug passa. Segurança é processo, não ritual mágico.</p>
<h2>Experimentos descartáveis: código ficou barato<span class="hx:absolute hx:-mt-20" id="experimentos-descartáveis-código-ficou-barato"></span>
    <a href="#experimentos-descart%c3%a1veis-c%c3%b3digo-ficou-barato" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Antes de escolher biblioteca, framework, arquitetura, modelo ou serviço, eu gosto de criar <code>experiments/</code>.</p>
<p>Exemplo:</p>
<blockquote>
  <p>&ldquo;Antes de escolher entre Qwen e DeepSeek, cria um protótipo descartável em <code>experiments/</code> pra A/B test. Documenta a análise em <code>docs/</code> com resultado, custo, latência, qualidade e recomendação.&rdquo;</p>

</blockquote>
<p>Isso mudou meu jeito de decidir. Antes, muita decisão de engenharia virava opinião, feeling, fé em benchmark dos outros. Agora código é barato. Peço pro agente fazer duas ou três versões, rodar teste, medir, documentar, jogar fora o que não presta.</p>
<p>Prototipar ficou rápido de verdade. O <a href="/2026/04/05/transformando-youtube-num-app-de-karaoke-frank-karaoke/">Frank Karaoke</a> é um bom exemplo: transformar YouTube num app de karaokê era o tipo de ideia que antes eu talvez deixasse numa lista mental por meses, esperando &ldquo;um fim de semana livre&rdquo; que nunca chega. Agora dá pra abrir um <code>experiments/</code>, pedir um protótipo tosco, testar o caminho técnico, e decidir se vale virar projeto. Olha meus outros posts de 2026 sobre os projetos <code>frank-*</code> e <code>ai-*</code>: quase todos começaram assim, como código descartável que provou alguma coisa antes de merecer nome.</p>
<p>Mas protótipo barato não significa one-shot. Já escrevi em <a href="/2026/04/15/como-falar-com-o-claude-code-efetivamente/">&ldquo;Por que as LLMs não te dão o resultado esperado&rdquo;</a>: prompt bom é conversa iterativa. Você dá contexto, mostra referência, aponta restrição, lê o resultado, corrige direção, manda refazer. Se você joga uma frase vaga e espera produto pronto, o erro é seu.</p>
<p>Também aprendi isso apanhando. No post do <a href="/2026/03/05/meu-primeiro-fracasso-com-vibe-code-e-como-consertei-frank-yomik/">Frank Yomik</a> contei meu primeiro fracasso real com vibe coding: quando a direção está errada, insistir no mesmo prompt só cava o buraco. Tem hora que precisa reduzir escopo, isolar o problema, criar teste, trocar estratégia. LLM não transforma plano ruim em engenharia boa.</p>
<p>E tem domínio onde você precisa estudar junto. No post de <a href="/2026/04/23/driveclub-shadps4-e-ia-como-aprender/">Driveclub e shadPS4</a>, a IA quase me levou pra todo lado errado porque o problema exigia entender renderização, gamma, shaders, buffers. A ferramenta ajuda a explorar, mas quem decide se a explicação faz sentido ainda é você. Se você não entende o suficiente pra verificar, está só aceitando chute bonito.</p>
<p>Por isso também repito a ideia de <a href="/2026/03/01/software-nunca-esta-pronto-4-projetos-a-vida-pos-deploy-e-por-que-one-shot-prompt-e-mito/">&ldquo;Software Nunca Está Pronto&rdquo;</a>: deploy não é linha de chegada. O protótipo vira produto quando aguenta bug report, manutenção, refatoração, docs, release, rollback, usuário reclamando. LLM ajuda muito nesse ciclo chato. Mas o ciclo continua existindo.</p>
<p>Se é testável, teste. Se dá pra medir, meça. Se não dá pra medir, pelo menos escreva as premissas. O importante é não escolher só porque &ldquo;parece melhor&rdquo;.</p>
<p>Código barato também significa desapego. Faça código pra jogar fora. Faça protótipo feio. Faça benchmark descartável. Peça pro agente documentar o que aprendeu em <code>docs/decision-qwen-vs-deepseek.md</code>, depois apague <code>experiments/</code> se quiser. O documento fica. O aprendizado fica.</p>
<p>LLMs também são muito bons em documentação. Use isso. Peça pra documentar tudo. Por que escolhemos PostgreSQL em vez de SQLite nesse caso. Por que o deploy usa Docker image multi-stage. Por que o serviço roda atrás de Cloudflare Tunnel. Por que aquele sysctl existe. Mesmo que depois você delete metade, o custo de escrever caiu perto de zero.</p>
<h2>Deploy automatizado ou você vai parar de manter<span class="hx:absolute hx:-mt-20" id="deploy-automatizado-ou-você-vai-parar-de-manter"></span>
    <a href="#deploy-automatizado-ou-voc%c3%aa-vai-parar-de-manter" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Todo projeto meu que importa tem build automatizado. Muitos rodam no meu homelab, como descrevi em <a href="/2026/03/31/migrando-meu-home-server-com-claude-code/">&ldquo;Migrando meu Home Server com Claude Code&rdquo;</a>. Quase todo projeto tem um <code>bin/deploy</code> que builda imagem Docker, faz push, rotaciona no servidor, aplica migração se precisar, e valida healthcheck.</p>
<p>Claude e Codex são excelentes em deploy. Eles leem o <code>bin/deploy</code>, entendem Dockerfile, editam GitHub Actions, ajustam release workflow, corrigem assinatura de binário, atualizam Homebrew tap, geram checksum. E sim, eu peço pra Claude/Codex dar SSH no meu homelab e redeployar container Docker. Eles são muito bons nisso. O ai-jail, por exemplo, tem GitHub Actions pra buildar binários assinados pra Linux e macOS.</p>
<p>Se você tem dezenas de projetos, quanto mais automatizado melhor. Eu raramente digito comando administrativo no terminal sozinho. Peço pro LLM fazer, observo, aprovo o que for perigoso, e depois peço:</p>
<blockquote>
  <p>&ldquo;Documente o que foi feito e por que foi feito.&rdquo;</p>

</blockquote>
<p>Isso vale pro homelab e pra minha workstation. Meu Omarchy é customizado via Claude: ZSH, Hyprland, Waybar, scripts, atalhos, temas, integrações. Até meus setups de gaming/emulação entram nessa, como mostrei no post dos <a href="/2026/04/19/retrogames-de-corrida-favoritos-no-distrobox/">retrogames de corrida rodando no Distrobox</a>. Esse é um caso onde normalmente não uso ai-jail, porque justamente quero mexer no host. Então olho comandos, leio diffs, aprovo devagar. Mesmo assim, nunca tive o agente quebrando meu sistema de um jeito irrecuperável. Pelo contrário. Meu PC nunca esteve tão estável e documentado.</p>
<p>Dias depois, quando esqueço por que configurei alguma coisa daquele jeito, o contexto está em markdown, Git, ai-memory, ou no próprio histórico do projeto. Eu posso perguntar e o agente tem de onde puxar.</p>
<h2>Até este post foi escrito assim<span class="hx:absolute hx:-mt-20" id="até-este-post-foi-escrito-assim"></span>
    <a href="#at%c3%a9-este-post-foi-escrito-assim" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Inclusive, é assim que escrevo estes posts agora. Eu jogo um bloco enorme e bagunçado do meu cérebro no Claude. Peço pra ler posts recentes pra calibrar estilo. Peço pra checar os projetos diretamente e elaborar as partes técnicas. Peço pra usar as screenshots mais recentes, subir pro S3 quando precisa, linkar os posts anteriores, revisar o tom.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/24/ai-toolkit/writing-this-post.png" alt="Screenshot do terminal com o prompt bruto usado pra escrever este post: um bloco enorme de instruções, links, opiniões e detalhes técnicos jogado no agente antes da edição final."  loading="lazy" /></p>
<p>Depois eu leio e edito. Corto o que ficou genérico. Troco frase que parece release note. Coloco minhas broncas de volta. O resultado ainda é meu texto, só que agora eu gasto energia no que importa: decidir o que dizer, corrigir nuance, cortar besteira.</p>
<h2>&ldquo;Mas você testou o Pi?&rdquo;<span class="hx:absolute hx:-mt-20" id="mas-você-testou-o-pi"></span>
    <a href="#mas-voc%c3%aa-testou-o-pi" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Toda vez que falo de LLM ou ferramenta de LLM, aparece alguém nos comentários com a mesma pergunta: &ldquo;mas você testou Pi?&rdquo;, &ldquo;mas você testou DeepSeek?&rdquo;, &ldquo;mas e o Qwen?&rdquo;, &ldquo;mas e o modelo novo que saiu ontem?&rdquo;. Toda. Santa. Vez.</p>
<p>É irritante pra cacete. E quase sempre vem de três tipos de pessoa: quem não testou nada e quer terceirizar o trabalho, quem já escolheu uma ferramenta e quer que eu valide a escolha dela, ou fanboy que trata vendor de LLM como time de futebol. Todos soam iguais. NPC repetindo diálogo de tutorial.</p>
<p>Engenheiro de software não deveria decidir baseado em opinião dos outros. Nem na minha. Se você escolhe ferramenta porque &ldquo;o Akita falou&rdquo;, você entendeu errado. Eu defendo Claude Code e Codex porque usei centenas de horas, em projetos reais, publicando código e post-mortem do que funcionou e do que falhou. E mesmo assim eu não parei em opinião.</p>
<p>Eu criei meu próprio benchmark automatizado: <a href="https://github.com/akitaonrails/llm-coding-benchmark"target="_blank" rel="noopener">llm-coding-benchmark</a>. Atualizo quando vendor popular solta versão nova. Rodo cenários comparáveis. Publico resultado. Depois ajusto minha opinião baseado nos dados. É por isso que eu tenho segurança pra dizer que, no meu fluxo, Opus e GPT continuam vencendo. Não porque acordei com vontade de defender logo de empresa bilionária.</p>
<p>Se sua primeira reação foi &ldquo;mas você testou Qwen?&rdquo;, ótimo. Testa você. Roda o benchmark. Cria cenário melhor. Manda PR. Mostra número. Mostra custo. Mostra latência. Mostra onde falhou. Mostra onde ganhou. Traga dado novo.</p>
<p>Opinião solta é irrelevante. &ldquo;Pra mim funciona&rdquo; não escala. &ldquo;Eu gosto mais&rdquo; não interessa. &ldquo;No meu prompt one-shot ele foi melhor&rdquo; é anedota. Engenharia começa quando dá pra reproduzir, comparar e agir em cima.</p>
<p>Então fica simples: traga dado acionável ou fique quieto. Eu não preciso de torcida organizada de vendor nos comentários. Preciso de gente testando, medindo e contribuindo resultado novo.</p>
<h2>Checklist final<span class="hx:absolute hx:-mt-20" id="checklist-final"></span>
    <a href="#checklist-final" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Resumo curto, porque este post já ficou grande:</p>
<ul>
<li>Foque em Claude Code, Codex ou opencode. Pare de colecionar agente.</li>
<li>Use Opus 4.7 e GPT 5.5 via planos Pro/Plus/Max quando produtividade diária importa.</li>
<li>DeepSeek, Kimi e modelos locais são úteis, mas ainda não substituem o fluxo principal.</li>
<li>Agile Vibe Coding é XP com LLM: testes, <a href="/2026/04/20/clean-code-para-agentes-de-ia/">Clean Code</a>, CI, pair programming e deploy.</li>
<li>Use <code>ai-jail</code> quando quiser autonomia do agente com cerca no filesystem.</li>
<li>Combine <code>ai-jail</code> com permissões perigosas do Claude/Codex quando o projeto estiver protegido por Git.</li>
<li>Tenha backup de verdade: Btrfs snapshots, restic, NAS, offsite, Git, Bitwarden.</li>
<li>Revise <code>git add</code>, <code>git diff --cached</code> e pushes pra não vazar secrets.</li>
<li>Use <code>ai-memory</code> pra contexto transitório e handoff entre agentes.</li>
<li>Escreva documentação canônica em <code>docs/</code> quando a informação precisa sobreviver com garantia.</li>
<li>Use <code>ai-usagebar</code> pra saber quando trocar de Claude pra Codex, ou quando recarregar OpenRouter.</li>
<li>Use <code>ghpending</code> pra não abandonar issues e PRs.</li>
<li>Peça refatoração explicitamente depois de features grandes.</li>
<li>Rode auditoria de segurança antes de release, de preferência com mais de um modelo.</li>
<li>Crie protótipos descartáveis em <code>experiments/</code> antes de decidir por fé.</li>
<li>Se discordar de benchmark, rode o <a href="https://github.com/akitaonrails/llm-coding-benchmark"target="_blank" rel="noopener">llm-coding-benchmark</a> e traga dado novo.</li>
<li>Documente decisões em markdown. Código ficou barato. Documentação também.</li>
<li>Automatize deploy. Se depender de ritual manual, você vai parar de fazer.</li>
</ul>
<p>No fim, é o mesmo conselho de sempre: ferramenta muda, engenharia não. LLM aumenta a alavanca. Se você já tinha bons hábitos, vai produzir mais. Se não tinha, vai só produzir bagunça mais rápido.</p>
<p>E sim, isso muda a interface do trabalho. Já escrevi sobre isso em <a href="/2026/04/11/vs-code-e-o-novo-cartao-perfurado/">&ldquo;VS Code é o novo Cartão Perfurado&rdquo;</a>: ficar polindo pixel em editor virou nostalgia de programador velho. A parte difícil agora é escrever intenção direito, revisar execução sem preguiça, medir resultado, jogar fora código barato, e não confundir opinião com dado.</p>
]]></content:encoded><category>ai-jail</category><category>ai-memory</category><category>ai-usagebar</category><category>ghpending</category></item><item><title>Criei um CLI pra Checar Pendências no Meu GitHub: ghpending</title><link>https://akitaonrails.github.io/2026/05/23/criei-cli-pra-checar-pendencias-github-ghpending/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/05/23/criei-cli-pra-checar-pendencias-github-ghpending/</guid><pubDate>Sat, 23 May 2026 22:00:00 -0300</pubDate><description>&lt;p&gt;Depois da minha &lt;a href="https://akitaonrails.github.io/2026/05/14/terminando-maratona-ia-sucesso-ou-fracasso/"&gt;maratona de IA&lt;/a&gt;, fiquei com dezenas de repositórios públicos no GitHub pra cuidar. Vários deles têm contribuidores postando issues e mandando pull requests. O problema é que abrir o navegador, entrar em cada repo, ver se tem alguma coisa nova esperando, vira um ritual cansativo que eu acabo evitando. E quando evito, fico semanas sem responder os colaboradores.&lt;/p&gt;
&lt;p&gt;Sei que tem várias ferramentas que resolvem isso. Mas eu queria algo bem simples e rápido pra rodar no terminal e ver pendências de todos os meus projetos de uma vez só. Então fiz: o &lt;strong&gt;&lt;a href="https://github.com/akitaonrails/ghpending"target="_blank" rel="noopener"&gt;ghpending&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Depois da minha <a href="/2026/05/14/terminando-maratona-ia-sucesso-ou-fracasso/">maratona de IA</a>, fiquei com dezenas de repositórios públicos no GitHub pra cuidar. Vários deles têm contribuidores postando issues e mandando pull requests. O problema é que abrir o navegador, entrar em cada repo, ver se tem alguma coisa nova esperando, vira um ritual cansativo que eu acabo evitando. E quando evito, fico semanas sem responder os colaboradores.</p>
<p>Sei que tem várias ferramentas que resolvem isso. Mas eu queria algo bem simples e rápido pra rodar no terminal e ver pendências de todos os meus projetos de uma vez só. Então fiz: o <strong><a href="https://github.com/akitaonrails/ghpending"target="_blank" rel="noopener">ghpending</a></strong>.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/23/ghpending/ghpending-screenshot.png" alt="Saída do ghpending no terminal: tabela compacta listando cada repo monitorado com contagem de issues e pull requests abertos, autor da última atividade e há quanto tempo."  loading="lazy" /></p>
<p>Roda em Linux e macOS. Eu testei em Linux (Arch + Omarchy) mas ainda não rodei no macOS. Se você for testar lá e topar com algum bug, abre uma issue lá: <a href="https://github.com/akitaonrails/ghpending/issues"target="_blank" rel="noopener">github.com/akitaonrails/ghpending/issues</a>.</p>
<h2>Instalação<span class="hx:absolute hx:-mt-20" id="instalação"></span>
    <a href="#instala%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Três caminhos, escolhe o que mais combina com seu setup.</p>
<p>Via Homebrew (macOS ou Linux):</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">brew tap akitaonrails/tap <span class="o">&amp;&amp;</span> brew install ghpending</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Via Cargo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">cargo install ghpending</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Via mise:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">mise use -g github:akitaonrails/ghpending</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h2>Atualizando<span class="hx:absolute hx:-mt-20" id="atualizando"></span>
    <a href="#atualizando" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl"><span class="c1"># Homebrew</span>
</span></span><span class="line"><span class="cl">brew upgrade ghpending
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Cargo</span>
</span></span><span class="line"><span class="cl">cargo install ghpending --force
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># mise</span>
</span></span><span class="line"><span class="cl">mise upgrade ghpending
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># From source</span>
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> ghpending <span class="o">&amp;&amp;</span> git pull <span class="o">&amp;&amp;</span> cargo install --path .</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h2>Uso<span class="hx:absolute hx:-mt-20" id="uso"></span>
    <a href="#uso" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Quatro comandos. O fluxo normal é rodar <code>ghpending add</code> uma vez pra configurar quais repos você quer monitorar, depois é só <code>ghpending</code> quando quiser ver o digest.</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">ghpending add    <span class="c1"># pick os repos de um usuário ou org pra monitorar</span>
</span></span><span class="line"><span class="cl">ghpending        <span class="c1"># imprime o digest de issues e PRs abertos</span>
</span></span><span class="line"><span class="cl">ghpending list   <span class="c1"># mostra os repos monitorados</span>
</span></span><span class="line"><span class="cl">ghpending rm     <span class="c1"># tira repos do monitoramento via menu interativo</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O <code>add</code> pergunta o usuário ou organização, lista os repos públicos, e deixa você marcar os que quer acompanhar. O username fica salvo, então rodar <code>add</code> de novo já pula essa pergunta.</p>
<p>O comando principal (<code>ghpending</code> sem argumentos) busca todos os repos monitorados em paralelo e mostra a tabela com issues e PRs abertos.</p>
<h2>Token do GitHub (opcional)<span class="hx:absolute hx:-mt-20" id="token-do-github-opcional"></span>
    <a href="#token-do-github-opcional" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Sem autenticação funciona, mas o GitHub limita em 60 requisições por hora pra anônimo. Pra subir esse teto pra 5.000 req/h, exporta um token:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl"><span class="nv">GITHUB_TOKEN</span><span class="o">=</span><span class="k">$(</span>gh auth token<span class="k">)</span> ghpending</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Ele é lido silenciosamente na inicialização, não precisa configurar nada.</p>
<h2>Onde fica o config<span class="hx:absolute hx:-mt-20" id="onde-fica-o-config"></span>
    <a href="#onde-fica-o-config" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><ul>
<li>Linux: <code>~/.config/ghpending/config.toml</code></li>
<li>macOS: <code>~/Library/Application Support/ghpending/config.toml</code></li>
</ul>
<p>Você pode editar direto se quiser reordenar ou trocar o <code>user</code>. Estrutura:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="nx">user</span> <span class="p">=</span> <span class="s2">&#34;akitaonrails&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">repos</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;akitaonrails/ai-memory&#34;</span><span class="p">,</span> <span class="s2">&#34;akitaonrails/ai-jail&#34;</span><span class="p">]</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h2>Por que esse CLI existe<span class="hx:absolute hx:-mt-20" id="por-que-esse-cli-existe"></span>
    <a href="#por-que-esse-cli-existe" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A real é simples: ferramenta que eu fizesse pra mim mesmo, eu uso. Ferramenta de outro autor, sempre tem fricção (login web, opinião arquitetural diferente, feature que faltou ou sobrou). Como o objetivo era reduzir o atrito de checar 30 repos por semana, melhor 200 linhas de Rust escritas num sábado à tarde do que aprender um stack novo.</p>
<p>Agora espero conseguir responder as pendências dos colaboradores mais rápido. Se você achar útil, é MIT, PRs são bem-vindos.</p>
]]></content:encoded><category>ghpending</category><category>automacao</category><category>ferramentas-de-desenvolvimento</category><category>controle-de-versao</category></item></channel></rss>