<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Reviews | AkitaOnRails.com</title><link>https://akitaonrails.github.io/tags/reviews/</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:49 +0000</lastBuildDate><atom:link href="https://akitaonrails.github.io/tags/reviews/index.xml" rel="self" type="application/rss+xml"/><item><title>A Volta da Intel: ARM64 vs X86-64 não é como você imagina</title><link>https://akitaonrails.github.io/2026/08/11/a-volta-da-intel-arm64-vs-x86-64-nao-e-como-voce-imagina/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/08/11/a-volta-da-intel-arm64-vs-x86-64-nao-e-como-voce-imagina/</guid><pubDate>Tue, 11 Aug 2026 10:00:00 -0300</pubDate><description>&lt;p&gt;Desde janeiro, quando os primeiros laptops com Panther Lake chegaram às lojas, os reviews vêm repetindo uma frase que há cinco anos soaria absurda: um chip Intel x86 batendo de frente com o Apple M5. Não em tudo — já chego nos poréns — mas no quesito que mais importa no dia a dia, bateria, o jogo virou. E isso me dá a desculpa perfeita pra escrever sobre uma crença que vejo programador repetir sem checar: a de que eficiência de verdade só vem com ARM64, porque o x86 é velho, pesado e cheio de entulho de 1978.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Desde janeiro, quando os primeiros laptops com Panther Lake chegaram às lojas, os reviews vêm repetindo uma frase que há cinco anos soaria absurda: um chip Intel x86 batendo de frente com o Apple M5. Não em tudo — já chego nos poréns — mas no quesito que mais importa no dia a dia, bateria, o jogo virou. E isso me dá a desculpa perfeita pra escrever sobre uma crença que vejo programador repetir sem checar: a de que eficiência de verdade só vem com ARM64, porque o x86 é velho, pesado e cheio de entulho de 1978.</p>
<p>Minha tese: isso era verdade gerações atrás, quando decodificar x86 custava uma fatia relevante da pastilha (o <em>die</em>). Hoje o x86 é, na prática, uma camada de tradução pra micro-instruções — e o que separa Apple, Qualcomm e Intel nunca foi o conjunto de instruções. A crise da Intel foi gerencial e de fábrica, não arquitetural. E é por isso que a volta dela, agora, faz sentido.</p>
<h2>O que os reviews mostram<span class="hx:absolute hx:-mt-20" id="o-que-os-reviews-mostram"></span>
    <a href="#o-que-os-reviews-mostram" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Os laptops Panther Lake (Core Ultra série 3, lançados na CES em 5 de janeiro e à venda desde 27 de janeiro) entregam números que a era Meteor/Arrow Lake não sonhava. Começando por bateria — Dell XPS 14 2026 (Core Ultra X7 358H) contra MacBook Air 15 (M5):</p>
<table>
  <thead>
      <tr>
          <th>Teste de bateria</th>
          <th>Dell XPS 14 (Panther Lake)</th>
          <th>MacBook Air 15 (M5)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Navegação web (<a href="https://www.notebookcheck.net/43-hours-battery-life-Dell-XPS-14-2026-lasts-almost-3x-longer-vs-MacBook-Air-15-M5-in-web-browsing-test.1262947.0.html"target="_blank" rel="noopener">Hardware Canucks</a>, com VRR)</td>
          <td><strong>43 horas</strong></td>
          <td>14h30</td>
      </tr>
      <tr>
          <td>Navegação web (<a href="https://www.notebookcheck.net/Dell-XPS-14-2026-with-Intel-Panther-Lake-delivers-55-longer-battery-life-vs-2025-Dell-14-Premium.1225329.0.html"target="_blank" rel="noopener">Notebookcheck</a>, outra metodologia)</td>
          <td>16h45 (+55% vs modelo 2025)</td>
          <td>17h12</td>
      </tr>
      <tr>
          <td>YouTube 4K</td>
          <td><strong>20h21</strong></td>
          <td>14h</td>
      </tr>
      <tr>
          <td>Carga pesada (game)</td>
          <td>2h30</td>
          <td><strong>4h10</strong></td>
      </tr>
  </tbody>
</table>
<p>Leitura honesta: em uso leve, o Dell empata ou passa; em carga sustentada, a Apple continua imbatível. E o DHH publicou que seu XPS 14 rodando Omarchy Linux passa de 16 horas de uso real, com consumo em repouso de 1,4W — a Dell fez questão de <a href="https://www.dell.com/en-us/blog/year-of-the-linux-laptop-omarchy-on-xps/"target="_blank" rel="noopener">suporte a Linux desde o dia um</a>.</p>
<p>Na CPU, o topo de linha Core Ultra X9 388H contra o M5 (<a href="https://www.notebookcheck.net/Intel-Panther-Lake-Core-Ultra-X9-388H-performance-analysis-Outpaces-Arrow-Lake-and-exceeds-Zen-5-in-efficiency.1212583.0.html"target="_blank" rel="noopener">dados da Notebookcheck</a>):</p>
<table>
  <thead>
      <tr>
          <th>Métrica</th>
          <th>Core Ultra X9 388H</th>
          <th>Apple M5</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cinebench 2024 multi-core</td>
          <td>~1.162</td>
          <td>~1.172 (<strong>empate estatístico</strong>)</td>
      </tr>
      <tr>
          <td>Cinebench 2024 single-core</td>
          <td>~130</td>
          <td><strong>200</strong> (~30% à frente)</td>
      </tr>
      <tr>
          <td>Eficiência single-core</td>
          <td>5,17 pts/watt</td>
          <td><strong>13,1 pts/watt</strong></td>
      </tr>
      <tr>
          <td>Eficiência multi-core limitado a 20W</td>
          <td>24,6 pts/watt</td>
          <td>24,8 (M4)</td>
      </tr>
  </tbody>
</table>
<p>Single-core continua território da Apple, que faz o mesmo trabalho <strong>com um terço da energia</strong>. Mas em multi-core moderado, a Intel encostou. Contra a AMD (Ryzen AI 9 465) o 388H ganha em tudo; contra o Snapdragon X Elite de primeira geração também; o X2 Elite Extreme, que chegou em 2026, já devolveu a coroa de CPU Windows pra Qualcomm (+24% em single-core). Honestidade acima de tudo.</p>
<p>Na GPU, o veredito é mais misto que o marketing da Intel sugere:</p>
<table>
  <thead>
      <tr>
          <th>Confronto da Arc B390</th>
          <th>Resultado</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>vs Radeon 890M (AMD)</td>
          <td><a href="https://videocardz.com/newz/intel-arc-b390-beats-amds-mainstream-igpus-and-nears-rtx-4050-level-performance-in-some-tests"target="_blank" rel="noopener">+63 a 80%</a></td>
      </tr>
      <tr>
          <td>vs RTX 4050 de laptop</td>
          <td>empate técnico</td>
      </tr>
      <tr>
          <td>vs Strix Halo (AMD) a 15-20W</td>
          <td><a href="https://www.notebookcheck.net/No-chance-for-AMD-Intel-Panther-Lake-Core-Ultra-X9-388H-trounces-AMD-Strix-Halo-at-low-power-signaling-handheld-gaming-domination-in-2026.1213244.0.html"target="_blank" rel="noopener">vence</a></td>
      </tr>
      <tr>
          <td>vs GPU do M5 base</td>
          <td>vence em desempenho, perde em fps/watt</td>
      </tr>
      <tr>
          <td>vs M5 Pro / M5 Max</td>
          <td><a href="https://nanoreview.net/en/gpu-compare/intel-arc-b390-vs-apple-m5-max-gpu-40-core"target="_blank" rel="noopener">17 contra 24 e 44</a> — sem chance</td>
      </tr>
  </tbody>
</table>
<p>O resumo da <a href="https://arstechnica.com/gadgets/2026/02/intel-panther-lake-core-ultra-review-intels-best-laptop-cpu-in-a-very-long-time/"target="_blank" rel="noopener">Ars Technica</a> é o mais justo: &ldquo;o melhor CPU de laptop da Intel em muito tempo&rdquo; — com a ressalva de que a Intel precisa provar que isso é o novo normal, não uma aberração.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> bateria de MacBook num laptop x86 aconteceu — em uso leve. Em single-core e sob carga pesada, a Apple ainda dita o ritmo.</p>

</blockquote>
<h2>A crença: &ldquo;pra ser eficiente tem que ser ARM&rdquo;<span class="hx:absolute hx:-mt-20" id="a-crença-pra-ser-eficiente-tem-que-ser-arm"></span>
    <a href="#a-cren%c3%a7a-pra-ser-eficiente-tem-que-ser-arm" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Todo programador já ouviu a explicação: ARM tem conjunto de instruções simples, de tamanho fixo, elegante. O x86 é uma quimera acumulada desde 1978, com instruções de tamanho variável, modo real, segmentação, décadas de bagunça. &ldquo;Portanto&rdquo; ARM é inerentemente mais eficiente, e o caminho pra qualquer um chegar na eficiência da Apple ou da Qualcomm é migrar pra ARM64.</p>
<p>Tem verdade aí: o x86 carrega entulho histórico, e decodificar instrução de tamanho variável é objetivamente mais chato que decodificar instrução fixa de 32 bits. O erro está na conclusão. Essa diferença importava quando a lógica de decodificação ocupava uma fração significativa do chip. Isso faz muito tempo.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> a diferença entre ISAs importava quando a decodificação ocupava uma fração relevante da pastilha. Isso acabou há gerações.</p>

</blockquote>
<h2>O x86 virou camada de tradução em 1995<span class="hx:absolute hx:-mt-20" id="o-x86-virou-camada-de-tradução-em-1995"></span>
    <a href="#o-x86-virou-camada-de-tradu%c3%a7%c3%a3o-em-1995" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O Pentium Pro, de novembro de 1995, já não executava x86 diretamente: ele traduzia cada instrução CISC pra micro-operações internas estilo RISC e executava essas. A AMD fez o mesmo com o K5 em 1996 (as &ldquo;ROPs&rdquo;). Ou seja: faz <strong>trinta anos</strong> que &ldquo;executar x86&rdquo; significa &ldquo;traduzir pra outra coisa e executar a outra coisa&rdquo;. O x86 é uma interface de compatibilidade, uma camada de tradução sobre um motor RISC. E os números mostram o quanto essa camada ficou barata:</p>
<table>
  <thead>
      <tr>
          <th>Medição</th>
          <th>Resultado</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Micro-ops por instrução x86 (Pentium Pro, dados da Intel)</td>
          <td>1,2 a 1,7</td>
      </tr>
      <tr>
          <td>Acerto do cache de micro-ops (desde Sandy Bridge, 2011)</td>
          <td>~80% em geral, ~100% em loops quentes</td>
      </tr>
      <tr>
          <td>Custo do decodificador no Haswell (<a href="https://research.aalto.fi/en/publications/empirical-study-of-the-power-consumption-of-the-x86-64-instructio/"target="_blank" rel="noopener">Hirki et al., 2016</a>)</td>
          <td>3 a 10% da potência do pacote, no pior caso</td>
      </tr>
      <tr>
          <td>Custo de desligar o cache de micro-ops (<a href="https://chipsandcheese.com/p/how-zen-2s-op-cache-affects-performance"target="_blank" rel="noopener">Zen 2, Chips and Cheese</a>)</td>
          <td>+4 a 10% no core, +0,5 a 6% no pacote</td>
      </tr>
  </tbody>
</table>
<p>Quando o cache de micro-ops acerta, o hardware de busca e decodificação fica literalmente desligado. A conclusão do estudo da Hirki é seca: &ldquo;o conjunto de instruções x86-64 não é um obstáculo relevante pra produzir um processador energeticamente eficiente&rdquo;. E o estudo acadêmico definitivo — <a href="https://research.cs.wisc.edu/vertical/papers/2013/hpca13-isa-power-struggles.pdf"target="_blank" rel="noopener">Blem, Menon e Sankaralingam, HPCA 2013</a>, medindo ARM contra x86 de verdade — concluiu: contagem e composição de instruções são independentes do ISA em primeira ordem, as diferenças de performance vêm de microarquitetura, e &ldquo;o consumo de energia é, novamente, independente do ISA&rdquo;.</p>
<p>O Jim Keller — o cara que desenhou o Zen da AMD e os chips A4/A5 da Apple, alguém que morou nos dois lados — foi ainda mais direto numa entrevista à AnandTech: a decodificação de tamanho variável &ldquo;não está dominando a pastilha, então não importa tanto&rdquo;. O que limita performance hoje, segundo ele, é previsibilidade de branch e localidade de dados.</p>
<p>E tem o detalhe que derruba o mito de vez: ARM moderno faz a mesma coisa. O Cortex-A77 tem cache de micro-ops. A Samsung adicionou um no Exynos M5 explicitamente pra economizar energia de busca e decodificação. O A64FX da Fujitsu — o ARM dentro do supercomputador Fugaku — decodifica a instrução SVE <code>FADDA</code> em <strong>63 micro-ops</strong>. Sessenta e três. A fantasia do &ldquo;ARM é uma instrução por ciclo, simples e pura&rdquo; não existe mais em nenhum ARM de alto desempenho.</p>
<p>Uma nuance honesta antes de seguir: o comprimento variável do x86 realmente dificulta fazer decodificadores muito largos — a Apple decodifica <strong>até o dobro</strong> de instruções por ciclo que um x86. É uma dificuldade de engenharia real. Só que ela se paga em área de lógica, que é barata, e não em consumo proporcional ao trabalho — que é o que define bateria.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> faz trinta anos que nenhum x86 executa x86 — tudo vira micro-operação estilo RISC. O ISA virou interface de compatibilidade.</p>

</blockquote>
<h2>A conta dos transistores<span class="hx:absolute hx:-mt-20" id="a-conta-dos-transistores"></span>
    <a href="#a-conta-dos-transistores" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra entender por que o peso da decodificação evaporou, olha a evolução:</p>
<table>
  <thead>
      <tr>
          <th>Ano</th>
          <th>Chip</th>
          <th>Processo</th>
          <th>Transistores</th>
          <th>Marco</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>2000</td>
          <td>Pentium 4 Willamette</td>
          <td>180nm</td>
          <td>42 milhões</td>
          <td>a era do clock subindo</td>
      </tr>
      <tr>
          <td>2006</td>
          <td>Core 2 Duo</td>
          <td>65nm</td>
          <td>291 milhões</td>
          <td>o pivô multicore pós-Tejas</td>
      </tr>
      <tr>
          <td>2007</td>
          <td>Penryn</td>
          <td>45nm</td>
          <td>410 milhões</td>
          <td>primeiro high-k metal gate da indústria</td>
      </tr>
      <tr>
          <td>2011</td>
          <td>Ivy Bridge</td>
          <td>22nm</td>
          <td>1,4 bilhão</td>
          <td>FinFET 3D, -50% de potência na mesma performance</td>
      </tr>
  </tbody>
</table>
<p>Em 2000, cada bloco de lógica era um orçamento apertado, e a bagunça do x86 custava caro. Conforme os transistores ficaram infinitos pra todo fim prático, o custo fixo do decodificador virou troco. No meio do caminho, duas mudanças importantes:</p>
<ul>
<li><strong>A escala de Dennard morreu por volta de 2005.</strong> Vazamento de corrente impediu que os clocks continuassem subindo, a Intel cancelou o Tejas em 2004 e o mundo virou multicore. Clock parou nos 1-4GHz e nunca mais saiu dali.</li>
<li><strong>A lei de Moore virou economia, não física.</strong> O custo por transistor parou de cair no 28nm: uma fab de ponta hoje custa US$20 a 30 bilhões, e uma máquina High-NA EUV da ASML custa US$350 milhões.</li>
</ul>
<p>E o que ocupa pastilha e consome energia num chip moderno? Caches gigantes, branch predictors, dezenas de execution ports, GPU, NPU, motores de mídia. O decodificador de x86, na fila do pão, nem aparece.</p>
<p>E a história dá a prova empírica perfeita: de 2015 a 2021, a Intel ficou presa em 14nm — Skylake e seus derivados, seis anos de processo estagnado por falha de fábrica. Mesmo assim, esses cores velhos em 14nm trocavam soco com o Zen 2 da AMD, fabricado em 7nm pela TSMC. Se o x86 fosse o problema, isso seria impossível. O gargalo era a fábrica. Era a fábrica o tempo todo.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> seis anos presa em 14nm, e mesmo assim a Intel competia com chips em 7nm da TSMC. O gargalo era a fábrica, nunca o ISA.</p>

</blockquote>
<h2>O que realmente faz a Apple ser eficiente<span class="hx:absolute hx:-mt-20" id="o-que-realmente-faz-a-apple-ser-eficiente"></span>
    <a href="#o-que-realmente-faz-a-apple-ser-eficiente" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O M1 não é eficiente &ldquo;porque é ARM&rdquo;. A Apple tem licença arquitetural da ARM desde o A6, em 2012: ela desenha os próprios cores do zero e só o conjunto de instruções é ARM. Quando a AnandTech dissecou o core Firestorm do M1, o contraste com o x86 contemporâneo era de escolhas de engenharia, não de instruções:</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>Apple Firestorm (M1, 2020)</th>
          <th>Intel Sunny Cove (2019)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Decodificação por ciclo</td>
          <td>8</td>
          <td>4</td>
      </tr>
      <tr>
          <td>Reorder buffer</td>
          <td>~630 entradas</td>
          <td>352 entradas</td>
      </tr>
      <tr>
          <td>Cache L1 de instruções</td>
          <td>192KB</td>
          <td>32KB</td>
      </tr>
  </tbody>
</table>
<p>Na prática: o dobro de decodificação por ciclo, quase o dobro de buffer de reordenação, <strong>seis vezes</strong> o cache de instruções. Some a isso a memória unificada soldada no pacote e o processo TSMC de última geração. É microarquitetura agressiva, cache enorme, integração vertical e processo de ponta — tudo caro, tudo deliberado, e nada disso vem de graça com o ISA.</p>
<p>Aliás, a recíproca também é verdadeira: dá pra fazer ARM ruim. O mercado está cheio de ARM medíocre. Eficiência é escolha de engenharia e de processo, não certidão de nascença do ISA.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> o M1 é eficiente por microarquitetura, cache, processo e integração vertical — não &ldquo;porque é ARM&rdquo;.</p>

</blockquote>
<h2>Suas instruções favoritas não são x86 nem ARM<span class="hx:absolute hx:-mt-20" id="suas-instruções-favoritas-não-são-x86-nem-arm"></span>
    <a href="#suas-instru%c3%a7%c3%b5es-favoritas-n%c3%a3o-s%c3%a3o-x86-nem-arm" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>E tem outra coisa que quase ninguém menciona nesse debate: boa parte do que uma CPU moderna executa não pertence ao conjunto &ldquo;clássico&rdquo; de nenhum dos dois lados. Olha o que roda fora dele:</p>
<ul>
<li><strong>Vídeo.</strong> Na Intel, a decodificação fica no Quick Sync, hardware de função fixa que existe desde Sandy Bridge — um bloco separado que nada tem a ver com o legado x86. É por causa dele que a Frandroid mediu o Snapdragon X2 <strong>58% mais lento</strong> que o Panther Lake em exportação de vídeo.</li>
<li><strong>Criptografia.</strong> AES-NI existe desde 2010, extensões de SHA desde 2016 — instruções dedicadas, acrescentadas décadas depois do &ldquo;x86 velho&rdquo;.</li>
<li><strong>IA e matrizes.</strong> AVX-512, depois AVX10, e o AMX, um acelerador de tiles de matriz. O lado ARM tem os equivalentes: NEON, SVE, SME.</li>
</ul>
<p>A Chips and Cheese fez o experimento perfeito: no mesmo encode HEVC 4K, um Ampere ARM levou <strong>mais de doze vezes</strong> o tempo de um Zen 2 com o ffmpeg padrão; usando assembly NEON, o tempo do ARM caiu mais de 60%. A diferença nunca foi ARM contra x86 — era extensão vetorial bem usada contra extensão vetorial ignorada. No mundo real, o trabalho pesado mora nas extensões e nos aceleradores, e esses são ortogonais ao ISA base.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> o trabalho pesado moderno — vídeo, cripto, IA — roda em extensões e aceleradores dedicados, ortogonais ao ISA base.</p>

</blockquote>
<h2>A queda foi gerencial, não arquitetural<span class="hx:absolute hx:-mt-20" id="a-queda-foi-gerencial-não-arquitetural"></span>
    <a href="#a-queda-foi-gerencial-n%c3%a3o-arquitetural" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui a parte que me convence de vez. Olha a linha do tempo e tenta achar &ldquo;o x86 era uma limitação fundamental&rdquo; em algum ponto:</p>
<ul>
<li><strong>2005-2006</strong>: a Intel recusa fabricar o chip do iPhone — o Otellini admitiu o arrependimento em entrevista de saída à The Atlantic: &ldquo;o mundo teria sido muito diferente&rdquo;. E o detalhe tragicômico: a Intel <strong>tinha</strong> uma divisão ARM (a XScale) — e vendeu pra Marvell em 2006 por US$600 milhões. Não foi falta de tecnologia; foi falta de visão.</li>
<li><strong>2013-2021</strong>: três CEOs. Krzanich sai em 2018 por escândalo interno. Entra Bob Swan, um CFO de finanças, pra comandar uma empresa de engenharia no momento mais delicado da história dela.</li>
<li><strong>2018-2020</strong>: o 10nm vira piada (Cannon Lake só em tiragem limitada) e em julho de 2020 a Intel anuncia atraso no 7nm — a ação cai 16% num dia. Em abril de 2019, abandona o modem 5G de smartphone; a Apple compra o negócio por US$1 bilhão. Em novembro de 2020, o M1.</li>
<li><strong>2021-2024</strong>: Gelsinger volta com o plano IDM 2.0, &ldquo;cinco nós em quatro anos&rdquo;. Em dezembro de 2024 é empurrado pra &ldquo;aposentadoria&rdquo; — ultimato do conselho, segundo Reuters e Bloomberg. O ano fecha com prejuízo de <strong>US$18,8 bilhões</strong>, 15 mil demissões, dividendo suspenso e a Intel expulsa do Dow Jones depois de 25 anos — substituída pela Nvidia, que naquele momento valia <strong>mais de 30 vezes</strong> a Intel. Até outubro de 2025, a conta de demissões acumuladas chegava a 35.500.</li>
</ul>
<p>Nada nessa lista é arquitetura. É produto perdido, fab atrasada, decisão errada atrás de decisão errada. O x86 estava lá, competente, enquanto a empresa desmontava ao redor dele.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> iPhone recusado, XScale vendida, 10nm quebrado, três CEOs, US$18,8 bilhões de prejuízo — a queda da Intel foi decisão atrás de decisão, não limitação do x86.</p>

</blockquote>
<h2>O resgate improvável<span class="hx:absolute hx:-mt-20" id="o-resgate-improvável"></span>
    <a href="#o-resgate-improv%c3%a1vel" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>E aí 2025 acontece. Lip-Bu Tan assume em março. Em agosto, Trump exige a cabeça dele no Truth Social por laços com a China — e poucos dias depois, após uma reunião na Casa Branca, vira fã do cara. No dia 22 de agosto, o governo americano <a href="https://newsroom.intel.com/corporate/intel-and-trump-administration-reach-historic-agreement"target="_blank" rel="noopener">compra 9,9% da Intel</a>: 433,3 milhões de ações a US$20,47, US$8,9 bilhões no total, convertendo subsídios do CHIPS Act em participação acionária, sem assento no conselho. A SoftBank coloca <a href="https://newsroom.intel.com/corporate/softbank-group-and-intel-corporation-sign-2b-investment-agreement"target="_blank" rel="noopener">US$2 bilhões</a>. E a cereja surreal: a <strong>Nvidia</strong> — a mesma que a expulsou do Dow — <a href="http://nvidianews.nvidia.com/news/nvidia-and-intel-to-develop-ai-infrastructure-and-personal-computing-products"target="_blank" rel="noopener">investe US$5 bilhões</a> e fecha parceria pra colocar chiplets RTX em CPUs x86.</p>
<p>O resultado financeiro começou a aparecer: Q1 2026 com receita de US$13,6 bilhões (+7% ao ano), Q2 com US$16,1 bilhões (+25%), sétimo trimestre seguido acima das projeções. A ação que o governo pagou US$20,47 chegou a <strong>mais de seis vezes</strong> esse valor em maio, quando a Bloomberg noticiou conversas pra Intel fabricar chips da Apple — reportagem preliminar, produção a anos de distância, mas o mercado pirou. Mesmo depois de esfriar, a posição do governo americano segue valendo <strong>cinco vezes</strong> o que custou. O contribuinte dos EUA é, hoje, sócio lucrativo da Intel. Vai entender.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> governo dos EUA, SoftBank e Nvidia como sócios, e a ação cinco vezes acima do preço que o governo pagou — a Intel virou causa nacional, e o mercado comprou a volta.</p>

</blockquote>
<h2>A volta, com os pés no chão<span class="hx:absolute hx:-mt-20" id="a-volta-com-os-pés-no-chão"></span>
    <a href="#a-volta-com-os-p%c3%a9s-no-ch%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O Panther Lake é o primeiro produto grande do 18A — RibbonFET (transistor gate-all-around) mais PowerVia (alimentação pelo verso do wafer), saindo da Fab 52 em Chandler, Arizona. Tem ironia deliciosa aqui: o tile de GPU de 12 núcleos do topo de linha ainda é fabricado pela TSMC. E o aproveitamento do 18A (a fração de chips bons por wafer), segundo a Tom&rsquo;s Hardware, só deve chegar ao padrão da indústria em 2027 — a rampa é lenta e a Ars Technica acerta na dúvida: é o novo normal ou uma aberração?</p>
<p>Mas o ponto deste artigo não é torcida organizada. É que o Panther Lake encerra empiricamente um debate que era teológico. Um x86-64 em processo competitivo entrega bateria de MacBook, empata multi-core com o M5 e ganha da concorrência Windows em vários cenários. Se o ISA fosse o fator decisivo, isso não aconteceria nunca, em nenhum processo. O que derrubou a Intel foi gestão; o que a traz de volta é fab e foco; e o que separa Apple, Qualcomm, AMD e Intel é microarquitetura, cache, processo e integração — exatamente como o Jim Keller e a literatura sempre disseram.</p>
<p>Torço pela volta dela. Não por nostalgia de quem montou PC com Pentium, mas porque o mercado de laptops eficientes estava virando duopólio confortável — e duopólio confortável é inimigo de preço e de inovação. Que a briga continue.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> o Panther Lake encerra um debate teológico: x86 competitivo existe quando a fábrica é competitiva. O jogo nunca foi sobre instruções.</p>

</blockquote>
]]></content:encoded><category>hardware</category><category>reviews</category></item><item><title>Primeiras Impressões usando Oh-My-Pi e OpenCode</title><link>https://akitaonrails.github.io/2026/05/25/primeiras-impressoes-usando-oh-my-pi-e-opencode/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/05/25/primeiras-impressoes-usando-oh-my-pi-e-opencode/</guid><pubDate>Mon, 25 May 2026 01:00:00 -0300</pubDate><description>&lt;p&gt;&lt;img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/26/oh-my-pi-opencode/omp-hero.webp" alt="Imagem oficial do Oh-My-Pi: “A coding agent with the IDE wired in”, com o logo Pi em gradiente roxo e azul." loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;Toda vez que menciono harnesses de coding agent, aparece alguém perguntando: &amp;ldquo;mas por que você não usa Pi?&amp;rdquo; ou &amp;ldquo;por que não Oh-My-Pi?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;E eu odeio essa pergunta desse jeito.&lt;/p&gt;
&lt;p&gt;Não porque eu tenha alguma coisa contra Pi. Não tenho. O problema é que quase ninguém explica o &lt;strong&gt;porquê&lt;/strong&gt;. Qual é o benefício objetivo? Que problema ele resolve melhor que Claude Code ou OpenCode? Em que caso de uso ele é claramente superior? Qual limitação concreta ele remove?&lt;/p&gt;</description><content:encoded><![CDATA[<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/26/oh-my-pi-opencode/omp-hero.webp" alt="Imagem oficial do Oh-My-Pi: “A coding agent with the IDE wired in”, com o logo Pi em gradiente roxo e azul."  loading="lazy" /></p>
<p>Toda vez que menciono harnesses de coding agent, aparece alguém perguntando: &ldquo;mas por que você não usa Pi?&rdquo; ou &ldquo;por que não Oh-My-Pi?&rdquo;</p>
<p>E eu odeio essa pergunta desse jeito.</p>
<p>Não porque eu tenha alguma coisa contra Pi. Não tenho. O problema é que quase ninguém explica o <strong>porquê</strong>. Qual é o benefício objetivo? Que problema ele resolve melhor que Claude Code ou OpenCode? Em que caso de uso ele é claramente superior? Qual limitação concreta ele remove?</p>
<p>Normalmente não vem nada. Só vem nome de ferramenta. Isso me cheira a duas coisas: fanboy querendo validação da escolha que já fez, ou gente querendo terceirizar a lição de casa. &ldquo;Akita, testa aí e me diz se minha ferramenta favorita é boa.&rdquo; Não é exatamente o tipo de incentivo que me faz querer largar o que estou fazendo.</p>
<p>Mas testei mesmo assim. E, como eu esperava, não explodiu minha cabeça.</p>
<p>Antes de entrar em Pi, OpenCode e Oh-My-Pi, preciso alinhar vocabulário. Já expliquei isso em posts anteriores, especialmente em <a href="/2026/02/08/rant-ia-acabou-com-programadores/">&ldquo;RANT: IA acabou com os programadores?&rdquo;</a>, mas vale repetir porque muita gente ainda mistura tudo.</p>
<h2>O que é um harness de coding agent<span class="hx:absolute hx:-mt-20" id="o-que-é-um-harness-de-coding-agent"></span>
    <a href="#o-que-%c3%a9-um-harness-de-coding-agent" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Uma LLM pura não edita seu projeto. Ela recebe texto e devolve texto. Só isso.</p>
<p>Quando você abre Claude Code, Codex, OpenCode, Oh-My-Pi, Crush ou qualquer coisa parecida, você não está falando diretamente com &ldquo;o modelo&rdquo; de forma crua. Você está falando com um programa no meio. Esse programa monta o ambiente de trabalho da LLM.</p>
<p>Esse programa é o que eu chamo de <strong>harness</strong>. Em inglês, harness é arreio, correia, a coisa que prende e direciona um cavalo. A metáfora é boa: o modelo bruto é forte, mas sem arreio sai correndo pra qualquer lado.</p>
<p>O harness faz várias coisas:</p>
<ul>
<li>monta o <strong>system prompt</strong>, com as regras de comportamento;</li>
<li>lê arquivos de contexto como <code>AGENTS.md</code>, <code>CLAUDE.md</code>, regras locais, skills e documentação do projeto;</li>
<li>define quais <strong>tools</strong> a LLM pode chamar;</li>
<li>executa essas tools: ler arquivos, pesquisar texto, editar, rodar shell, rodar testes, abrir navegador, consultar LSP, chamar MCP;</li>
<li>coleta o resultado das tools e devolve pro modelo como novo contexto;</li>
<li>gerencia permissões, sandbox, confirmação de comandos perigosos;</li>
<li>controla plano de execução, lista de tarefas, subagentes em paralelo;</li>
<li>detecta contexto enchendo e dispara compaction;</li>
<li>tenta preservar memória entre turnos ou sessões;</li>
<li>decide como interromper, retomar ou redirecionar o agente quando você muda de ideia no meio do trabalho.</li>
</ul>
<p>Por isso dois CLIs usando o mesmo modelo podem se comportar diferente. Não é só &ldquo;GPT 5.5 vs Opus 4.7&rdquo;. É modelo <strong>mais</strong> harness. O harness decide que informação o modelo vê, que ferramentas ele sabe que existem, que formato de patch ele usa, como ele confirma ações, quando ele sumariza, quando ele chama subagente, quando ele para.</p>
<p>É essa camada que separa um chat com copy-paste manual de uma ferramenta que consegue mexer num projeto real.</p>
<h2>O problema dos planos subsidiados<span class="hx:absolute hx:-mt-20" id="o-problema-dos-planos-subsidiados"></span>
    <a href="#o-problema-dos-planos-subsidiados" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Eu já bati nessa tecla várias vezes: pra quem usa agentes muitas horas por dia, os planos subsidiados da Anthropic e da OpenAI são muito mais interessantes que pagar token avulso.</p>
<p>Pagar API direto é caro. Muito caro. Se você faz Agile Vibe Coding de verdade, deixa o agente rodando testes, lendo código, refatorando, compilando, reescrevendo, revisando, ele queima token como se fosse churrasco de fim de semana.</p>
<p>Plano mensal muda a conta. Você paga um valor fixo, ganha uma cota grande, e consegue trabalhar sem ficar calculando cada tool call como se fosse taxímetro.</p>
<p>O problema é que a Anthropic é bem rígida sobre onde esses planos podem ser usados. A própria documentação de <a href="https://code.claude.com/docs/en/legal-and-compliance"target="_blank" rel="noopener">Legal and compliance do Claude Code</a> diz que OAuth dos planos Free, Pro e Max é pra Claude Code e aplicações nativas da Anthropic, e que desenvolvedores terceiros devem usar API key via Claude Console ou cloud provider. Também diz explicitamente que a Anthropic não permite terceiros oferecerem login Claude.ai ou rotearem requests usando credenciais Free, Pro ou Max dos usuários.</p>
<p>Ou seja: existe hack pra fazer OpenCode, OpenClaw e outras ferramentas usarem o plano da Anthropic? Existe. O vazamento do Claude Code ajudou muita gente a entender como a autenticação e o transporte funcionavam. Escrevi sobre isso em <a href="/2026/03/31/codigo-fonte-do-claude-code-vazou-o-que-achamos-dentro/">&ldquo;O código fonte do Claude Code vazou. O que achamos dentro.&rdquo;</a>.</p>
<p>Mas eu não recomendo.</p>
<p>Pelo que tenho visto, a Anthropic continua aplicando a política. Você pode conseguir fazer funcionar hoje e amanhã tomar bloqueio. Pior: você pode perder uma conta que usa todo dia. Pra mim não vale o risco. Se quer usar Opus com plano Anthropic, use Claude Code. Ponto.</p>
<p>E, pra ser justo, Claude Code é um dos melhores harnesses que existem. Depois de centenas de horas usando, eu consigo elogiar sem dó:</p>
<ul>
<li>o modo de planejamento é bom;</li>
<li>a lista de tarefas é clara e o agente segue passo a passo;</li>
<li>dá pra interromper e redirecionar sem destruir a sessão;</li>
<li>dá pra injetar prompt enquanto ele trabalha;</li>
<li>a memória e a compaction são bem mais sofisticadas que as alternativas;</li>
<li>depois do vazamento, deu pra ver que não é só uma sumarização besta, tem várias camadas de gerenciamento de contexto.</li>
</ul>
<p>Expliquei a parte de memória com mais calma em <a href="/2026/05/18/memoria-agentes-karpathy-llm-wiki-agentmemory/">&ldquo;Memória de Agentes IA: Karpathy LLM Wiki e agentmemory na Prática&rdquo;</a>. O ponto lá: Claude Code investe muito em preservar o que importa quando o contexto enche. Codex e OpenCode fazem o suficiente. Claude Code vai além.</p>
<h2>Codex é o problema, não o GPT<span class="hx:absolute hx:-mt-20" id="codex-é-o-problema-não-o-gpt"></span>
    <a href="#codex-%c3%a9-o-problema-n%c3%a3o-o-gpt" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>OpenAI tem o Codex CLI pra usar com seus modelos. E aqui vou ser direto: Codex é um harness inferior.</p>
<p>Não estou dizendo que GPT 5.5 é ruim. Pelo contrário. O modelo é excelente. O problema é o arreio em volta dele.</p>
<p>O modo de plano do Codex é fraco perto do Claude Code. A interrupção é ruim: muitas vezes significa parar tudo, perder o fluxo e continuar manualmente. A organização de tarefas é mais frouxa. Mais de uma vez ele não terminou o que prometeu até eu mandar explicitamente &ldquo;termina isso direito&rdquo;. Parece ferramenta que ainda não decidiu se quer ser chat, executor, planner ou assistente de terminal.</p>
<p>É usável? Claro. Dá pra trabalhar? Dá. Mas a experiência é pior do que deveria ser.</p>
<p>A boa notícia é que não somos obrigados a usar Codex pra usar GPT. OpenCode existe. E, na prática, usando GPT 5.5 por OpenCode, eu sinto o modelo muito menos nerfado. O harness deixa o modelo trabalhar melhor.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/26/oh-my-pi-opencode/opencode.webp" alt="OpenCode 1.15.10 rodando GPT-5.5 num review de código, com sidebar mostrando contexto, MCP ai-memory conectado, lista de tarefas e arquivos modificados."  loading="lazy" /></p>
<p>OpenCode também documenta que dá pra conectar provedores e usar assinaturas em alguns casos. Na página de <a href="https://opencode.ai/docs/providers/"target="_blank" rel="noopener">Providers</a>, eles mesmos avisam que Anthropic proíbe uso de Claude Pro/Max em terceiros, mas listam assinaturas como ChatGPT Plus, GitHub Copilot e GitLab Duo como suportadas no OpenCode. A interface muda de versão pra versão, às vezes você vê <code>/connect</code>, às vezes o pessoal fala em <code>/login</code>, mas a ideia é a mesma: OAuth do plano é diferente de API key. API key é crédito por token. OAuth é usar a assinatura.</p>
<p>Então minha recomendação prática hoje é simples:</p>
<ul>
<li>Quer usar Opus 4.7 subsidiado? Use Claude Code.</li>
<li>Quer usar GPT 5.5 subsidiado? Use OpenCode.</li>
<li>Quer usar GPT 5.5 via Codex? Pode, mas na minha opinião está nerfando o modelo com um harness pior.</li>
</ul>
<p>Se a OpenAI fosse esperta, eu sinceramente largaria Codex CLI e adotaria OpenCode como base. Ou pelo menos copiaria sem vergonha o que OpenCode faz bem. Codex não tem nenhuma vantagem objetiva pra mim hoje.</p>
<h2>E onde entra Pi?<span class="hx:absolute hx:-mt-20" id="e-onde-entra-pi"></span>
    <a href="#e-onde-entra-pi" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Agora sim, Pi.</p>
<p>Pi é um harness minimalista. Dá pra usar sozinho, mas pra mim é como abrir NeoVim sem plugin nenhum. Sim, funciona. Sim, tem gente que ama montar tudo do zero. Sim, você aprende bastante fazendo isso.</p>
<p>Mas eu não recomendo como ponto de partida pra quem só quer trabalhar.</p>
<p>Oh-My-Pi é um fork baseado em Bun, com &ldquo;baterias inclusas&rdquo;. E, claro, já existe polarização: extremista de Pi diz que Oh-My-Pi é inchado, que o certo é usar Pi puro, montar suas ferramentas, compor sua própria distro, configurar tudo no braço.</p>
<p>Isso me lembra NeoVim. Eu gosto de NeoVim. Mas eu não quero gastar minha vida escolhendo plugin de statusline, configurando LSP na unha, ajustando keymap de árvore de arquivos e comparando 12 fuzzy finders. Instalo LazyVim e pronto. Quando eu quiser estudar internals, estudo. Quando quero entregar trabalho, uso o pacote que funciona.</p>
<p>Pra mim, Oh-My-Pi ocupa esse lugar. Se você tem curiosidade por Pi, comece pelo Oh-My-Pi. Se gostar, se sentir vontade, aí vá pro Pi minimalista e construa sua própria distribuição. Vai fundo. Só não finja que isso é objetivamente melhor pra todo mundo.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/26/oh-my-pi-opencode/omp.webp" alt="Oh-My-Pi v15.2.4 abrindo com GPT-5.5, lista de LSP servers detectados e o prompt inicial colado no terminal."  loading="lazy" /></p>
<p>Minha primeira impressão do Oh-My-Pi é que ele funciona. Não é ruim. Também não me fez dizer &ldquo;nossa, como vivi sem isso até hoje?&rdquo;</p>
<p>Out of the box achei verboso demais. Tenho certeza de que dá pra customizar, mas aqui mora a toca do coelho. Eu não quero passar a tarde tunando prompt, tema, modo de exibição, tamanho de painel, política de tool e sei lá mais o quê. Deixei default.</p>
<p>Em uso normal, ele lembra bastante OpenCode. Ambos conseguem trabalhar com plano, tarefas, tools, subagentes, LSP, compaction, interrupção e steering. Ambos são superiores ao Codex como harness. Isso já basta pra eu levar a sério.</p>
<p>Mas OpenCode parece mais coeso. Mais produto. Mais polido. O Oh-My-Pi parece mais laboratório de gente que gosta de ferramenta poderosa e cheia de knobs. Isso pode ser elogio ou crítica, dependendo do tipo de pessoa que você é.</p>
<h2>O que eu fui checar no código<span class="hx:absolute hx:-mt-20" id="o-que-eu-fui-checar-no-código"></span>
    <a href="#o-que-eu-fui-checar-no-c%c3%b3digo" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra não ficar só em impressão visual, pedi uma análise comparando OpenCode, Pi e Oh-My-Pi, e depois conferi partes do código-fonte.</p>
<p>O resultado bate com a intuição.</p>
<h3>Pi upstream<span class="hx:absolute hx:-mt-20" id="pi-upstream"></span>
    <a href="#pi-upstream" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O Pi original é pequeno. O conjunto de tools embutidas é basicamente:</p>
<ul>
<li><code>read</code></li>
<li><code>bash</code></li>
<li><code>edit</code></li>
<li><code>write</code></li>
<li><code>grep</code></li>
<li><code>find</code></li>
<li><code>ls</code></li>
</ul>
<p>Isso é limpo. Eu gosto de código limpo. Mas como harness moderno pra programação pesada, sozinho, não compete com OpenCode ou Oh-My-Pi.</p>
<p>De novo: não quer dizer que é inútil. Quer dizer que é base minimalista. Se você quer montar sua própria distribuição de agente, ótimo. Se quer abrir e trabalhar hoje, é pouco.</p>
<h3>OpenCode<span class="hx:absolute hx:-mt-20" id="opencode"></span>
    <a href="#opencode" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>OpenCode tem o kit normal e competente pra programação:</p>
<ul>
<li>shell;</li>
<li>read;</li>
<li>glob;</li>
<li>grep;</li>
<li>edit/write ou apply_patch;</li>
<li>task/subagentes;</li>
<li>todo;</li>
<li>web fetch/search;</li>
<li>skills;</li>
<li>LSP opcional;</li>
<li>plugins e MCP.</li>
</ul>
<p>O <code>read</code> dele cobre o que eu espero num projeto de código: arquivo-fonte, diretório, imagem suportada e PDF. Tem LSP. Tem task. Tem todo. Não tenta ser o canivete suíço de todo artefato possível.</p>
<p>Pra software normal, isso resolve. Pra um projeto que mistura banco SQLite, planilhas, notebooks, PDFs, arquivos compactados e páginas web, aí começa a aparecer a diferença.</p>
<h3>Oh-My-Pi<span class="hx:absolute hx:-mt-20" id="oh-my-pi"></span>
    <a href="#oh-my-pi" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Oh-My-Pi vem com mais tools. Bem mais. No registry dele aparecem coisas como:</p>
<ul>
<li><code>read</code></li>
<li><code>bash</code></li>
<li><code>edit</code></li>
<li><code>ast_grep</code></li>
<li><code>ast_edit</code></li>
<li><code>ask</code></li>
<li><code>debug</code></li>
<li><code>eval</code></li>
<li><code>find</code></li>
<li><code>search</code></li>
<li><code>lsp</code></li>
<li><code>inspect_image</code></li>
<li><code>browser</code></li>
<li><code>task</code></li>
<li><code>job</code></li>
<li><code>recipe</code></li>
<li><code>irc</code></li>
<li><code>todo_write</code></li>
<li><code>web_search</code></li>
<li><code>write</code></li>
<li>ferramentas de memória/hindsight</li>
</ul>
<p>A vantagem mais clara é o <code>read</code>.</p>
<p>No Oh-My-Pi, uma única tool <code>read</code> entende arquivos, diretórios, archives (<code>.tar</code>, <code>.tar.gz</code>, <code>.tgz</code>, <code>.zip</code>), SQLite, imagens, documentos (<code>PDF</code>, <code>DOCX</code>, <code>PPTX</code>, <code>XLSX</code>, <code>RTF</code>, <code>EPUB</code>), notebooks Jupyter (<code>.ipynb</code>), URLs em modo reader, e URIs internas como <code>skill://</code>, <code>agent://</code>, <code>artifact://</code>, <code>memory://</code>, <code>rule://</code>, <code>local://</code>, <code>mcp://</code>.</p>
<p>Aqui ele ganha de verdade quando o trabalho depende desses formatos.</p>
<p>Exemplo: projeto Rails com SQLite local. Em OpenCode, o agente provavelmente vai tentar usar <code>sqlite3</code> via shell, ou escrever script, ou você vai ter que instruir. No Oh-My-Pi, o próprio prompt da tool ensina:</p>
<ul>
<li><code>file.db</code> lista tabelas e contagem de linhas;</li>
<li><code>file.db:table</code> mostra schema e amostras;</li>
<li><code>file.db:table:key</code> pega uma linha por chave primária;</li>
<li><code>file.db:table?limit=50&amp;offset=100</code> pagina;</li>
<li><code>file.db:table?where=status='active'&amp;order=created:desc</code> filtra;</li>
<li><code>file.db?q=SELECT ...</code> roda <code>SELECT</code> read-only.</li>
</ul>
<p>Isso importa. Claro que um humano consegue fazer com shell. Mas o modelo não precisa inventar o comando, não precisa depender de <code>sqlite3</code> instalado, não precisa errar escaping, não precisa despejar 30 mil linhas no contexto. O caminho certo já está descrito dentro da tool, visível pro modelo.</p>
<p>Mesma coisa pra ZIP, PDF, planilha, notebook. Se seu projeto é só TypeScript, Ruby, Go e Markdown, tanto faz. Se seu projeto é data science, investigação, auditoria, análise de documentos, migração de banco, parsing de artefatos, aí Oh-My-Pi começa a fazer mais sentido.</p>
<h2>A vantagem em código-fonte puro é menor<span class="hx:absolute hx:-mt-20" id="a-vantagem-em-código-fonte-puro-é-menor"></span>
    <a href="#a-vantagem-em-c%c3%b3digo-fonte-puro-%c3%a9-menor" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra source code comum, a diferença existe, mas não é gigantesca.</p>
<p>Oh-My-Pi tem algumas conveniências boas:</p>
<ul>
<li>leitura de código com resumo estrutural quando o arquivo é parseável;</li>
<li>leitura por múltiplos ranges numa chamada só;</li>
<li>anchors com hash de linha, que deixam edição textual mais segura;</li>
<li>roteamento mais agressivo pra LSP;</li>
<li>tools de AST (<code>ast_grep</code> e <code>ast_edit</code>);</li>
<li>prompt de sistema insistindo pra usar a ferramenta especializada em vez de cair no shell.</li>
</ul>
<p>A parte de AST merece explicar.</p>
<p><code>grep</code> e <code>rg</code> procuram texto. AST procura estrutura sintática. Em vez de buscar a string <code>console.log</code>, você pode procurar uma chamada <code>console.log($$$)</code> e ignorar espaços, quebra de linha, comentários, formatação. Em vez de fazer replace textual de import, você pode reescrever um nó de import. Em vez de caçar <code>foo &amp;&amp; foo()</code> como texto, pode transformar estruturalmente em <code>foo?.()</code> garantindo que o mesmo metavariável aparece dos dois lados.</p>
<p>Isso é útil em codemod. É útil quando você quer alterar chamadas de função, imports, declarações, padrões de erro, sem pegar falso positivo em string, comentário ou documentação.</p>
<p>Mas não é mágica. AST pattern é sensível. O modelo pode errar o formato. Às vezes precisa ajustar a query. Pra refactor grande, LSP rename ainda é mais correto que AST se a linguagem suporta. AST é uma ferramenta a mais, não uma religião.</p>
<p>OpenCode não fica indefeso sem isso. Ele tem grep, edit, apply_patch, LSP opcional, task, todo. Pra 90% das tarefas comuns de código, isso resolve.</p>
<p>Minha leitura, depois de olhar o código, é simples: quando o trabalho envolve SQLite, notebook, documento, archive, imagem, URL ou artefato interno, Oh-My-Pi tem uma vantagem real. Em código-fonte puro, a vantagem aparece mais em refactor grande, navegação por tipo, busca estrutural e codemod. Pra edição normal de código, OpenCode continua tão bom quanto e costuma ser mais agradável.</p>
<h2>Prompt também é ferramenta<span class="hx:absolute hx:-mt-20" id="prompt-também-é-ferramenta"></span>
    <a href="#prompt-tamb%c3%a9m-%c3%a9-ferramenta" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Uma coisa que muita gente ignora: não basta existir tool. A LLM precisa saber quando usar.</p>
<p>O prompt do Oh-My-Pi é bem explícito. Ele manda usar ferramentas quando melhoram corretude, paralelizar chamadas quando fizer sentido, preferir LSP pra operações de símbolo, preferir AST pra busca estrutural e codemod, preferir <code>read</code>/<code>search</code>/<code>find</code> em vez de shell, delegar pra subagentes quando o trabalho é decomponível.</p>
<p>Isso ajuda modelos grandes. Opus e GPT 5.5 obedecem bem esse tipo de instrução quando a descrição da tool é clara.</p>
<p>O OpenCode não fica devendo no básico. Ele ensina <code>Read</code>, <code>Glob</code>, <code>Grep</code>, <code>Edit</code>, <code>Write</code>, <code>Bash</code>, <code>Task</code>, patch. Dá conta do fluxo normal. A diferença é que ele não empurra LSP e ferramentas avançadas com a mesma insistência do Oh-My-Pi.</p>
<p>Pi upstream é minimalista também no prompt. Lista tools, dá guidelines, mas não faz roteamento pesado. De novo: bom pra quem quer base pequena. Menos bom pra quem quer harness cheio de conveniência pronta.</p>
<h2>Memória, plano, interrupção<span class="hx:absolute hx:-mt-20" id="memória-plano-interrupção"></span>
    <a href="#mem%c3%b3ria-plano-interrup%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui Oh-My-Pi e OpenCode ficam mais parecidos.</p>
<p>Ambos têm compaction de contexto. Ambos têm algum modo de plano/todo. Ambos conseguem spawnar subagentes. Ambos permitem steering, isto é, você não precisa tratar a lista de tarefas como escritura sagrada. Se o agente começou a fazer besteira, você interrompe, injeta novo prompt, muda direção.</p>
<p>Isso é obrigatório pra Agile Vibe Coding. Sem steering decente, a ferramenta vira esteira rolante: começou errado, continua errado até bater na parede. Claude Code é muito bom nisso. Oh-My-Pi e OpenCode chegam perto o bastante. Codex, na minha experiência, não.</p>
<p>No Oh-My-Pi, olhando configuração, existem knobs explícitos pra <code>steeringMode</code>, <code>interruptMode</code> e <code>compaction.strategy</code>. Essa é a cara dele: expor comportamento do harness como configuração. Poderoso, mas também mais uma toca de coelho.</p>
<p>OpenCode tende a esconder mais disso e entregar um produto mais fechado. Eu gosto desse trade-off pro dia a dia.</p>
<h2>Mas o Pi não tem mais agentes?<span class="hx:absolute hx:-mt-20" id="mas-o-pi-não-tem-mais-agentes"></span>
    <a href="#mas-o-pi-n%c3%a3o-tem-mais-agentes" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Outro argumento que aparece: &ldquo;mas no Pi dá pra spawnar muito mais agentes&rdquo;.</p>
<p>E daí?</p>
<p>Ter mais agentes disponíveis não significa que a tarefa ficou mais paralelizável. Programação é difícil de paralelizar pelo mesmo motivo que gerenciar time de programadores é difícil: quase sempre existe um caminho crítico. Você consegue dividir alguma coisa, claro, mas logo chega num ponto em que uma decisão depende da anterior, que depende de um detalhe que só apareceu depois de rodar o teste, que muda a arquitetura, que invalida metade do plano original.</p>
<p>LLM com subagente sofre da mesma física. Agente A precisa saber o que agente B decidiu. Agente C implementa em cima de uma API que agente A ainda está mudando. O agente principal precisa consolidar tudo, detectar conflito, pedir correção, reler diff, rodar teste, mandar outro patch. A partir de certo ponto, você não está paralelizando. Está inventando gerência.</p>
<p>Eu já demonstrei 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>. Rodei variações com planner forte, executor barato, delegação livre, delegação forçada, orquestração manual. O resultado foi chato: em coding agent contínuo, o overhead de coordenação come o ganho. Quando não forcei delegação, os modelos Tier A simplesmente não delegaram. Quando forcei, a qualidade caiu ou o tempo aumentou. No melhor caso, empatou custando mais coordenação.</p>
<p>Isso não é bug. É bom senso do modelo.</p>
<p>Numa tarefa coesa, o modelo bom percebe que precisa manter o raciocínio no mesmo contexto. Design e implementação se misturam. Você planeja, escreve, testa, descobre que uma premissa estava errada, ajusta, volta, simplifica. Separar isso artificialmente em 10 agentes só cria mais borda pra dar ruim.</p>
<p>Tarefas realmente paralelizáveis existem. Traduzir um arquivo enorme de strings pra 10 idiomas? Beleza. Um agente por idioma. Converter 200 imagens pra WebP? Pode paralelizar. Aplicar o mesmo refactor mecânico em 50 arquivos independentes? Talvez. O resultado de um item não muda o outro.</p>
<p>Mas quantas tarefas do seu dia a dia são assim?</p>
<p>Eu não vi o Oh-My-Pi paralelizar mais que OpenCode ou Claude Code em programação normal. E isso é o correto. Se ele saísse abrindo agente pra tudo, eu desconfiaria. Ia gastar tempo, contexto e token consolidando trabalho duplicado.</p>
<p>Então não: misturar modelos, misturar agentes ad hoc, aumentar o número mágico de workers, nada disso resolve programação difícil. Resolve lote independente. E lote independente é a parte fácil.</p>
<h2>Mas o Pi não economiza mais tokens?<span class="hx:absolute hx:-mt-20" id="mas-o-pi-não-economiza-mais-tokens"></span>
    <a href="#mas-o-pi-n%c3%a3o-economiza-mais-tokens" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Outro mito: como Pi é mais customizável, você controla system prompt de cada componente, então dá pra minimizar tudo e economizar tokens contra OpenCode, Codex ou Claude Code, que começam com prompts maiores.</p>
<p>Você está economizando centavos e perdendo dólares.</p>
<p>O prompt inicial não é onde a maior parte do gasto acontece num coding agent sério. O gasto vem do trabalho: ler código, escrever código, rodar teste, receber stack trace, ler log, reler arquivo, aplicar patch, rodar teste de novo. Um ou dois logs verbosos já comem a janela inteira de um modelo local pequeno com 30K tokens. Um <code>bundle exec</code>, um <code>npm test</code>, um build de frontend cuspindo warning, pronto: lá se foi sua economia heroica de system prompt.</p>
<p>Minha regra pessoal: eu não tentaria usar coding agent sério com menos de 200K tokens de contexto. Abaixo disso, o harness precisa compactar memória toda hora. Compaction ajuda, mas sempre perde detalhe. Perde o warning que apareceu antes do erro. Perde a decisão tomada meia hora atrás. Perde o trecho do stdout que parecia ruído mas era a pista.</p>
<p>Com menos de 100K, pra mim, é basicamente inutilizável pra sessão longa de programação. Você não consegue deixar o agente ler log grande, output de teste, stdout de build, diff comprido. Volta pro trabalho idiota de ficar escolhendo manualmente o que cabe no contexto. Isso é o oposto de produtividade. É você virando assistente do assistente.</p>
<p>Por isso eu recomendo frontier models. Opus e GPT têm janelas na faixa de 1 milhão de tokens, e isso importa em sessão longa. Dá pra deixar o harness trabalhar sem tratar cada log como contrabando. Dá pra manter detalhes recentes por mais tempo antes da próxima compaction. A resposta melhora porque o modelo ainda tem os fatos na frente dele.</p>
<p>Esse é um motivo grande pra eu não recomendar LLM open source local pra programação séria. Não é só qualidade do modelo. É KV cache. Não existe GPU de consumidor com VRAM sobrando pra contexto gigante em modelo grande. Mesmo num Mac Studio parrudo, na prática, você mal chega perto de algo como 300K antes de começar a sacrificar memória e desempenho. Ainda está longe de 1 milhão.</p>
<p>Nesse ponto, a comparação de preço muda. Mesmo pagando por token, muitas vezes compensa. E se quiser economizar, use um modelo cloud de geração anterior, tipo Kimi K2.6. No <a href="/2026/04/24/llm-benchmarks-parte-3-deepseek-kimi-mimo/">meu benchmark</a>, ele continua muito melhor que qualquer open source local que testei. Sai barato e você não precisa fingir que 30K de contexto é ambiente sério de desenvolvimento.</p>
<p>Pior: se você tenta economizar token manualmente, você quebra o fluxo certo.</p>
<p>O jeito errado é deixar o harness sugerir comando, copiar pro seu terminal, rodar você mesmo, pegar só um pedaço do output, colar de volta no chat e torcer pra ter escolhido o pedaço relevante. Isso economiza token e destrói contexto. O modelo fica cego justamente na parte que importa: o erro inteiro, a ordem dos eventos, o warning anterior, o path real, a diferença entre stdout e stderr, o comando exato que rodou.</p>
<p>O jeito certo é deixar o harness rodar. Sim, ele vai mandar output pro contexto. Sim, custa. Mas é assim que o modelo tem informação suficiente pra escolher o próximo passo. Quanto mais contexto real e verificável ele tem, melhor a chance de corrigir certo na próxima iteração.</p>
<p>É por isso que eu insisto nos planos subsidiados. Se você paga por token avulso, fica tentado a dirigir com o freio de mão puxado. Se você está num plano Pro/Max/Plus, use a ferramenta direito. Deixa rodar teste. Deixa ler log. Deixa abrir arquivo. Deixa o agente trabalhar.</p>
<p>E, por favor, não perca tempo tentando transformar Qwen local no seu programador principal porque &ldquo;é grátis&rdquo;. Eu já testei isso no benchmark canônico <a href="/2026/04/24/llm-benchmarks-parte-3-deepseek-kimi-mimo/">&ldquo;Benchmark de LLMs pra Coding: DeepSeek, Kimi, MiMo, GPT&rdquo;</a>. Os modelos open source locais ficaram Tier C ou pior. Qwen local é legal pra laboratório, demo, curiosidade, estudo. Pra programação séria com tool calling longo, contexto grande, testes e refactor, ainda não é substituto pra Claude ou GPT.</p>
<p>Se você não consegue pagar US$100 por mês numa ferramenta que pode multiplicar sua produtividade por 5 ou 10, o problema não é token. É ROI. É carreira. É o tipo de trabalho que você está fazendo.</p>
<p>Ficar tunando Pi pra economizar migalha de token não é seu ticket pra ganhar melhor. Entregar mais, com mais qualidade, usando ferramenta boa, é.</p>
<h2>Pi é melhor que OpenCode?<span class="hx:absolute hx:-mt-20" id="pi-é-melhor-que-opencode"></span>
    <a href="#pi-%c3%a9-melhor-que-opencode" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Eu tentei uma comparação prática. Peguei o mesmo PR, <a href="https://github.com/akitaonrails/ai-memory/pull/10"target="_blank" rel="noopener">akitaonrails/ai-memory#10</a>, e pedi review pra três combinações:</p>
<ul>
<li>Oh-My-Pi com GPT 5.5;</li>
<li>OpenCode com GPT 5.5;</li>
<li>Claude Code com Opus 4.7.</li>
</ul>
<p>Mesmo PR. Mesmo tipo de pedido. Mesma intenção: achar problemas reais antes de merge.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/26/oh-my-pi-opencode/review-omp.webp" alt="Oh-My-Pi com GPT-5.5 revisando o PR #10 e concluindo que pegou só parte dos problemas: temperatura em modelos GPT-5/o-series, mismatch de comentário em required e cap de GPT-4 Turbo, mas deixando outras divergências de fora."  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/26/oh-my-pi-opencode/review-opencode.webp" alt="OpenCode com GPT-5.5 revisando o mesmo PR #10, concordando em pedir mudanças e acrescentando um problema que a primeira passada tinha perdido sobre OpenAiCompatProvider reaproveitar comportamento de OpenAiProvider."  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/26/oh-my-pi-opencode/review-claude.webp" alt="Claude Code com Opus 4.7 revisando o PR #10, listando problemas em temperatura, additionalProperties, vazamento de comportamento OpenAI para compat providers e dry-run vazio."  loading="lazy" /></p>
<p>Nenhum achou tudo.</p>
<p>Pra simplificar, imagine que os problemas do PR eram A, B, C e D. Oh-My-Pi achou A e B. OpenCode achou B e C. Claude achou C e D. Não foi exatamente essa a matriz, mas a ideia é essa: cada um pegou uma parte. Cada um perdeu uma parte.</p>
<p>Isso é o que eu vivo repetindo: não confie em uma única LLM pra auditar nada importante. Ela vai achar <strong>alguns</strong> problemas. Talvez bons problemas. Talvez problemas que você não viu. Mas não existe garantia de cobertura completa. Depende do contexto que ela leu, de como você perguntou, de que arquivos ela abriu, de que tool ela decidiu usar, do caminho que o raciocínio tomou.</p>
<p>O detalhe interessante: o mesmo GPT 5.5 deu respostas diferentes em dois harnesses diferentes. Oh-My-Pi e OpenCode não viraram clones só porque usaram o mesmo modelo. O harness muda prompt, tools, formato de contexto, ordem das coisas, pressão pra usar LSP ou AST, tudo. Isso muda o caminho.</p>
<p>Nesse caso específico, eu diria que Oh-My-Pi e OpenCode empataram. Ambos acharam problemas reais. Ambos deixaram passar problemas reais. Claude ficou um pouco pior porque em uma passagem chegou mais perto de dizer que o PR era mergeável quando ainda tinha coisa faltando. Mas isso também não prova que Claude é pior. Numa segunda passada, com prompt diferente, poderia inverter.</p>
<p>O ponto não é coroar vencedor. É matar a fantasia.</p>
<p>Pi não tem uma magia escondida que transforma review em auditoria perfeita. Oh-My-Pi é um harness muito bom. OpenCode também. Claude Code também. Todos erram. Todos dependem do modelo, do contexto e do pedido. Por isso eu não sei se preferiria Oh-My-Pi a OpenCode ou Claude Code como ferramenta principal. Ele entra na mesma prateleira: excelente, útil, mas não milagroso.</p>
<p>Mais uma anedota, sem virar prova de nada. Enquanto eu editava este post no Oh-My-Pi, pedi uma mudança localizada. Com Claude Code e OpenCode, quando peço isso num post bilíngue, normalmente eles alteram o trecho em PT-BR e o trecho equivalente em EN, só naquele range. O Oh-My-Pi fez metade certo: editou o PT-BR no lugar certo. Mas no EN decidiu retraduzir o arquivo inteiro do zero. Não sei por quê.</p>
<p>É só um caso. Não prova incompetência. Mas é curioso porque justamente derruba a fantasia de que Pi sempre economiza token. Nessa rodada, ele gastou muito mais. Eu nunca vi Claude Code ou OpenCode retraduzirem o post inteiro quando eu pedi uma edição pequena; eles costumam ser bons em mexer só no pedaço pedido.</p>
<p>Minha primeira impressão é que o OMP realmente tem mais tools e se esforça pra usá-las. Talvez até demais. Às vezes eu fico com a sensação de que ele força tooling em tarefa onde OpenCode e Claude Code seriam mais diretos ao ponto, e isso quase começa a piorar a resposta em vez de ajudar. Pode ser só impressão inicial, mas a sensação até aqui é essa: o OMP às vezes tenta demais pro próprio bem.</p>
<h2>Então qual eu usaria?<span class="hx:absolute hx:-mt-20" id="então-qual-eu-usaria"></span>
    <a href="#ent%c3%a3o-qual-eu-usaria" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se o assunto é programação normal, eu continuaria alternando entre Claude Code e OpenCode.</p>
<p>Claude Code quando quero usar Opus e o plano Anthropic. OpenCode quando quero usar GPT 5.5 e não sofrer com Codex. Simples.</p>
<p>Oh-My-Pi eu colocaria na caixa de ferramentas, não como substituto obrigatório. Eu escolheria Oh-My-Pi quando o projeto tivesse muita coisa fora de source code:</p>
<ul>
<li>PDFs que precisam ser lidos;</li>
<li>planilhas;</li>
<li>SQLite;</li>
<li>notebooks Jupyter;</li>
<li>ZIPs e tarballs;</li>
<li>imagens;</li>
<li>páginas web que precisam virar texto;</li>
<li>artefatos internos de outras execuções;</li>
<li>necessidade de AST codemod com mais frequência.</li>
</ul>
<p>Talvez em projeto de data science ele brilhe mais. Talvez em investigação de dados. Talvez em auditoria, migração, pesquisa com documentos, ferramenta interna cheia de SQLite e CSV e XLSX. Nesses cenários, a tool <code>read</code> universal é muito conveniente.</p>
<p>Pra CRUD Rails, backend Go, frontend TypeScript, CLI Rust, blog Hugo? OpenCode é tão bom quanto e mais polido.</p>
<p>E Pi puro? Eu só usaria se minha diversão fosse montar o harness em si. Nada errado com isso. Só não vou fingir que é o caminho pra quem quer terminar trabalho hoje.</p>
<h2>Minha recomendação atual<span class="hx:absolute hx:-mt-20" id="minha-recomendação-atual"></span>
    <a href="#minha-recomenda%c3%a7%c3%a3o-atual" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se você quer uma resposta curta:</p>
<ul>
<li>Use <strong>Claude Code</strong> com <strong>Opus 4.7</strong> se você quer o melhor harness proprietário e pode ficar dentro do ecossistema Anthropic.</li>
<li>Use <strong>OpenCode</strong> com <strong>GPT 5.5</strong> se você quer usar o plano da OpenAI sem se prender ao Codex.</li>
<li>Use <strong>Oh-My-Pi</strong> se você quer um harness mais flexível, com mais tools, especialmente pra projetos com arquivos e artefatos variados.</li>
<li>Evite <strong>Codex</strong> se você tem alternativa. O modelo é bom. O harness atrapalha.</li>
<li>Use <strong>Pi</strong> puro se você gosta de montar sua própria distro. Como ferramenta de trabalho imediata, eu começaria pelo Oh-My-Pi.</li>
</ul>
<p>A analogia com Linux ajuda. Eu não uso Linux porque é &ldquo;grátis&rdquo;. Uso porque, pra mim, é a melhor ferramenta pro trabalho. As alternativas não chegam perto no meu fluxo. Mas isso não quer dizer que todo iniciante deveria largar Windows ou macOS amanhã e montar Arch na unha.</p>
<p>Mesma coisa com editor. NeoVim é tecnicamente fantástico. Eu adoro. Mas existe um motivo pra ele não ser tão mainstream quanto VS Code: não é produtivo no primeiro dia, a não ser que você já tenha experiência e tenha aprendido aos poucos. Se você precisa de produtividade agora, usa a ferramenta mais fácil que funciona out of the box. VS Code, Cursor, Windsurf, JetBrains, o que for. Entrega primeiro. Tweaka depois.</p>
<p>E olha que eu nem sou o cara de ficar fazendo rice de NeoVim o dia inteiro. Eu prefiro NeoVim porque as capacidades de edição são superiores às do VS Code, e porque gosto de ficar 100% no terminal. Editor GUI como VS Code ou Zed não me dá esse fluxo. Uso o mesmo editor localmente ou via SSH, combino com Tmux ou Zellij, rodo tudo em terminal moderno tipo Kitty, Ghostty ou Alacritty, e sou produtivo assim.</p>
<p>Nesse ponto, harness de LLM combina comigo. Oh-My-Pi, OpenCode e Claude Code já são terminal-based. Qualquer um deles encaixa bem no meu fluxo.</p>
<p>Pi cai nessa categoria. É NeoVim. Tecnicamente ótimo, elegante pra quem gosta de montar a própria oficina, mas não é a escolha certa pra todo mundo. É ferramenta pra quem gosta de tunar, entende o custo disso, e aceita passar tempo ajustando o harness como parte do hobby ou do trabalho. Pra maioria, comece pelo pacote que funciona.</p>
<p>Ou seja: Oh-My-Pi e OpenCode são bons. Escolha um e trabalhe. Não tem religião aqui.</p>
<p>O que me irrita é fanboy vendendo nome de ferramenta como se fosse argumento. &ldquo;Usa Pi&rdquo; não significa nada. Me diga o que ele resolve melhor. Me diga onde economiza tempo. Me diga que bug real ele evita. Me diga que fluxo fica impossível no Claude Code ou no OpenCode e trivial no Pi.</p>
<p>Aí sim temos conversa.</p>
<p>Até agora, minha leitura é chata: pra desenvolvimento de software normal, Oh-My-Pi e OpenCode performam parecido quando usam o mesmo modelo. Oh-My-Pi tem mais ferramentas e é mais flexível. OpenCode é mais coeso e polido. Claude Code continua sendo a régua quando o assunto é Opus. Codex continua sendo a opção que eu só usaria se não tivesse escolha.</p>
<p>Ferramenta ajuda. Harness importa. Mas quem ganha ainda é processo: prompt pequeno, escopo claro, teste rodando, revisão cuidadosa, commit frequente, engenharia de verdade.</p>
]]></content:encoded><category>agentes-de-codigo</category><category>reviews</category></item><item><title>Omarchy no Thinkpad T14 Gen 6: Mini-Review e Setup Completo</title><link>https://akitaonrails.github.io/2026/04/18/omarchy-no-thinkpad-t14-gen-6/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/04/18/omarchy-no-thinkpad-t14-gen-6/</guid><pubDate>Sat, 18 Apr 2026 08:30:00 -0300</pubDate><description>&lt;p&gt;&lt;img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/closed-lid.jpg" alt="Thinkpad T14 Gen 6 fechado ao lado do carregador USB-C" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;Comprei um Lenovo Thinkpad T14 Gen 6 e instalei Omarchy em cima. Não é minha máquina principal, nem pretende ser. É companion: um notebook pra abrir em cima da mesa do escritório de impressão 3D, dar um SSH no desktop, chamar Claude Code, acessar arquivos no NAS, debugar rede pelo ethernet sem ficar procurando adaptador USB e cabo longo. Esse artigo cobre a escolha do hardware, o setup de Omarchy em cima, as customizações específicas pra notebook e pra esse Thinkpad em particular, e as decisões de arquitetura que podem não ser óbvias.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/closed-lid.jpg" alt="Thinkpad T14 Gen 6 fechado ao lado do carregador USB-C"  loading="lazy" /></p>
<p>Comprei um Lenovo Thinkpad T14 Gen 6 e instalei Omarchy em cima. Não é minha máquina principal, nem pretende ser. É companion: um notebook pra abrir em cima da mesa do escritório de impressão 3D, dar um SSH no desktop, chamar Claude Code, acessar arquivos no NAS, debugar rede pelo ethernet sem ficar procurando adaptador USB e cabo longo. Esse artigo cobre a escolha do hardware, o setup de Omarchy em cima, as customizações específicas pra notebook e pra esse Thinkpad em particular, e as decisões de arquitetura que podem não ser óbvias.</p>
<h2>Mini-review do Thinkpad T14 Gen 6<span class="hx:absolute hx:-mt-20" id="mini-review-do-thinkpad-t14-gen-6"></span>
    <a href="#mini-review-do-thinkpad-t14-gen-6" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/open-lid-turned-off.jpg" alt="Thinkpad T14 Gen 6 aberto, tela desligada, mostrando o teclado e o selo do Intel Core Ultra 5"  loading="lazy" /></p>
<p>Vamos tirar do caminho: esse não é o notebook dos sonhos. Se eu fosse escolher por estética, pegaria um Asus Zenbook S 14 com tela OLED. Se fosse por portabilidade, o Thinkpad T14s com casca de alumínio, que é mais leve e muito mais bonito. O T14 regular tem tela IPS 1920x1200 de 14&quot;, 400 nits, 60Hz, sem HDR. Dá pro gasto, mas está longe da tela do Zenbook. A casca é de plástico com um acabamento emborrachado, o que deixa ele resistente a arranhão, mas não é premium. Revisões da <a href="https://www.notebookcheck.net/AMD-Ryzen-AI-meets-classic-ThinkPad-Lenovo-ThinkPad-T14-Gen-6-AMD-laptop-review.1222690.0.html"target="_blank" rel="noopener">NotebookCheck</a> e da <a href="https://www.xda-developers.com/lenovo-thinkpad-t14-gen-6-review/"target="_blank" rel="noopener">XDA Developers</a> batem na mesma tecla: bom custo, boa conectividade, desempenho adequado pra escritório, mas a tela é datada.</p>
<p>O que compensa:</p>
<ul>
<li>Seleção de portas. HDMI full-size. Ethernet gigabit. USB-A, USB-C Thunderbolt 4, carrega pelo USB-C (não é carregador proprietário). Pra um companion de debug, isso é exatamente o que eu queria. O Zenbook S 14, por ser mais fino, corta portas.</li>
<li>Sensor de digital funcional no Linux (Goodix MOC, funciona com libfprint em kernel 6.11+). Isso eu uso, detalho mais à frente.</li>
<li>Teclado Thinkpad. Curso de tecla de 1.5mm, trackpoint, layout clássico. Não é o melhor teclado do mundo em 2026, mas é confiável e durável.</li>
<li>Carcaça rugged. Vai cair, vai arranhar, vai viajar na mala. Se eu colocasse um Zenbook OLED ou um Macbook Pro em cima da mesa do escritório de impressão 3D, ao lado da impressora, com poeira de PLA voando, eu ficaria nervoso. O Thinkpad pode levar porrada.</li>
</ul>
<p>Se eu quisesse máquina de jogo, pegaria um Asus Zephyrus G14, meu favorito de notebook gamer. Se eu quisesse máquina de trabalho criativo, pegaria o <a href="https://www.asus.com/laptops/for-home/zenbook/zenbook-duo-ux8406/"target="_blank" rel="noopener">Asus Zenbook Duo (UX8406)</a> com duas telas OLED verticais, ótimo pra edição de vídeo e modelagem 3D. Tenho grana pra qualquer Macbook Pro ou Mac Studio, e escolhi não ir por esse caminho. Explico melhor na próxima seção.</p>
<h2>Meu caso de uso<span class="hx:absolute hx:-mt-20" id="meu-caso-de-uso"></span>
    <a href="#meu-caso-de-uso" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/open-lid-fastfetch.jpg" alt="Thinkpad aberto numa bancada do escritório de impressão 3D, com fastfetch mostrando Omarchy no terminal"  loading="lazy" /></p>
<p>Meu PC principal é um desktop com Ryzen 9 7950X3D, 96 GB de RAM, RTX 5090 de 32 GB. É onde eu trabalho, experimento com modelos locais, rodo containers, edito o blog. Pra jogo, tenho um mini-PC separado com RTX 4090. Esses dois atendem 100% do que eu preciso fazer em casa.</p>
<p>O notebook existe pra cobrir o 1% restante: sentar no sofá, levar no escritório de impressão 3D, levar na cozinha, levar em viagem curta. Não é pra substituir o desktop. É pra ter acesso remoto ao desktop quando eu estiver longe dele.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/ssh-to-remote-desktop-on-left.png" alt="Hyprland com dois terminais lado a lado: à esquerda SSH pro desktop principal (96 GB, RTX 5090), à direita o próprio Thinkpad. Mesma UI, duas máquinas."  loading="lazy" /></p>
<p>Na prática fica assim: abro o notebook, dou split no Hyprland, janela da esquerda dá SSH no desktop principal, janela da direita é o próprio notebook. Mesmo Omarchy nos dois, mesmos atalhos, mesmo bash. O notebook vira extensão do desktop, não um ambiente paralelo que eu tenho que reconfigurar na cabeça toda vez que alterno.</p>
<h3>SSH fora de casa: Tailscale<span class="hx:absolute hx:-mt-20" id="ssh-fora-de-casa-tailscale"></span>
    <a href="#ssh-fora-de-casa-tailscale" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Dentro da rede local, SSH é trivial, o notebook fala com o desktop via IP interno. Fora de casa é outra história. Meu IP doméstico é dinâmico, abrir porta 22 pra internet é péssima ideia, e mesmo com DDNS e port forwarding você está colocando SSH na cara da internet pra qualquer scanner achar.</p>
<p>A solução que uso é <a href="https://tailscale.com/"target="_blank" rel="noopener">Tailscale</a>. Pra quem não conhece: Tailscale é uma mesh VPN baseada no WireGuard, que cria uma rede privada entre seus dispositivos (o &ldquo;tailnet&rdquo;). Cada máquina roda o agente, autentica uma vez, e passa a ter um IP fixo na rede privada (tipo 100.x.y.z). O tráfego entre seus próprios dispositivos vai direto peer-to-peer, cifrado pelo WireGuard. Não passa por servidor central da Tailscale, eles só coordenam NAT traversal. Resultado: do meu notebook num café em qualquer lugar do mundo, eu dou <code>ssh hal9000</code> e caio no desktop de casa como se estivesse na mesma rede.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/tailscale-machines.png" alt="Painel admin da Tailscale mostrando as duas máquinas do meu tailnet, hal9000 (desktop) e hal9666 (thinkpad), ambas com SSH habilitado"  loading="lazy" /></p>
<p>Existem opções mais sofisticadas: <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/"target="_blank" rel="noopener">Cloudflare Tunnel</a> com Zero Trust pra expor serviços publicamente com autenticação SSO, headscale self-hosted, WireGuard cru com config manual, Nebula, OpenVPN. Cada uma tem seu caso de uso. Se você precisa expor serviços pra terceiros, controlar acesso granular por identidade, rodar a infraestrutura inteira em casa sem depender de terceiros, essas opções ganham. No meu caso, é só notebook falando com desktop, por períodos curtos (não é trabalho de uma semana inteira, é debug rápido de fim de semana), então Tailscale grátis resolve. O tier free aceita até 100 dispositivos e 3 usuários, muito mais do que eu preciso.</p>
<p>Setup é o mais simples possível:</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="c1"># No Arch/Omarchy</span>
</span></span><span class="line"><span class="cl">sudo pacman -S tailscale
</span></span><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> --now tailscaled.service
</span></span><span class="line"><span class="cl">sudo tailscale up --ssh</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>A flag <code>--ssh</code> ativa o <a href="https://tailscale.com/kb/1193/tailscale-ssh/"target="_blank" rel="noopener">Tailscale SSH</a>, que faz autenticação via identidade da tailnet em vez de chave SSH local. Uma vez fez login via browser no tailscale, cada máquina registrada pode entrar nas outras com base em política de ACL definida no painel admin. Zero key management.</p>
<p>Repito no desktop, faço login com a mesma conta, e pronto. As duas máquinas aparecem no painel (hal9000 e hal9666 na screenshot acima, com SSH habilitado nas duas). Do notebook: <code>ssh hal9000</code>. Do desktop pro notebook: <code>ssh hal9666</code>. Sem port forward, sem IP público, sem expor porta 22 pra internet. Se o notebook for roubado, eu removo ele do tailnet num clique.</p>
<p>Um detalhe prático: como o tailnet dá nome estável, eu adicionei entradas no <code>~/.ssh/config</code> pra usar esses nomes curtos:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>Host hal9000
  HostName hal9000
  User akitaonrails</code></pre></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>Assim <code>ssh hal9000</code> funciona de qualquer lugar que tenha Tailscale conectado. É a solução mais próxima de &ldquo;it just works&rdquo; que já vi pra SSH remoto.</p>
<h3>Por que não um Mac<span class="hx:absolute hx:-mt-20" id="por-que-não-um-mac"></span>
    <a href="#por-que-n%c3%a3o-um-mac" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Eu não tenho uso pro macOS. Como dev, eu vivo melhor em Linux nativo. Toda ferramenta que eu preciso tem versão Linux de primeira, e no macOS eu teria versão de segunda via Homebrew. Não faço iOS, então não preciso do XCode. Pra mobile uso Flutter ou Hotwire Native, que rodam em qualquer OS. iTerm2 e Ghostty no Mac são bons, mas Alacritty, Kitty e o próprio Ghostty no Linux me atendem igual. Todo software bom chega primeiro no Linux, daí é portado pros outros. Arch com AUR cobre tudo num único <code>yay</code>.</p>
<p>Pra trabalho criativo, faz anos que não faço profissionalmente. DaVinci Resolve Studio no Linux é superior ao Final Cut Pro. Krita ou Affinity Photo substituem Photoshop na maioria dos casos. Clip Studio Paint no Android é superior ao Procreate. Eu simplesmente não tenho um workflow que depende da Apple, e a App Store me irrita.</p>
<p>Pra jogo, Mac é terrível. Apple Silicon tem GPU boa pra algumas coisas, mas a biblioteca de jogo pro macOS nativo é pífia comparada com Windows ou Linux. Game Porting Toolkit existe, CrossOver existe, mas pra quem joga sério, não serve. Eu não vou jogar no Thinkpad, pra isso tenho o desktop principal e o mini-PC com RTX 4090, mas se um dia bater vontade de rodar um Hollow Knight ou um indie num trem, é só instalar Steam e deixar o Proton fazer o trabalho. Linux virou plataforma de jogo de verdade nos últimos anos, com Proton/DXVK rodando quase todo o catálogo da Steam (checa <a href="https://www.protondb.com/"target="_blank" rel="noopener">ProtonDB</a>). Inclusive documentei recentemente como <a href="/2026/04/11/distrobox-de-emulacao-com-claude-code/">rodei minha biblioteca de emulação em distrobox</a> sem poluir o sistema host. Com Mac, essas opções não existem.</p>
<p>Outro argumento que sempre aparece: &ldquo;mas um Mac Mini M4 ou Mac Studio com 128GB de memória unificada roda modelos grandes localmente, é o substituto do ChatGPT&rdquo;. Já testei essa tese e escrevi um <a href="/2026/04/05/testando-llms-open-source-e-comerciais-quem-consegue-bater-o-claude-opus/">benchmark detalhado</a>. A conclusão: hardware local caro pra rodar LLM é hobby de fim de semana, não é ferramenta de produção. Os modelos open source que cabem não entregam a qualidade que o Claude Opus entrega. Eu tenho um <a href="/2026/03/31/migrando-meu-home-server-com-claude-code/">home server com AMD Strix Halo e 96 GB de RAM unificada</a>, rodei modelos por dezenas de horas, e no meu fluxo real de programação eles servem pra tarefas simples. Pras tarefas complexas, Claude Opus. Antes de gastar os $4000 num Mac Studio com a justificativa de rodar modelos locais, faça o teste de verdade. Você provavelmente vai voltar a pagar Opus depois.</p>
<h2>Por que Omarchy<span class="hx:absolute hx:-mt-20" id="por-que-omarchy"></span>
    <a href="#por-que-omarchy" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Eu uso Omarchy no desktop há meses e documentei o caminho numa <a href="/tags/omarchy/">série de artigos</a>. O <a href="/2025/08/29/new-omarchy-2-0-install/">Omarchy 2.0</a> tem instalador próprio com LUKS, Btrfs, Limine, snapper e SDDM já configurados. Escrevi sobre <a href="/2025/09/12/omarchy-2-0-instale-com-a-iso-do-omarchy/">usar a ISO oficial</a>, sobre as <a href="/2025/09/07/omarchy-2-0-zsh-configs/">customizações de ZSH</a> com atuin, starship, secrets bem organizados, sobre <a href="/2025/09/07/omarchy-2-0-mise-pra-organizar-ambientes-de-desenvolvimento/">Mise pra múltiplas linguagens</a>, sobre <a href="/2025/09/07/omarchy-2-0-lazyvim-lazyextras/">LazyVim e LazyExtras</a>, sobre <a href="/2025/09/09/omarchy-2-0-entendendo-ssh-e-yubikeys/">SSH e Yubikeys</a>, sobre <a href="/2025/09/09/omarchy-2-0-tuis/">TUIs modernas</a>. Também tem o <a href="/2026/01/21/omarchy-3-setup-de-dual-gpus-com-amd-e-nvidia/">Omarchy 3 com dual GPU AMD + NVIDIA</a> e o <a href="/2026/01/09/omarchy-3-um-dos-melhores-agentes-pra-programacao-crush/">Crush</a> como agente de coding.</p>
<p>Pra quem não conhece: Omarchy é Arch Linux puro com uma camada de cosmética em cima do Hyprland/Wayland. Pré-configurado com defaults sãos. Eu podia montar tudo isso do zero, já fiz isso várias vezes na vida, mas por que refazer trabalho que alguém já fez bem feito? Instalo Omarchy, faço os tweaks que são meus em cima, e tenho Arch customizado numa fração do tempo.</p>
<p>Um ponto que eu levanto toda vez que recomendo Omarchy: a documentação é excelente. Tem um <a href="https://manuals.omamix.org/2/the-omarchy-manual"target="_blank" rel="noopener">manual oficial</a> que cobre desde instalação até customização de tema, keybindings, Hyprland, Waybar, tudo. Se você vem de Ubuntu ou Fedora e tem receio de Arch, esse manual resolve o grosso das dúvidas. Pra quem nunca tocou em Hyprland, abre ele e vai tangenciando. Não é um README jogado no GitHub, é manual de verdade, com capítulos e índice.</p>
<p>A história desse artigo começa num fio anterior. Eu migrei meu home server recentemente, trocando um servidor Ubuntu antigo por um <a href="/2026/03/31/migrando-meu-home-server-com-claude-code/">Minisforum MS-S1 com openSUSE MicroOS configurado com Claude Code</a>. Esse foi o primeiro experimento sério de deixar o Claude Code guiar uma migração de infra inteira, com containers, NFS, serviços, networking. Deu certo. E deixou no ar a ideia: por que não usar a mesma abordagem pra configurar um notebook novo?</p>
<p>Foi o que fiz. Peguei o Thinkpad, baixei a ISO do Omarchy mais recente, gravei num pendrive, instalei por cima do Windows. Do zero ao desktop funcional, menos de uma hora. Dali pra frente, tudo é tweaking, que eu fui documentando conforme fazia.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/open-lid-claude-terminal.jpg" alt="Claude Code rodando no terminal do Thinkpad, pronto pra começar a configurar o notebook"  loading="lazy" /></p>
<p>Vou detalhar as duas camadas de customização: o que precisa pra um notebook qualquer, e o que é específico desse Thinkpad.</p>
<h2>Configs específicos de notebook<span class="hx:absolute hx:-mt-20" id="configs-específicos-de-notebook"></span>
    <a href="#configs-espec%c3%adficos-de-notebook" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Um notebook tem problemas que um desktop não tem: bateria, suspensão, tampa, brilho, trackpad. Essas são as partes que Omarchy default não cobre do jeito que eu quero.</p>
<h3>Power management com TLP<span class="hx:absolute hx:-mt-20" id="power-management-com-tlp"></span>
    <a href="#power-management-com-tlp" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O default do Omarchy vem com <code>power-profiles-daemon</code>. Troquei por TLP, que dá controle granular de CPU scaling, thresholds de bateria e perfil dinâmico baseado em AC vs bateria.</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 tlp tlp-rdw
</span></span><span class="line"><span class="cl">sudo systemctl mask power-profiles-daemon.service
</span></span><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> --now tlp.service</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>mask</code> é necessário porque o upower traz o <code>power-profiles-daemon</code> de volta se você só der <code>disable</code>.</p>
<p>Thresholds de carga: 60% pra começar, 85% pra parar. O notebook fica a maior parte do tempo plugado na mesa do escritório, e manter a bateria em 100% 24/7 detona a capacidade ao longo do tempo. Com 60/85, a bateria passa a maior parte do tempo na faixa saudável de lítio e ainda sobra capacidade útil decente.</p>
<p>Perfis: <code>balanced</code> com <code>balance_power</code> na bateria, <code>performance</code> no AC. O <code>low-power</code> do TLP era agressivo demais no Core Ultra 5 235U, a resposta de janela e terminal ficava perceptível. Balanced dá a melhor relação consumo/responsividade pra uso normal.</p>
<p>Tem uma pegadinha: <code>tlp auto</code> depois de <code>tlp ac</code> nem sempre reaplica o perfil de bateria. Criei um pequeno script ligado ao <code>Super+Ctrl+P</code> que lê o estado atual e chama <code>tlp bat</code> ou <code>tlp ac</code> explicitamente:</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">profile</span><span class="o">=</span><span class="k">$(</span>cat /sys/firmware/acpi/platform_profile 2&gt;/dev/null <span class="o">||</span> <span class="nb">echo</span> unknown<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">on_ac</span><span class="o">=</span><span class="k">$(</span>cat /sys/class/power_supply/AC*/online 2&gt;/dev/null <span class="p">|</span> head -1 <span class="o">||</span> <span class="nb">echo</span> 0<span class="k">)</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="s2">&#34;</span><span class="nv">$profile</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;performance&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$on_ac</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;1&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    sudo /usr/bin/tlp auto &gt;/dev/null
</span></span><span class="line"><span class="cl">    <span class="nv">label</span><span class="o">=</span><span class="s2">&#34;Plugged in — back to AC auto&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">else</span>
</span></span><span class="line"><span class="cl">    sudo /usr/bin/tlp bat &gt;/dev/null
</span></span><span class="line"><span class="cl">    <span class="nv">label</span><span class="o">=</span><span class="s2">&#34;On battery — normal profile&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">  notify-send -t <span class="m">2000</span> <span class="s2">&#34;Performance mode: off&#34;</span> <span class="s2">&#34;</span><span class="nv">$label</span><span class="s2">&#34;</span> 2&gt;/dev/null <span class="o">||</span> <span class="nb">true</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  sudo /usr/bin/tlp ac &gt;/dev/null
</span></span><span class="line"><span class="cl">  notify-send -t <span class="m">2000</span> <span class="s2">&#34;Performance mode: on&#34;</span> <span class="s2">&#34;Forcing AC profile&#34;</span> 2&gt;/dev/null <span class="o">||</span> <span class="nb">true</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</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 waybar, um módulo custom <code>custom/perf</code> mostra o estado atual (󰓅 PERF, 󰌪 ECO, ou vazio pra balanced) e aceita clique pra alternar. O script de output é bem curto:</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="nv">p</span><span class="o">=</span><span class="k">$(</span>cat /sys/firmware/acpi/platform_profile 2&gt;/dev/null<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="s2">&#34;</span><span class="nv">$p</span><span class="s2">&#34;</span> in
</span></span><span class="line"><span class="cl">  performance<span class="o">)</span> <span class="nb">printf</span> <span class="s1">&#39;󰓅 PERF&#39;</span> <span class="p">;;</span>
</span></span><span class="line"><span class="cl">  low-power<span class="o">)</span>   <span class="nb">printf</span> <span class="s1">&#39;󰌪 ECO&#39;</span>  <span class="p">;;</span>
</span></span><span class="line"><span class="cl">  balanced<span class="p">|</span><span class="s2">&#34;&#34;</span><span class="o">)</span> <span class="nb">printf</span> <span class="s1">&#39;&#39;</span>       <span class="p">;;</span>
</span></span><span class="line"><span class="cl">  *<span class="o">)</span>           <span class="nb">printf</span> <span class="s1">&#39;%s&#39;</span> <span class="s2">&#34;</span><span class="nv">$p</span><span class="s2">&#34;</span> <span class="p">;;</span>
</span></span><span class="line"><span class="cl"><span class="k">esac</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>
<h3>Suspend, hibernate, e tampa<span class="hx:absolute hx:-mt-20" id="suspend-hibernate-e-tampa"></span>
    <a href="#suspend-hibernate-e-tampa" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Isso aqui é o que mudou em relação aos notebooks que eu usava em 2015. O T14 Gen 6 fecha a tampa, suspende, e acorda quando você abre de novo. Sem bug, sem delay estranho, sem precisar dar login de novo no meio da sessão gráfica. O hyprlock pega depois do suspend, aceita digital ou senha, e volta pro desktop em segundos. Isso é o comportamento que a gente tem na Apple há anos e que no Linux era uma aventura. Em 2026, em hardware moderno com kernel 6.11+, simplesmente funciona.</p>
<p>Mem sleep mode é s2idle (sem deep sleep). Hibernação habilitada via swapfile Btrfs de ~30 GB e <code>resume=/dev/mapper/root resume_offset=...</code> no kernel cmdline do Limine. Raramente uso, mas está lá.</p>
<p>O hypridle tem timeouts agressivos pra notebook:</p>
<ul>
<li>2.5 min → screensaver</li>
<li>5 min → lock</li>
<li>5.5 min → DPMS off + keyboard backlight off</li>
</ul>
<p>Depois de trancado, passa mais 5 min e a tela apaga de vez. No unlock, restaura brilho de tela e de teclado pro nível anterior. Essas timings são muito mais curtas que as do desktop (20-40 min lá). A diferença de bateria ao longo do dia é mensurável.</p>
<h3>Brilho e backlight de teclado<span class="hx:absolute hx:-mt-20" id="brilho-e-backlight-de-teclado"></span>
    <a href="#brilho-e-backlight-de-teclado" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p><code>brightnessctl</code> controla os dois. Fn+Space alterna o backlight do teclado em três níveis. Hypridle salva o nível atual antes de apagar e restaura no retorno. Comando que uso no 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">brightnessctl -sd <span class="s1">&#39;*::kbd_backlight&#39;</span> <span class="nb">set</span> <span class="m">0</span>    <span class="c1"># salva e desliga</span>
</span></span><span class="line"><span class="cl">brightnessctl -rd <span class="s1">&#39;*::kbd_backlight&#39;</span>          <span class="c1"># restaura</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>
<h3>Touchpad<span class="hx:absolute hx:-mt-20" id="touchpad"></span>
    <a href="#touchpad" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>No <code>hypr/input.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>touchpad {
    natural_scroll = true
    clickfinger_behavior = true
    disable_while_typing = true
    scroll_factor = 0.4
}
gesture = 3, horizontal, workspace</code></pre></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><code>clickfinger_behavior</code> troca o clique de 2 dedos como botão direito (mais confortável que acertar a zona inferior direita). <code>disable_while_typing</code> é palm rejection básico. Três dedos horizontais alternam workspaces, o gesto mais útil no Hyprland.</p>
<h2>Configs específicos do Thinkpad<span class="hx:absolute hx:-mt-20" id="configs-específicos-do-thinkpad"></span>
    <a href="#configs-espec%c3%adficos-do-thinkpad" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui entra o que é particular desse modelo. Algumas coisas o Linux moderno já cobre sozinho, outras exigem configuração específica.</p>
<h3>Sensor de digital<span class="hx:absolute hx:-mt-20" id="sensor-de-digital"></span>
    <a href="#sensor-de-digital" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Goodix MOC <code>27c6:6594</code>, funciona com libfprint 1.94.9+ em kernel 6.11+. Pacote é <code>fprintd</code>.</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 fprintd
</span></span><span class="line"><span class="cl">fprintd-enroll                        <span class="c1"># dedo indicador direito por default</span>
</span></span><span class="line"><span class="cl">fprintd-enroll -f left-index-finger   <span class="c1"># outro dedo</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>Pro <code>sudo</code> aceitar digital, adiciono <code>auth sufficient pam_fprintd.so</code> acima da linha do <code>pam_unix.so</code> em <code>/etc/pam.d/sudo</code>. Com <code>sufficient</code>, se a digital passar, autentica direto. Se falhar ou se eu digitar ESC, cai pro prompt de senha. Isso vale a pena de verdade: dezenas de vezes por dia, <code>sudo pacman -Syu</code> ou <code>sudo systemctl restart algo</code>, e é só encostar o dedo.</p>
<p>No hyprlock, uso a configuração nativa do próprio hyprlock, não o PAM:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>auth {
    fingerprint {
        enabled = true
        ready_message = Scan fingerprint or type password
        present_message = Scanning...
        retry_delay = 250
    }
}</code></pre></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>A razão é que o caminho PAM dá prompt duplo. Configurado nativo, o hyprlock aceita digital ou senha, o que vier primeiro desbloqueia.</p>
<p>No SDDM (login inicial), deixei senha apenas. O motivo: a senha de login destrava o keyring do GNOME, e a digital não consegue fornecer plaintext pra isso. Depois que o keyring está destrancado, o hyprlock pode usar digital sem problema.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/sudo-asks-for-fingerprinting.png" alt="Prompt do sudo pedindo leitura de digital"  loading="lazy" /></p>
<p>Na prática, o sudo fica assim. Encosta o dedo, autentica, segue.</p>
<h3>Teclado brasileiro do Thinkpad<span class="hx:absolute hx:-mt-20" id="teclado-brasileiro-do-thinkpad"></span>
    <a href="#teclado-brasileiro-do-thinkpad" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O teclado brasileiro do Thinkpad tem uma peculiaridade chata. A tecla <code>/?</code> fica na posição que seria o Ctrl direito (keycode 97), não na posição AB11 tradicional do ABNT2 (keycode 89). Se você usar o layout padrão <code>br(abnt2)</code>, essa tecla fica inacessível. Literalmente não imprime nada.</p>
<p>A solução é o variant <code>br(thinkpad)</code> que existe em <code>/usr/share/X11/xkb/symbols/br</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>xkb_symbols &#34;thinkpad&#34; {
    include &#34;br(abnt2)&#34;
    name[Group1]=&#34;Portuguese (Brazil, IBM/Lenovo ThinkPad)&#34;;
    key &lt;RCTL&gt; { [ slash, question, degree, questiondown ] };
};</code></pre></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 <code>hypr/input.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>kb_layout = br
kb_variant = thinkpad
kb_model = thinkpad60</code></pre></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 system-wide pra TTY/X11:</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 localectl set-keymap br-abnt2
</span></span><span class="line"><span class="cl">sudo localectl set-x11-keymap br thinkpad thinkpad60</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>Escrevi um pequeno Python que lê scancodes brutos de <code>/dev/input/event*</code> pra diagnosticar essas esquisitices. Útil quando uma tecla decide não funcionar e você precisa descobrir se é hardware, kernel, ou xkb.</p>
<h3>Input method: fcitx5<span class="hx:absolute hx:-mt-20" id="input-method-fcitx5"></span>
    <a href="#input-method-fcitx5" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Junto com o layout eu instalo fcitx5. Input method, pra quem não conhece, é a camada que transforma sequência de teclas em caracteres. É onde entram deadkeys (til pra nasalizar, acento agudo, circunflexo), composição de caracteres que não estão no teclado (ç, Ç, letras acentuadas em maiúscula), suporte a emoji. Em app Qt ou GTK, o input method também cuida dos menus de contexto pra cedilha e acentos.</p>
<p>Pacotes:</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 --needed fcitx5 fcitx5-configtool fcitx5-gtk fcitx5-qt</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 as variáveis de ambiente pros toolkits encontrarem o fcitx5. Criei <code>~/.config/environment.d/fcitx.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>INPUT_METHOD=fcitx
QT_IM_MODULE=fcitx
XMODIFIERS=@im=fcitx
SDL_IM_MODULE=fcitx</code></pre></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>environment.d</code> do systemd é carregado antes das sessões gráficas, então Brave, Alacritty, VS Code e qualquer GTK/Qt pegam automaticamente. Habilito autostart no Hyprland:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>exec-once = fcitx5 -d</code></pre></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>Digitando <code>~a</code> vira <code>ã</code>, <code>'e</code> vira <code>é</code>, <code>ç</code> funciona como deveria em toda aplicação. Num teclado Thinkpad brasileiro, isso é a diferença entre conseguir escrever em português com naturalidade ou ficar catando letra.</p>
<h3>Áudio SOF<span class="hx:absolute hx:-mt-20" id="áudio-sof"></span>
    <a href="#%c3%a1udio-sof" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Codec Realtek ALC3306/ALC287 via Sound Open Firmware. Sem o <code>sof-firmware</code>, o módulo de kernel carrega mas o DSP nunca boota e o PipeWire cai silenciosamente pra <code>auto_null</code>. Resultado: você acha que o alto-falante está no mudo, mas na verdade o PipeWire não tem device nenhum.</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 --needed sof-firmware alsa-ucm-conf pipewire pipewire-pulse wireplumber</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 precisar forçar SOF em vez do HDA legacy:</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;options snd-intel-dspcfg dsp_driver=3&#34;</span> <span class="p">|</span> sudo tee /etc/modprobe.d/alsa.conf</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>Reload sem reboot:</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 modprobe -r snd_sof_pci_intel_mtl
</span></span><span class="line"><span class="cl">sudo modprobe snd_sof_pci_intel_mtl
</span></span><span class="line"><span class="cl">systemctl --user restart wireplumber pipewire pipewire-pulse</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>
<h3>Firmware updates pelo fwupd<span class="hx:absolute hx:-mt-20" id="firmware-updates-pelo-fwupd"></span>
    <a href="#firmware-updates-pelo-fwupd" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/bios-update.jpg" alt="Firmware update da Lenovo (ME Corp) rodando no boot"  loading="lazy" /></p>
<p><code>fwupdmgr update</code> funciona, mas com Limine tem uma pegadinha: o fwupd tenta escrever em <code>/boot/EFI/systemd/</code> ou <code>/boot/EFI/arch/</code>, que não existem. O workaround:</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 mkdir -p /boot/EFI/arch
</span></span><span class="line"><span class="cl">sudo fwupdmgr update -y --no-reboot-check
</span></span><span class="line"><span class="cl">fwupdmgr get-history  <span class="c1"># deve mostrar &#34;Success&#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>
<h3>HiDPI / fractional scaling<span class="hx:absolute hx:-mt-20" id="hidpi--fractional-scaling"></span>
    <a href="#hidpi--fractional-scaling" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Painel 14&quot; em 1920x1200 numa resolução do Hyprland livre. O auto 1.5x do Omarchy ficava chunky demais. Fixei em 1.333x:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>env = GDK_SCALE,1
monitor=,preferred,auto,1.3333,vrr,2</code></pre></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>Efetivo 1440x900. GTK com <code>GDK_SCALE=1</code> renderiza 1:1 com o Hyprland (não magnifica duplo). VRR mode 2 só em fullscreen, porque painéis LCD tendem a cintilar em conteúdo estático com VRR ativa.</p>
<p>Flags do Brave e Chromium pra renderizar bem nessa escala:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>--ozone-platform=wayland
--enable-features=WaylandFractionalScaleV1,UseOzonePlatform,VaapiVideoDecoder,VaapiVideoEncoder
--enable-gpu-rasterization</code></pre></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 VAAPI faz diferença real na bateria em YouTube.</p>
<h2>Tunando Omarchy pra ser meu<span class="hx:absolute hx:-mt-20" id="tunando-omarchy-pra-ser-meu"></span>
    <a href="#tunando-omarchy-pra-ser-meu" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Omarchy vem com defaults bons. O que eu ajusto é no topo deles, sem tocar em <code>~/.local/share/omarchy/</code> (que é clobbered pelo <code>omarchy-update</code>). Toda customização fica em <code>~/.config/</code>.</p>
<h3>Infra: Btrfs, snapshots, Snapper<span class="hx:absolute hx:-mt-20" id="infra-btrfs-snapshots-snapper"></span>
    <a href="#infra-btrfs-snapshots-snapper" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Omarchy já vem com Btrfs e subvolumes separados:</p>
<table>
  <thead>
      <tr>
          <th>Subvolume</th>
          <th>Mount</th>
          <th>Entra nos snapshots?</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>@</code></td>
          <td><code>/</code></td>
          <td>sim</td>
      </tr>
      <tr>
          <td><code>@home</code></td>
          <td><code>/home</code></td>
          <td>não</td>
      </tr>
      <tr>
          <td><code>@log</code></td>
          <td><code>/var/log</code></td>
          <td>não</td>
      </tr>
      <tr>
          <td><code>@pkg</code></td>
          <td><code>/var/cache/pacman/pkg</code></td>
          <td>não</td>
      </tr>
  </tbody>
</table>
<p><code>@home</code> separado significa que <code>~/.cache</code>, <code>~/.config/BraveSoftware</code>, etc. não incham snapshots do root. Snapshot é de sistema, não de perfil.</p>
<p>Swap: zram de 4 GB com prioridade 100 (hit primeiro), mais swapfile de 30 GB com prioridade 0 (habilita hibernação, dimensionado pra RAM).</p>
<p>O stack de snapshot: Snapper tira snapshot antes e depois de cada <code>pacman -Syu</code> via snap-pac. <code>limine-snapper-sync</code> escreve esses snapshots no menu do Limine, então dá pra bootar num snapshot anterior pra reverter. Se algo quebra depois de update, você segura uma tecla no boot, escolhe o snapshot pré-update, boota read-only pra verificar, e se estiver bom, faz <code>snapper rollback</code>.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/btrfs-snapshots-config.png" alt="Subvolumes Btrfs separados pra que snapshots do root não inchem com cache de usuário"  loading="lazy" /></p>
<p>Omarchy deixa o <code>snapper-cleanup.timer</code> e o <code>snapper-boot.timer</code> desabilitados por default. Habilitei os dois e configurei retenção pra caber num SSD de 1 TB sem explodir:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>TIMELINE_LIMIT_HOURLY=10
TIMELINE_LIMIT_DAILY=0
TIMELINE_LIMIT_WEEKLY=1
TIMELINE_LIMIT_MONTHLY=1
NUMBER_LIMIT=50</code></pre></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>Um detalhe que custa debug pra quem esquece: Docker e Ollama escrevem gigabytes em <code>/var/lib/docker</code> e <code>/var/lib/ollama</code>. Se isso cai dentro de <code>@</code>, os snapshots catastrofizam. Cada imagem Docker ou modelo Ollama baixado triplica em tamanho. Criei subvolumes aninhados pros dois, com <code>chattr +C</code> pra desligar CoW:</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 btrfs subvolume create /var/lib/docker
</span></span><span class="line"><span class="cl">sudo chattr +C /var/lib/docker
</span></span><span class="line"><span class="cl">sudo btrfs subvolume create /var/lib/ollama</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>Isso tem que ser feito ANTES de o Docker ou Ollama escrever dados. Se já tem dados lá, precisa migrar.</p>
<h3>NFS pro NAS Synology<span class="hx:absolute hx:-mt-20" id="nfs-pro-nas-synology"></span>
    <a href="#nfs-pro-nas-synology" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Meu Synology expõe três volumes. No desktop, monto normal. No notebook, tem que ser mais defensivo. O notebook anda, esquece a rede, conecta em WiFi público. Fstab do notebook:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>nfs4  _netdev,noauto,nofail,x-systemd.automount,x-systemd.idle-timeout=10min,x-systemd.mount-timeout=15s,noatime,nodiratime,nconnect=4,actimeo=10,soft,timeo=30,retrans=2</code></pre></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>Diferença crítica em relação ao desktop: <code>soft</code> com timeouts curtos (não fica pendurado pra sempre), <code>x-systemd.idle-timeout=10min</code> (auto-unmount quando ocioso), sem <code>network-online.target</code> no require (não atrasa boot). Resultado prático: <code>cd /mnt/gigachad</code> em casa monta lazy, fora de casa falha rápido sem trancar shell.</p>
<p>Outro detalhe importante: meu user no notebook tem UID 1026, que bate com a permissão do share no Synology. O Linux default cria user em 1000, o Synology impõe identidade via UID no fio. Se os UIDs não batem, você não consegue ler os arquivos, ou ainda pior, escreve como nobody. Rodei de TTY (com usuário deslogado) os <code>usermod</code>/<code>groupmod</code> pra remapear o user pra 1026/1026 e fiz <code>chown -R</code> em <code>/home</code>.</p>
<h3>Hardening de WiFi público<span class="hx:absolute hx:-mt-20" id="hardening-de-wifi-público"></span>
    <a href="#hardening-de-wifi-p%c3%bablico" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Notebook vai sair de casa. Num aeroporto ou café, eu não quero anunciar hostname, não quero MAC rastreável, não quero serviço escutando porta aberta.</p>
<p><code>/etc/NetworkManager/conf.d/00-macrandomize.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[device]
wifi.scan-rand-mac-address=yes

[connection]
wifi.cloned-mac-address=stable
ethernet.cloned-mac-address=stable
connection.stable-id=${CONNECTION}/${BOOT}

ipv6.ip6-privacy=2
ipv6.addr-gen-mode=stable-privacy</code></pre></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>MAC aleatório por scan (anti-fingerprinting passivo). MAC clonado estável por SSID (o portal cativo não te re-pergunta login toda vez) mas diferente entre redes. IPv6 com endereços temporários e interface ID derivado de segredo estável, não do MAC (sem vazar EUI-64).</p>
<p><code>/etc/systemd/resolved.conf.d/hardening.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[Resolve]
LLMNR=no
MulticastDNS=no</code></pre></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>Mata broadcast de hostname em LLMNR e mDNS. Também desabilito avahi:</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 systemctl disable --now avahi-daemon.service avahi-daemon.socket</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>UFW firewall:</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 ufw default deny incoming
</span></span><span class="line"><span class="cl">sudo ufw default allow outgoing
</span></span><span class="line"><span class="cl">sudo ufw --force enable</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>SSH server já é off por default no Omarchy. Nada escutando. Mesmo que o firewall vaze, não tem superfície.</p>
<p>Tudo isso entra num único ritual de setup inicial.</p>
<h3>Persistência de SSH agent (keyring + keychain)<span class="hx:absolute hx:-mt-20" id="persistência-de-ssh-agent-keyring--keychain"></span>
    <a href="#persist%c3%aancia-de-ssh-agent-keyring--keychain" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Se você usa SSH sério, quer digitar a passphrase uma vez por boot e ter <code>ssh</code>, <code>git push</code>, <code>scp</code> mudos pelo resto do dia. No Arch atual isso tem uma pegadinha: o <code>gnome-keyring</code> 50 deixou de oferecer componente SSH, e o substituto (<code>gcr-ssh-agent</code>) é um agente plain em memória, sem persistência de passphrase. A caixa &ldquo;lembrar esta chave&rdquo; que você viu em guias antigos simplesmente não existe mais.</p>
<p>A combinação que funciona tem três peças:</p>
<ol>
<li><code>gcr-ssh-agent.socket</code> gerenciado pelo systemd serve o <code>SSH_AUTH_SOCK</code> em <code>$XDG_RUNTIME_DIR/gcr/ssh</code></li>
<li><code>pam_gnome_keyring</code> no login SDDM destrava o keyring com a senha de login (usado por apps GUI tipo Brave, não pelo SSH)</li>
<li><code>keychain</code> (wrapper) mantém um <code>ssh-agent</code> vivo entre logouts, sobrescreve o <code>SSH_AUTH_SOCK</code> pra apontar pra esse agent persistente, e cacheia o PID em <code>~/.keychain/&lt;host&gt;-sh</code></li>
</ol>
<p>Primeiro, instalo o keyring:</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 --needed gnome-keyring seahorse keychain</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>Depois, edito <code>/etc/pam.d/sddm</code> pra o login password destravar o keyring automaticamente. Adiciono no topo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>-auth      optional    pam_gnome_keyring.so</code></pre></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 no final:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>-session   optional    pam_gnome_keyring.so    auto_start</code></pre></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 hífen na frente (<code>-auth</code>, <code>-session</code>) marca como opcional, se o módulo não carregar, não quebra login.</p>
<p>Pino o <code>SSH_AUTH_SOCK</code> pra sessões gráficas e TTY via <code>~/.config/environment.d/ssh-agent.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>SSH_AUTH_SOCK=%t/gcr/ssh</code></pre></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>%t</code> resolve pra <code>$XDG_RUNTIME_DIR</code>, tipo <code>/run/user/1026</code>. Habilito o socket do gcr e o linger do usuário (pra user daemons sobreviverem ao logout):</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">systemctl --user <span class="nb">enable</span> --now gcr-ssh-agent.socket
</span></span><span class="line"><span class="cl">sudo loginctl enable-linger <span class="nv">$USER</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>Por fim, no <code>~/.config/bash/init.sh</code> o keychain inicia ou reusa o agent:</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="k">if</span> <span class="nb">command</span> -v keychain <span class="p">&amp;</span>&gt;/dev/null <span class="o">&amp;&amp;</span> <span class="o">[[</span> -r ~/.ssh/id_ed25519 <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">eval</span> <span class="s2">&#34;</span><span class="k">$(</span>keychain --eval --quiet ~/.ssh/id_ed25519<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</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><code>--eval</code> emite atribuições shell (<code>SSH_AUTH_SOCK</code>, <code>SSH_AGENT_PID</code>) apontando pro agent do keychain, que passa por cima do gcr setado pelo environment.d. <code>--quiet</code> cala o banner depois que a chave está carregada.</p>
<p>Fluxo na prática: boot → primeiro terminal → keychain pede passphrase uma vez → chave fica carregada. Logout → login de novo → novos shells re-atacham no mesmo agent (via <code>~/.keychain/&lt;host&gt;-sh</code>) → zero prompt. <code>ssh-add -l</code> confirma que a chave está lá, <code>echo $SSH_AUTH_SOCK</code> confirma que está no caminho do keychain.</p>
<p>Quando você vai digitar a passphrase de novo: reboot, <code>ssh-add -D</code>, ou <code>keychain --clear</code>. Em uso normal, uma vez por dia.</p>
<h3>Bash em vez de ZSH<span class="hx:absolute hx:-mt-20" id="bash-em-vez-de-zsh"></span>
    <a href="#bash-em-vez-de-zsh" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>No desktop uso ZSH. No notebook fui de Bash pra alinhar com o default do Omarchy, sem dupla de camadas modulares pra manter. <code>~/.bashrc</code> é um symlink pra <code>~/.config/bash/bashrc</code>, que faz source dos defaults do Omarchy primeiro e depois empilha as minhas customizações:</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">source</span> ~/.local/share/omarchy/default/bash/rc
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/envs.sh
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/aliases.sh
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/mounts.sh
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/init.sh
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/secrets    <span class="c1"># gitignored, chmod 600</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><code>envs.sh</code> tem o que é meu: OpenRouter base URL, Ollama apontando pro GPU box da rede local (192.168.0.14), AWS region, analytics do Hugo, configs de zoxide e SSH agent. <code>aliases.sh</code> tem os atalhos de TLP, um alias pra <code>shell-gpt</code> via Docker, e functions pra hardenar o PATH quando rodo <code>makepkg</code> ou <code>yay</code> (prevenir injeção de binário via user config malicioso).</p>
<p><code>init.sh</code> faz o trabalho de integração. Atuin com bind manual do Ctrl-R (pra deixar a seta pra cima com o history-search padrão do bash, que eu uso mais). Keychain carregando <code>~/.ssh/id_ed25519</code> uma vez por boot e reusando nos shells seguintes (sem ter que re-autenticar SSH toda hora). Blesh se estiver instalado (autosuggestion estilo ZSH pra Bash). E uma função que manda o PROMPT_COMMAND ajustar o título da janela com o pwd atual e o comando em execuçã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">__title_idle<span class="o">()</span> <span class="o">{</span> <span class="nb">printf</span> <span class="s1">&#39;\033]2;%s\007&#39;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">PWD</span><span class="p">/#</span><span class="nv">$HOME</span><span class="p">/~</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">;</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl">__title_busy<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> <span class="nv">cmd</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">BASH_COMMAND</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$cmd</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;__title_&#34;</span>* <span class="o">||</span> <span class="s2">&#34;</span><span class="nv">$cmd</span><span class="s2">&#34;</span> <span class="o">==</span> *<span class="s2">&#34;PROMPT_COMMAND&#34;</span>* <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="k">return</span>
</span></span><span class="line"><span class="cl">  <span class="nb">printf</span> <span class="s1">&#39;\033]2;%s — %s\007&#39;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">PWD</span><span class="p">/#</span><span class="nv">$HOME</span><span class="p">/~</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$cmd</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> -n <span class="s2">&#34;</span><span class="si">${</span><span class="nv">PROMPT_COMMAND</span><span class="p">-</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nv">PROMPT_COMMAND</span><span class="o">=</span><span class="s2">&#34;__title_idle; </span><span class="si">${</span><span class="nv">PROMPT_COMMAND</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  <span class="nv">PROMPT_COMMAND</span><span class="o">=</span><span class="s2">&#34;__title_idle&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl"><span class="nb">trap</span> <span class="s1">&#39;__title_busy&#39;</span> DEBUG</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 idle, título mostra só o pwd. Com um comando rodando, <code>trap DEBUG</code> pega o <code>BASH_COMMAND</code> em execução e atualiza o título. Integra com o <code>hyprland/window</code> do waybar pra mostrar tudo lá.</p>
<p>Pro toolbelt Rust moderno, a lista:</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 --needed <span class="se">\
</span></span></span><span class="line"><span class="cl">  eza bat fd ripgrep sd git-delta dust procs bottom duf tokei hyperfine <span class="se">\
</span></span></span><span class="line"><span class="cl">  zoxide atuin tldr starship</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><code>eza</code> substitui <code>ls</code>. <code>bat</code> substitui <code>cat</code> com syntax highlight. <code>fd</code> substitui <code>find</code>. <code>ripgrep</code> substitui <code>grep</code>. <code>sd</code> substitui <code>sed</code>. <code>delta</code> pluga no git pra diff side-by-side colorido. <code>dust</code> pro <code>du</code> visual. <code>procs</code> pro <code>ps</code>. <code>btm</code> (bottom) pro <code>top</code>. <code>duf</code> pro <code>df</code>. <code>tokei</code> conta linhas de código. <code>hyperfine</code> pra benchmark de comando. <code>zoxide</code> é <code>cd</code> com memória (muito útil). <code>atuin</code> é history do shell com sync criptografado (aponto pro meu home server via <code>sync_address = &quot;http://192.168.0.90:8888&quot;</code>). <code>starship</code> é o prompt. <code>tldr</code> é man page em 10 linhas.</p>
<p>O <code>atuin key</code> tem que ser backupeado offline. Se você perde, perde o histórico criptografado. Salvei no meu Bitwarden self-hosted (Vaultwarden), que eu documentei no <a href="/2025/09/10/omarchy-2-0-bitwarden-self-hosted-vaultwarden/">artigo sobre Bitwarden self-hosted</a>.</p>
<p>O git passa diff pelo delta:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[core]        pager = delta
[interactive] diffFilter = delta --color-only
[delta]       navigate side-by-side line-numbers hyperlinks, light=false
[merge]       conflictstyle = zdiff3</code></pre></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>
<h3>Hyprland e Waybar<span class="hx:absolute hx:-mt-20" id="hyprland-e-waybar"></span>
    <a href="#hyprland-e-waybar" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Customizações visuais e de UX que fiz em cima do default.</p>
<p>No <code>hypr/looknfeel.conf</code>, gaps menores (2/5 vs 5/10 do default), animação de slide entre workspaces, VFR ligado (reduz consumo quando a tela está estática), <code>allow_session_lock_restore</code> (se o hyprlock crasha, volta pra tela de lock em vez de jogar pro desktop).</p>
<p>No <code>hypr/bindings.conf</code>:</p>
<table>
  <thead>
      <tr>
          <th>Binding</th>
          <th>Ação</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>Super+B</code></td>
          <td>Brave</td>
      </tr>
      <tr>
          <td><code>Super+L</code></td>
          <td>Lock screen (default era layout toggle)</td>
      </tr>
      <tr>
          <td><code>Super+Ctrl+L</code></td>
          <td>Layout toggle (movi pra cá)</td>
      </tr>
      <tr>
          <td><code>Super+Ctrl+P</code></td>
          <td>Toggle TLP perf mode</td>
      </tr>
  </tbody>
</table>
<p>No Waybar, três módulos custom que recomendo:</p>
<p><strong>Título de janela</strong>: o módulo <code>hyprland/window</code> mostra o que tá focado. No bash, o PROMPT_COMMAND atualiza o título pra algo como &ldquo;~/Projects/blog — hugo server&rdquo;. Então no waybar aparece o diretório e o comando em execução, sem eu precisar olhar pro terminal.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/hypr---window-title-on-waybar.png" alt="Waybar mostrando workspaces à esquerda e o título da janela focada com o pwd e comando em execução"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/hypr---another-window-title-on-waybar.png" alt="Outro exemplo do título da janela no waybar, dessa vez mostrando “Claude Code”"  loading="lazy" /></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-jsonc" data-lang="jsonc"><span class="line"><span class="cl"><span class="s2">&#34;hyprland/window&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{title}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;max-length&#34;</span><span class="p">:</span> <span class="mi">50</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rewrite&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;(.{47}).+&#34;</span><span class="p">:</span> <span class="s2">&#34;$1…&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><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>
<p><strong>Perf mode</strong>: o <code>custom/perf</code> executa um script que lê o estado do TLP e mostra um ícone:</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-jsonc" data-lang="jsonc"><span class="line"><span class="cl"><span class="s2">&#34;custom/perf&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;exec&#34;</span><span class="p">:</span> <span class="s2">&#34;~/.config/scripts/perf-waybar.sh&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;interval&#34;</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;on-click&#34;</span><span class="p">:</span> <span class="s2">&#34;~/.config/scripts/perf-toggle.sh&#34;</span>
</span></span><span class="line"><span class="cl"><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>
<p>Vazio em balanced, 󰓅 PERF em performance, 󰌪 ECO em low-power. Clique alterna. Útil pra ver rapidamente em que modo a máquina está.</p>
<p><strong>Claudebar</strong>: integrei o <a href="https://github.com/alfredopiquet/claudebar"target="_blank" rel="noopener">claudebar</a> num módulo custom que mostra a % de uso da sessão do Claude Code e o gasto extra inline no waybar. Sem ter que abrir outra janela.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/hypr---power-profile-and-claudebar-next-to-traybar.png" alt="Claudebar mostrando 9%, 1h16m restantes e $1120.74 de uso extra, seguido do indicador PERF e o tray"  loading="lazy" /></p>
<p>O clock:</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-jsonc" data-lang="jsonc"><span class="line"><span class="cl"><span class="s2">&#34;clock&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{:L%A %d %B - %H:%M}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;format-alt&#34;</span><span class="p">:</span> <span class="s2">&#34;{:L%A W%V %Y - %H:%M}&#34;</span>
</span></span><span class="line"><span class="cl"><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>
<p>Exibe &ldquo;quinta 17 abril - 14:32&rdquo; por padrão, clique alterna pra &ldquo;quinta W16 2026 - 14:32&rdquo; com número da semana do ano, útil pra planejar artigos e tarefas.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/hypr---better-date-time-on-waybar-center.png" alt="Clock do waybar no centro com data e hora em português"  loading="lazy" /></p>
<h3>Atuin self-hosted<span class="hx:absolute hx:-mt-20" id="atuin-self-hosted"></span>
    <a href="#atuin-self-hosted" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Atuin roda no meu home server em 192.168.0.90:8888. Criei uma conta separada pro notebook (<code>akitaonrails-thinkpad</code>), não misturo histórico com desktop de propósito. <code>atuin sync</code> roda a cada 5 minutos e todo histórico é criptografado antes de ir pro server. O server não vê os comandos, só vê bytes criptografados.</p>
<h2>Conclusão: escolhendo notebook pra Linux<span class="hx:absolute hx:-mt-20" id="conclusão-escolhendo-notebook-pra-linux"></span>
    <a href="#conclus%c3%a3o-escolhendo-notebook-pra-linux" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se tem uma coisa que eu aprendi nessa jornada: escolher notebook pra rodar Linux confortavelmente não é trivial. Precisa checar a <a href="https://wiki.archlinux.org/title/Laptop"target="_blank" rel="noopener">ArchWiki</a> pelo modelo específico antes de comprar. A do <a href="https://wiki.archlinux.org/title/Lenovo_ThinkPad_T14s_%28AMD%29_Gen_6"target="_blank" rel="noopener">T14s Gen 6 AMD</a>, por exemplo, cataloga cada peculiaridade de hardware e como contornar. Sem essa referência, você descobre os problemas instalando.</p>
<p>Regra que sigo: nunca comprar modelo recém-lançado. Deixar passar uns 6 a 12 meses depois do lançamento. Isso dá tempo pra comunidade iron out os bugs, pros drivers entrarem no mainline, pra ArchWiki ter uma página decente, pra libfprint incluir o sensor de digital, pro kernel cobrir o WiFi e a câmera IR. Comprar de primeira é assumir o papel de tester beta.</p>
<p>Marcas com trilha Linux decente: Lenovo (especialmente Thinkpad, eles oferecem Ubuntu e Fedora pré-instalados), Dell (a linha XPS e Latitude), Asus (Zenbook e ROG têm suporte razoável), Framework (fábrica direto pra Linux). Mac qualquer geração recente é cortado do Linux mainline ou via Asahi com caveats.</p>
<p>O Thinkpad T14 Gen 6 não é o notebook mais bonito que eu podia ter comprado. Mas é rugged, tem as portas certas, o sensor de digital funciona, e a carcaça plástica aceita cair, arranhar, viajar na mala sem eu ficar nervoso. Pra servir de companion de debug remoto, é o que eu precisava. Se esse é o seu perfil de uso também, recomendo. Se você quer OLED e metal, vai de Zenbook ou de T14s. Cada premium tem seu compromisso, nenhum notebook Linux em 2026 é perfeito.</p>
<p>Tudo que descrevi aqui ficou versionado num repo privado meu. Se eu precisar reinstalar amanhã, rodo meia dúzia de passos em ordem e volto ao mesmo lugar. Esse é o ponto todo de manter configuração em Git: notebook é commodity, config é minha.</p>
]]></content:encoded><category>omarchy</category><category>linux</category><category>hardware</category><category>reviews</category></item><item><title>Seedance 2.0 finalmente foi lançado: Primeiras Impressões</title><link>https://akitaonrails.github.io/2026/04/15/seedance-2-0-finalmente-foi-lancado-primeiras-impressoes/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/04/15/seedance-2-0-finalmente-foi-lancado-primeiras-impressoes/</guid><pubDate>Wed, 15 Apr 2026 10:00:00 -0300</pubDate><description>&lt;p&gt;A ByteDance lançou hoje, 15 de abril, a versão pública do &lt;a href="https://seed.bytedance.com/en/blog/official-launch-of-seedance-2-0"target="_blank" rel="noopener"&gt;Seedance 2.0&lt;/a&gt;. Eles prometeram esse modelo no fim do ano passado, mas o acesso ficou restrito a parceiros comerciais por meses, com vários adiamentos pelo caminho. Hoje finalmente abriu pra qualquer um testar.&lt;/p&gt;
&lt;p&gt;A proposta é forte. É um modelo multimodal de geração de vídeo que aceita simultaneamente texto, até 9 imagens de referência, 3 clipes de vídeo de referência e 3 trilhas de áudio numa mesma chamada. Em cima disso, ele gera saída de até 15 segundos com áudio sincronizado nativo (diálogo, efeitos, música ambiente), suporta extensão de vídeo, edição pontual de personagens e objetos, e tem planejamento de câmera dirigido por prompt. A ByteDance posiciona o modelo pra publicidade comercial, vídeos explicativos, produção de filme, e-commerce e gaming. Ou seja: pra criador de conteúdo que quer escapar do estágio &amp;ldquo;meme aleatório&amp;rdquo; e começar a entregar peça com uso profissional.&lt;/p&gt;</description><content:encoded><![CDATA[<p>A ByteDance lançou hoje, 15 de abril, a versão pública do <a href="https://seed.bytedance.com/en/blog/official-launch-of-seedance-2-0"target="_blank" rel="noopener">Seedance 2.0</a>. Eles prometeram esse modelo no fim do ano passado, mas o acesso ficou restrito a parceiros comerciais por meses, com vários adiamentos pelo caminho. Hoje finalmente abriu pra qualquer um testar.</p>
<p>A proposta é forte. É um modelo multimodal de geração de vídeo que aceita simultaneamente texto, até 9 imagens de referência, 3 clipes de vídeo de referência e 3 trilhas de áudio numa mesma chamada. Em cima disso, ele gera saída de até 15 segundos com áudio sincronizado nativo (diálogo, efeitos, música ambiente), suporta extensão de vídeo, edição pontual de personagens e objetos, e tem planejamento de câmera dirigido por prompt. A ByteDance posiciona o modelo pra publicidade comercial, vídeos explicativos, produção de filme, e-commerce e gaming. Ou seja: pra criador de conteúdo que quer escapar do estágio &ldquo;meme aleatório&rdquo; e começar a entregar peça com uso profissional.</p>
<p>Pra quem quer ver o modelo em ação antes de continuar lendo, recomendo essa visão geral feita pelo Stefan, do canal <a href="https://www.youtube.com/channel/UCRW08KcTVjXEmBzBsVl7XjA"target="_blank" rel="noopener">Stefan 3D AI Lab</a>, que eu já tinha indicado lá no <a href="/2026/01/23/ai-3d-ja-da-pra-modelar-3d-com-prompts/">post sobre modelagem 3D com IA</a>:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/fv9vA6RCNHU"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>A interface principal é o &ldquo;Photo Studio&rdquo; da Dreamina, onde você escolhe o modo de geração e empilha as referências. Por enquanto eu testei só o modo de multi-referência padrão.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/15/seedance/studio.png" alt="A interface do Photo Studio do Seedance 2.0, com painel de upload de referências e configuração de prompt"  loading="lazy" /></p>
<h2>Teste 1: lip-sync com áudio do podcast<span class="hx:absolute hx:-mt-20" id="teste-1-lip-sync-com-áudio-do-podcast"></span>
    <a href="#teste-1-lip-sync-com-%c3%a1udio-do-podcast" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Meu primeiro teste foi simples. Peguei alguns segundos do bumper de abertura do meu podcast <a href="/tags/the-m-akita-chronicles/">The M.Akita Chronicles</a>, que é gerado com IA via <a href="/2026/04/09/como-a-elevenlabs-nao-foi-morta-pelo-qwen3-tts/">pipeline ElevenLabs v3</a>, passei o meu novo avatar em estilo anime como imagem de referência, e pedi pro Seedance fazer o personagem sincronizar boca e gesticular em cima daquele áudio.</p>
<div style="max-width: 100%; margin: 1em 0;">
  <video controls playsinline style="width: 100%; border-radius: 8px;">
    <source src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/15/seedance/test1.mp4" type="video/mp4">
  </video>
  <em>Avatar anime sincronizando boca com áudio do bumper do M.Akita Chronicles</em>
</div>
<p>O resultado é decente. Saiu tudo de uma imagem fixa só. O lip-sync acompanha a fala razoavelmente bem, a expressão tem alguma vida, o gesto da mão entra no momento certo. Mas é o tipo de coisa que rende clipinho curto pro YouTube ou Instagram. Não é animação que você usaria como abertura de um vídeo profissional.</p>
<h2>A função que de fato importa: vídeo de referência<span class="hx:absolute hx:-mt-20" id="a-função-que-de-fato-importa-vídeo-de-referência"></span>
    <a href="#a-fun%c3%a7%c3%a3o-que-de-fato-importa-v%c3%addeo-de-refer%c3%aancia" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>E aqui eu chego no que eu considero o único uso de verdade desses modelos pra trabalho sério: usar <strong>vídeo como referência</strong>. Texto sozinho nunca vai ser preciso o suficiente. Você pode descrever a cena com o vocabulário que quiser, mudar adjetivo, especificar lente, ângulo, framing, e ainda assim cada geração vai te dar algo um pouco diferente. É loteria. Bom pra meme, péssimo pra produção.</p>
<p>A maioria dos amadores se impressiona com qualquer clipe aleatório que sai bonito de primeira, e enche o feed do X e do Instagram com isso. Só que aquilo não é controle. É sorte. Pra cinema, pra publicidade, pra abertura de programa, pra qualquer coisa onde a próxima cena precisa casar com a anterior, você tem que conseguir dizer pro modelo: &ldquo;faça exatamente esse movimento, com exatamente essa câmera&rdquo;. E é aí que o vídeo de referência muda o jogo, porque ele substitui horas de modelagem 3D, rigging, animação e renderização que custariam fortunas em estúdio.</p>
<p>Pro meu teste, eu reciclei o modelo que já tinha gerado lá no <a href="/2026/01/23/ai-3d-ja-da-pra-modelar-3d-com-prompts/">post sobre AI 3D com Hunyuan e Nano Banana</a>, onde testei o quanto dá pra modelar 3D do nada com prompt e ainda imprimir em 3D. Mas pra uma referência mais cinematográfica eu queria algo com animação pronta. Baixei do Sketchfab o modelo <a href="https://sketchfab.com/3d-models/darth-talon-4338105e09704f359c6afcab7e5fce10"target="_blank" rel="noopener">Darth Talon</a>, que tem uma sequência curta de movimento bem feita, só porque achei legal.</p>
<p>Importei o FBX no Blender, montei câmera e luz básica, e fiz uma renderização rápida no Cycles. Nada bonito, é só um esboço pra servir de referência de movimento e enquadramento.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/15/seedance/blender.png" alt="O modelo Darth Talon importado no Blender com câmera e iluminação configuradas pra render rápido no Cycles"  loading="lazy" /></p>
<div style="max-width: 100%; margin: 1em 0;">
  <video controls playsinline style="width: 100%; border-radius: 8px;">
    <source src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/15/seedance/blender-render.mp4" type="video/mp4">
  </video>
  <em>O render rápido no Cycles que vai virar referência de movimento</em>
</div>
<p>Subi pro Seedance esse render como vídeo de referência junto com três imagens em t-pose do personagem (frente, costas, lado esquerdo) pra dar consistência visual:</p>
<div style="display: flex; gap: 8px; flex-wrap: wrap; margin: 1em 0; justify-content: center;">
  <img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/15/seedance/front.jpg" alt="T-pose frontal" style="flex: 1 1 30%; min-width: 140px; max-width: 32%; border-radius: 8px;" />
  <img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/15/seedance/back.jpg" alt="T-pose de costas" style="flex: 1 1 30%; min-width: 140px; max-width: 32%; border-radius: 8px;" />
  <img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/15/seedance/left.jpg" alt="T-pose lateral esquerda" style="flex: 1 1 30%; min-width: 140px; max-width: 32%; border-radius: 8px;" />
</div>
<p>Primeira tentativa, com prompt genérico:</p>
<div style="max-width: 100%; margin: 1em 0;">
  <video controls playsinline style="width: 100%; border-radius: 8px;">
    <source src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/15/seedance/test2.mp4" type="video/mp4">
  </video>
  <em>Primeira geração: o personagem ficou consistente, mas o movimento e a câmera não bateram com a referência</em>
</div>
<p>Não ficou ruim. O personagem mantém identidade, a iluminação melhorou bastante em cima do meu render bruto, e o vídeo é coerente. Só que o movimento e a posição de câmera divergiram bastante da referência. O modelo entendeu &ldquo;ali tem um personagem parecido com esse fazendo algo parecido com aquilo&rdquo;, e improvisou o resto.</p>
<p>Lembrei do tutorial do Stefan: o truque é colocar literalmente no prompt algo como <code>Follow exact motion and camera from reference video</code>. Tentei de novo:</p>
<div style="max-width: 100%; margin: 1em 0;">
  <video controls playsinline style="width: 100%; border-radius: 8px;">
    <source src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/15/seedance/test3.mp4" type="video/mp4">
  </video>
  <em>Segunda geração: instrução explícita pra seguir movimento e câmera da referência</em>
</div>
<p>Bem melhor. Está claramente seguindo a coreografia da referência, o ângulo de câmera bate em vários momentos, e a aparência do personagem ficou mais polida que tudo que eu poderia renderizar à mão num esboço de Cycles. Mas ainda assim não é cópia exata do meu render. Em alguns frames o modelo ainda toma liberdade com timing, posição e enquadramento. Existem outras técnicas de prompting e parâmetros pra ajustar, mas eu parei aqui pra registrar essas primeiras impressões enquanto o lançamento está fresco.</p>
<h2>ComfyUI, Runway e o resto do ecossistema<span class="hx:absolute hx:-mt-20" id="comfyui-runway-e-o-resto-do-ecossistema"></span>
    <a href="#comfyui-runway-e-o-resto-do-ecossistema" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O Seedance 2.0 também já saiu <a href="https://blog.comfy.org/p/seedance-20-is-now-available-in-comfyui"target="_blank" rel="noopener">como nó do ComfyUI na nuvem</a>, o que ajuda muito quem quer encaixar a geração dentro de pipeline maior sem ficar pulando entre interface web. Pra quem já tem pipeline de geração de imagem montado em ComfyUI, isso é bem prático.</p>
<p>E pra quem quer um caminho com volume sem pensar em crédito por geração, a Runway está oferecendo o Seedance 2.0 dentro do <a href="https://www.mindstudio.ai/blog/seedance-2-0-runway-unlimited-plan"target="_blank" rel="noopener">plano Unlimited</a>, que sai por volta de US$ 76/mês no anual ou US$ 95/mês no mensal. &ldquo;Unlimited&rdquo; no caso significa sem cobrança por geração, mas com prioridade de fila menor em horários de pico e cota de armazenamento de saída. Pra quem precisa iterar muito, esse modelo de assinatura faz bem mais sentido que crédito avulso.</p>
<h2>A questão do preço<span class="hx:absolute hx:-mt-20" id="a-questão-do-preço"></span>
    <a href="#a-quest%c3%a3o-do-pre%c3%a7o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A precificação direta do Seedance é em crédito. O plano Standard sai por US$ 24,90/mês no anual ou US$ 49,90/mês no mensal, e te dá 2500 créditos por mês. Cada 10 segundos de vídeo gerado consome 6 créditos.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/15/seedance/pricing.png" alt="Tabela de preços do Seedance 2.0, com planos Standard até o tier mais alto e custos em crédito por segundo de geração"  loading="lazy" /></p>
<p>A conta é cruel. Com 2500 créditos no Standard, dá pra rodar cerca de 416 gerações de 10 segundos por mês. Parece muito, mas lembra do meu próprio teste: foram pelo menos duas tentativas pra chegar perto do que eu queria, e mesmo assim não foi cópia exata do que pedi. Na prática, pra cada cena que você quer entregar bem, é razoável assumir 3 a 5 regerações. Isso derruba o número útil pra algo na faixa de 80 a 140 cenas curtas por mês. Pode até dar pra um criador solo fazendo conteúdo curto. Não dá pra produção que precisa de minutos contínuos de vídeo polido.</p>
<p>Os planos superiores escalam linearmente o número de créditos, mas o problema continua: no preço de hoje, o Seedance 2.0 ainda é ferramenta pra clipe curto e meme bem-feito, ou pra prototipagem de cena antes de mandar pra estúdio de verdade. Não substitui produção profissional contínua. Pra esse perfil, na prática a Runway com Unlimited sai mais em conta. <a href="https://seedance2.ai/pricing"target="_blank" rel="noopener">Confira a tabela de preços completa aqui</a>.</p>
<h2>O que ninguém quer falar: restrição e deepfake<span class="hx:absolute hx:-mt-20" id="o-que-ninguém-quer-falar-restrição-e-deepfake"></span>
    <a href="#o-que-ningu%c3%a9m-quer-falar-restri%c3%a7%c3%a3o-e-deepfake" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Tem dois pontos que eu não quero deixar de fora. O primeiro: o Seedance 2.0 demorou a chegar pro grande público em parte porque a ByteDance está sendo bem mais conservadora que a concorrência na hora de moderar. O modelo bloqueia geração com referência de pessoas reais (celebridades, políticos, figuras públicas) e filtra personagens com IP forte de Disney, Marvel/DC, Nintendo e marcas registradas em geral. Quem quiser detalhe sobre o que passa e o que não passa, e por que a empresa optou por essa postura, tem <a href="https://www.mindstudio.ai/blog/seedance-2-0-content-restrictions-workarounds"target="_blank" rel="noopener">esse artigo da MindStudio explicando os limites</a>. Faz sentido: a ByteDance opera em dezenas de jurisdições, está sob escrutínio regulatório global, e ainda tem o tema espinhoso de Hollywood pressionando o setor inteiro com ações de copyright sobre uso de material protegido em treinamento e geração. O lançamento atrasou e veio com filtro pesado justamente por isso.</p>
<p>Segundo ponto, e mais importante: pra você, leitor comum, a mensagem é que <strong>deepfake deixou de ser hipótese</strong>. Foto na internet já não vale como prova há um bom tempo, porque modelos de imagem como Nano Banana, Hunyuan e congêneres entregam realismo que engana qualquer um. Agora vídeo está na mesma categoria. O que a gente acabou de ver acima, onde com algumas referências e dois prompts dá pra gerar uma cena animada coerente em minutos, é só o começo. A pessoa comum, sem treino, não vai mais conseguir distinguir vídeo gerado de vídeo real só batendo o olho. E os filtros do Seedance só barram o uso aberto e legal. Quem quer fazer mau uso vai sempre encontrar caminho com modelo open source, com workaround, com plataforma menos rígida. Esse é o mundo real agora, e quanto antes a gente assumir isso socialmente, melhor.</p>
<h2>Não, isso não substitui artista de verdade<span class="hx:absolute hx:-mt-20" id="não-isso-não-substitui-artista-de-verdade"></span>
    <a href="#n%c3%a3o-isso-n%c3%a3o-substitui-artista-de-verdade" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Já vou cortar o discurso de sempre antes que ele apareça nos comentários. Não, o Seedance não substitui artista de VFX, diretor, editor, nada disso. Isso aqui é martelo. A ferramenta é a mesma pra todo mundo. O que sai do outro lado depende inteiramente de quem está segurando ela.</p>
<p>Quem estudou enquadramento, ritmo, continuidade, direção de arte, edição, cor, composição, vai usar o Seedance pra acelerar 10 vezes o trabalho que já sabia entregar. Quem não estudou nada disso vai produzir 10 vezes mais rápido o mesmo meme de Instagram que já produzia. <strong>A IA reflete quem você é.</strong> Se você é bom artista, a ferramenta multiplica. Se você só acha que é bom, a ferramenta multiplica a mesmice. Não tem milagre.</p>
<p>E é por isso que essa onda de &ldquo;agora todo mundo vira diretor de cinema com IA&rdquo; é a mesma ladainha que ouvimos com câmera digital, com Photoshop, com After Effects, com Premiere e com qualquer ferramenta poderosa que apareceu nos últimos 30 anos. A barreira técnica cai, a barreira de gosto, repertório e estudo continua exatamente onde estava. Quem é bom fica mais produtivo. Quem não é continua precisando de gente de verdade pra fazer trabalho de verdade.</p>
<h2>Onde isso vai parar<span class="hx:absolute hx:-mt-20" id="onde-isso-vai-parar"></span>
    <a href="#onde-isso-vai-parar" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Seedance 2.0 é claramente um passo na direção certa, mas ainda não é a ferramenta que substitui produção profissional. Texto sozinho continua impreciso, vídeo de referência ajuda mas ainda escapa, e o preço por minuto útil de saída polida é alto pro que entrega. A boa notícia é que a história se repete: Google já tem o Veo, Runway está com modelo próprio e ainda revendendo Seedance, Kling e Hailuo da China continuam puxando, e os modelos open source vão ganhando tração. A OpenAI tinha o Sora, mas descontinuou. Conforme a competição aperta, qualidade sobe e preço cai. Em um ou dois anos a gente deve estar olhando pra esse post e achando primitivo o que acabei de mostrar. Como sempre.</p>
]]></content:encoded><category>midia-generativa</category><category>reviews</category><category>seguranca</category></item><item><title>Como a ElevenLabs Não Foi Morta pelo Qwen3 TTS</title><link>https://akitaonrails.github.io/2026/04/09/como-a-elevenlabs-nao-foi-morta-pelo-qwen3-tts/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/04/09/como-a-elevenlabs-nao-foi-morta-pelo-qwen3-tts/</guid><pubDate>Thu, 09 Apr 2026 08:30:00 -0300</pubDate><description>&lt;p&gt;&lt;strong&gt;TL;DR — Escuta isso e continua lendo:&lt;/strong&gt;&lt;/p&gt;
&lt;audio controls preload="metadata" style="width: 100%; max-width: 640px;"&gt;
&lt;source src="https://makita-news.s3.amazonaws.com/podcasts/episodes/2026-04-06.mp3" type="audio/mpeg"&gt;
Seu navegador não suporta o elemento de áudio. &lt;a href="https://makita-news.s3.amazonaws.com/podcasts/episodes/2026-04-06.mp3"&gt;Baixar o mp3 aqui.&lt;/a&gt;
&lt;/audio&gt;
&lt;p&gt;Esse é o episódio do dia 6 de abril do podcast do &lt;a href="https://akitaonrails.github.io/tags/the-m-akita-chronicles/"&gt;The M.Akita Chronicles&lt;/a&gt;, já gerado com a nova pipeline da ElevenLabs v3. Assina o canal no &lt;a href="https://open.spotify.com/show/7MzG2UB7IAkC3GAwEXEIVD"target="_blank" rel="noopener"&gt;Spotify&lt;/a&gt; pra não perder episódio novo desses.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Quando o Qwen3 TTS foi lançado, pelos idos de janeiro desse ano, todo mundo no Twitter/X e nas newsletters de IA gritou &amp;ldquo;ElevenLabs killer&amp;rdquo;. Tem &lt;a href="https://medium.com/@warpie/qwen3-tts-is-the-first-real-open-source-threat-to-elevenlabs-56ba200ab5ee"target="_blank" rel="noopener"&gt;artigo no Medium&lt;/a&gt; dizendo que é a primeira ameaça open source real à ElevenLabs. Tem &lt;a href="https://byteiota.com/qwen3-tts-3-second-voice-cloning-beats-elevenlabs/"target="_blank" rel="noopener"&gt;post da byteiota&lt;/a&gt; dizendo que a clonagem de voz em 3 segundos bate a ElevenLabs. Tem &lt;a href="https://www.analyticsvidhya.com/blog/2025/12/qwen3-tts-flash-review/"target="_blank" rel="noopener"&gt;análise no Analytics Vidhya&lt;/a&gt; falando que é o TTS open source mais realista já lançado. O consenso da internet entusiasta era: finalmente temos open source que faz frente à ElevenLabs, o jogo virou, é só questão de tempo.&lt;/p&gt;</description><content:encoded><![CDATA[<p><strong>TL;DR — Escuta isso e continua lendo:</strong></p>
<audio controls preload="metadata" style="width: 100%; max-width: 640px;">
  <source src="https://makita-news.s3.amazonaws.com/podcasts/episodes/2026-04-06.mp3" type="audio/mpeg">
  Seu navegador não suporta o elemento de áudio. <a href="https://makita-news.s3.amazonaws.com/podcasts/episodes/2026-04-06.mp3">Baixar o mp3 aqui.</a>
</audio>
<p>Esse é o episódio do dia 6 de abril do podcast do <a href="/tags/the-m-akita-chronicles/">The M.Akita Chronicles</a>, já gerado com a nova pipeline da ElevenLabs v3. Assina o canal no <a href="https://open.spotify.com/show/7MzG2UB7IAkC3GAwEXEIVD"target="_blank" rel="noopener">Spotify</a> pra não perder episódio novo desses.</p>
<hr>
<p>Quando o Qwen3 TTS foi lançado, pelos idos de janeiro desse ano, todo mundo no Twitter/X e nas newsletters de IA gritou &ldquo;ElevenLabs killer&rdquo;. Tem <a href="https://medium.com/@warpie/qwen3-tts-is-the-first-real-open-source-threat-to-elevenlabs-56ba200ab5ee"target="_blank" rel="noopener">artigo no Medium</a> dizendo que é a primeira ameaça open source real à ElevenLabs. Tem <a href="https://byteiota.com/qwen3-tts-3-second-voice-cloning-beats-elevenlabs/"target="_blank" rel="noopener">post da byteiota</a> dizendo que a clonagem de voz em 3 segundos bate a ElevenLabs. Tem <a href="https://www.analyticsvidhya.com/blog/2025/12/qwen3-tts-flash-review/"target="_blank" rel="noopener">análise no Analytics Vidhya</a> falando que é o TTS open source mais realista já lançado. O consenso da internet entusiasta era: finalmente temos open source que faz frente à ElevenLabs, o jogo virou, é só questão de tempo.</p>
<p>Eu resolvi testar no meu próprio fluxo de produção, como de costume. Montei um pipeline inteiro em cima do Qwen3 TTS 1.7B pra gerar o podcast semanal do <a href="/tags/the-m-akita-chronicles/">The M.Akita Chronicles</a>, e documentei os bastidores no <a href="/2026/02/18/servindo-ia-na-nuvem-meu-tts-pessoal-bastidores-do-the-m-akita-chronicles/">post sobre servir IA na nuvem</a>. Quem quiser ver o detalhe de tempo de partida a frio, clonagem de voz, parâmetros de sampling que mudam de um modo pro outro, dá uma olhada nesse link que eu não vou repetir tudo aqui.</p>
<p>A pergunta desse post é diferente. Depois de quase dois meses rodando essa configuração em produção, com episódio indo ao ar toda segunda-feira, ontem à noite eu finalmente desliguei o Qwen3 e passei tudo pra ElevenLabs v3. Vou contar por quê.</p>
<h2>O que não funcionou no Qwen3<span class="hx:absolute hx:-mt-20" id="o-que-não-funcionou-no-qwen3"></span>
    <a href="#o-que-n%c3%a3o-funcionou-no-qwen3" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Entre 15 de fevereiro e 30 de março eu fiz dezenas de commits ajustando o fluxo do podcast: prompts, parâmetros de sampling, ordem de geração, silêncios de referência na amostra de clone de voz, normalização de volume, pronúncia de siglas técnicas. Corrigir a voz do Marvin que cortava a primeira sílaba porque o áudio de referência começava sem silêncio inicial. Afinar a voz do Akita pra ela soar mais confiante e assertiva. Adicionar crossfade entre jingles de seção. Resolver a pronúncia errada de &ldquo;podcast&rdquo; pra ela não sair como &ldquo;pódcast&rdquo;. Mandar o gerador de roteiro preferir português a anglicismo gratuito pro TTS não engasgar. Cada um desses ajustes foi uma sessão de horas escutando áudio, gerando de novo, ajustando parâmetro.</p>
<p>O resultado ficou aceitável. &ldquo;Aceitável&rdquo; no sentido de que eu consegui publicar todo episódio sem ter que regravar nada à mão. Mas escutando com atenção, a voz do Qwen3 tem aquele jeito inconfundível de IA gerando áudio. Intonação meio morta, ritmo uniforme. Em trechos longos, você sente que é máquina falando. Serve pra ir pro ar, mas tá a quilômetros do que você escuta num podcast profissional feito por gente.</p>
<p>O problema pior foi a pronúncia em inglês. Meu podcast cobre notícias de tecnologia, então termos como &ldquo;MCP&rdquo;, &ldquo;RAG&rdquo;, &ldquo;Claude Opus&rdquo;, &ldquo;GPT-5&rdquo;, &ldquo;open source&rdquo; aparecem em toda conversa. O Qwen3 pegava esses termos e pronunciava eles com sotaque brasileiro, tipo &ldquo;ó-péne-ssourssê&rdquo;, coisa assim. Ficava ilegível pro ouvinte. A solução que eu tive que implementar foi mapear manualmente no prompt do LLM que gera o roteiro quais palavras em inglês trocar por equivalente em português. O prompt hoje tem uma seção inteira dividida entre &ldquo;manter em inglês&rdquo; (nomes próprios, marcas, termos já incorporados ao brasileiro) e &ldquo;traduzir pro português&rdquo; (anglicismo gratuito), mais ou menos 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-markdown" data-lang="markdown"><span class="line"><span class="cl">**REPLACE with Portuguese** (common English words that have natural
</span></span><span class="line"><span class="cl">Brazilian Portuguese equivalents):
</span></span><span class="line"><span class="cl"><span class="k">-</span> &#34;update&#34; → &#34;atualização&#34;
</span></span><span class="line"><span class="cl"><span class="k">-</span> &#34;release&#34; → &#34;lançamento&#34;
</span></span><span class="line"><span class="cl"><span class="k">-</span> &#34;feature&#34; → &#34;recurso/funcionalidade&#34;
</span></span><span class="line"><span class="cl"><span class="k">-</span> &#34;deploy&#34; → &#34;implantação&#34; or just &#34;colocar em produção&#34;
</span></span><span class="line"><span class="cl"><span class="k">-</span> &#34;trade-off&#34; → &#34;dilema&#34; or &#34;escolha&#34;
</span></span><span class="line"><span class="cl"><span class="k">-</span> &#34;performance&#34; → &#34;desempenho&#34;
</span></span><span class="line"><span class="cl"><span class="k">-</span> &#34;default&#34; → &#34;padrão&#34;
</span></span><span class="line"><span class="cl"><span class="k">-</span> &#34;insight&#34; → &#34;percepção/sacada&#34;
</span></span><span class="line"><span class="cl"><span class="k">-</span> &#34;skills&#34; → &#34;habilidades&#34;
</span></span><span class="line"><span class="cl"><span class="k">-</span> &#34;approach&#34; → &#34;abordagem&#34;
</span></span><span class="line"><span class="cl">- &#34;highlights&#34; → &#34;destaques&#34;</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>Chamam isso aqui em casa de &ldquo;limpar anglicismo pra o TTS não engasgar&rdquo;. Engraçado porque eu não queria esse nível de restrição no meu roteiro. Queria que a voz simplesmente pronunciasse &ldquo;update&rdquo; quando o contexto natural fosse &ldquo;update&rdquo;. Como o modelo não consegue, tive que mutilar o vocabulário do podcast pra o resultado final ficar escutável. É uma solução paliativa, daquelas que você adiciona torcendo pra poder remover depois quando a tecnologia amadurecer.</p>
<h2>A experiência com a ElevenLabs v3<span class="hx:absolute hx:-mt-20" id="a-experiência-com-a-elevenlabs-v3"></span>
    <a href="#a-experi%c3%aancia-com-a-elevenlabs-v3" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Ontem à tarde abri uma conta na ElevenLabs, comprei o plano Pro (US$99/mês), e comecei a experimentar com o modelo <code>eleven_v3</code>, que saiu em fevereiro desse ano. Trinta minutos depois eu tinha uma prova de conceito rodando, e umas duas horas depois o sistema inteiro do podcast migrou. A diferença de esforço é abissal.</p>
<p>Os detalhes técnicos da migração ficaram documentados num doc interno do projeto, então vou resumir aqui o quadro comparativo que importa:</p>
<table>
  <thead>
      <tr>
          <th>Dimensão</th>
          <th>Qwen3 TTS 1.7B (antigo)</th>
          <th>ElevenLabs <code>eleven_v3</code> (atual)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Qualidade (Akita)</td>
          <td>Boa, clone de áudio real</td>
          <td>Melhor, mesmo clone mas prosódia mais natural</td>
      </tr>
      <tr>
          <td>Emoção inline no roteiro</td>
          <td>Não suporta</td>
          <td><code>[sighs]</code>, <code>[sarcastically]</code>, <code>[excited]</code>, <code>[laughs]</code>, funciona em pt-BR</td>
      </tr>
      <tr>
          <td>Tempo de partida a frio</td>
          <td>5 a 15 min subindo GPU na RunPod antes de cada rodagem</td>
          <td>Zero, chamada HTTPS com resposta imediata</td>
      </tr>
      <tr>
          <td>Vazão</td>
          <td>~1× do tempo real (serializado)</td>
          <td>~6× do tempo real com concorrência 4</td>
      </tr>
      <tr>
          <td>Tempo total pra um episódio de 28 min</td>
          <td>~25 a 30 min</td>
          <td><strong>~4 min</strong></td>
      </tr>
      <tr>
          <td>Superfície operacional</td>
          <td>RunPod, Docker, FastAPI, pesos do Qwen, conta de GPU</td>
          <td>Uma variável de ambiente (<code>ELEVENLABS_API_KEY</code>)</td>
      </tr>
      <tr>
          <td>Custo por episódio</td>
          <td>~$0.08 de GPU</td>
          <td>~$2.70 em créditos ElevenLabs</td>
      </tr>
  </tbody>
</table>
<p>Repara no último ponto. O Qwen3 custa menos de dez centavos de dólar por episódio. A ElevenLabs custa quase trinta vezes mais. E mesmo assim vale a pena. Os outros pontos do quadro resolvem problemas que sugavam horas da minha semana. Eu não preciso mais escrever código pra escalar GPU na nuvem, não preciso esperar a máquina ligar toda vez, não preciso ficar de babá do modelo nem reconstruir a imagem Docker quando o peso muda. A operação virou uma linha de configuração.</p>
<p>E o mais interessante: as tags de emoção no meio do texto. O modelo v3 aceita marcadores tipo <code>[sighs]</code>, <code>[sarcastically]</code>, <code>[dryly]</code>, <code>[excited]</code>, e muda a entonação de acordo. Isso funciona em mais de 70 idiomas, incluindo português do Brasil. Isso transformou a geração do roteiro porque agora eu posso pedir ao LLM que monta o roteiro pra colocar tags emocionais nos momentos certos, o que dá uma vivacidade que o Qwen3 não conseguia entregar nem de longe. Um exemplo concreto do que sai no roteiro depois:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>AKITA: Isso é simples. [dismissive] Quem ainda acredita que Bitcoin
vai morrer não tá prestando atenção.
MARVIN: [sighs] Mais uma semana, mais uma leva de devs confiando
cegamente em pacotes npm. Previsível.</code></pre></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>Eu tenho até duas paletas separadas de tags, uma pro Akita (expressivo mas controlado, usa <code>[excited]</code>, <code>[dismissive]</code>, <code>[emphatic]</code>) e outra pro Marvin (estóico, só <code>[sighs]</code>, <code>[sarcastically]</code>, <code>[tired]</code>, <code>[dryly]</code>). Isso tá tudo codificado nos prompts de geração do roteiro pro LLM saber que personagem pode usar o quê.</p>
<h2>Sobre a voz do Marvin<span class="hx:absolute hx:-mt-20" id="sobre-a-voz-do-marvin"></span>
    <a href="#sobre-a-voz-do-marvin" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pros ouvintes que já se acostumaram com a voz do Marvin, fica tranquilo: eu fiz o clone dele na ElevenLabs usando a mesma amostra de áudio que eu já tinha usado pra treinar no Qwen3. É a mesma voz. Só que agora ela soa ainda melhor, porque o modelo da ElevenLabs captura nuance e prosódia que o Qwen3 não conseguia entregar.</p>
<h2>Escuta aí e me conta<span class="hx:absolute hx:-mt-20" id="escuta-aí-e-me-conta"></span>
    <a href="#escuta-a%c3%ad-e-me-conta" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra provar que o papo é real, aqui tá o episódio de segunda-feira, dia 6 de abril, já gerado com a nova pipeline:</p>
<audio controls preload="metadata" style="width: 100%; max-width: 640px;">
  <source src="https://makita-news.s3.amazonaws.com/podcasts/episodes/2026-04-06.mp3" type="audio/mpeg">
  Seu navegador não suporta o elemento de áudio. <a href="https://makita-news.s3.amazonaws.com/podcasts/episodes/2026-04-06.mp3">Baixar o mp3 aqui.</a>
</audio>
<p>Se você já é ouvinte do podcast no <a href="https://open.spotify.com/show/7MzG2UB7IAkC3GAwEXEIVD"target="_blank" rel="noopener">Spotify</a> e escutou os episódios anteriores feitos com Qwen3, compara e me diz nos comentários se você nota a diferença ou se pra você tanto faz. Eu tô curioso de saber quanto é percepção treinada minha escutando horas de áudio de TTS e quanto é diferença óbvia pra ouvinte casual.</p>
<p>A partir da próxima semana, todos os episódios do podcast serão gerados pela ElevenLabs v3. A newsletter já tá ligada na nova pipeline, os jobs agendados de pré-aquecer a GPU na RunPod foram desativados, e o código legado do Qwen3 fica no repositório como plano B caso um dia o v3 dê problema crônico. Em duas edições de arquivo eu volto pra ele. Provavelmente nunca vou ter que voltar.</p>
<h2>A parte de dublar os vídeos do YouTube<span class="hx:absolute hx:-mt-20" id="a-parte-de-dublar-os-vídeos-do-youtube"></span>
    <a href="#a-parte-de-dublar-os-v%c3%addeos-do-youtube" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Agora o gancho pra segunda metade desse post. No <a href="/2026/04/09/20-anos-de-blog-o-ano-em-que-a-ia-finalmente-me-deixou-traduzir-tudo/">artigo de aniversário que eu publiquei mais cedo hoje</a>, contei que o Claude Code traduziu quase metade do meu blog pra inglês num fim de semana. No mesmo espírito, fui atrás de dublar os vídeos do canal <a href="https://www.youtube.com/@Akitando"target="_blank" rel="noopener">Akitando</a>.</p>
<p>O canal tem 146 episódios, algo como 96 horas de conteúdo técnico em português, e mais de 500 mil inscritos. Eu já tinha as legendas traduzidas (um <code>.srt</code> curado por episódio), e o YouTube até oferece dublagem automática em inglês. Mas o resultado é tipo Google Translate de 2015: entende, passa a ideia, mas ninguém quer ouvir por muito tempo.</p>
<p>Testei as três abordagens de voz da ElevenLabs e só uma servia. Speech-to-Speech converte voz mas não traduz. A API de Dubbing traduz mas cria a voz sozinha, sem deixar forçar um clone específico. Só a Text-to-Speech resolvia: pegar meu <code>.srt</code> em inglês, mandar cada bloco pro endpoint TTS com a minha voz clonada, e montar o áudio alinhado com o vídeo original.</p>
<p>Só que ter o <code>.srt</code> traduzido não basta. Tradução crua de legenda não sobrevive ao TTS. Trechos com código-fonte, URLs, hashes hexadecimais, listas de comandos shell — o modelo entra em modo soletrar e o áudio sai com o dobro da duração esperada. Traduções longas demais estouram a janela de tempo e precisam ser condensadas pra a voz não ficar atropelada. SRTs truncadas precisam ser completadas. E a cada correção, rodar a pipeline de novo, escutar, achar o próximo problema, corrigir, repetir. O processo inteiro foi um ciclo de interrupções, correções manuais e re-runs — longe do &ldquo;aperta o botão e sai dublado&rdquo; que a gente imagina antes de meter a mão.</p>
<p>O grande desafio era o sotaque. Minha voz clonada foi treinada em português brasileiro, então quando tenta falar inglês o sotaque puxado aparece. A ElevenLabs tem a tag <code>[American accent]</code> que funciona em v3, mas em cima de uma voz treinada em outra língua ela é fraca — o sotaque brasileiro ainda saía por baixo. A saída foi treinar uma segunda voz minha, só em inglês. Gravei uns minutos no meu melhor sotaque americano, subi como Instant Voice Clone separado na minha conta, batizei de &ldquo;Akita English&rdquo;, e configurei o pipeline pra usar essa voz por padrão. O resultado sai mais natural, sem precisar de tag nenhuma, e a identidade de voz continua sendo a minha.</p>
<h3>O teto honesto de qualidade da minha voz em inglês<span class="hx:absolute hx:-mt-20" id="o-teto-honesto-de-qualidade-da-minha-voz-em-inglês"></span>
    <a href="#o-teto-honesto-de-qualidade-da-minha-voz-em-ingl%c3%aas" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Vamos ser francos. Eu sou brasileiro falando inglês, não sou nativo, e não tenho tempo nem paciência pra treinar pronúncia por horas. O clone só consegue ser tão bom quanto a amostra original — se a amostra é um não-nativo lendo um roteiro, o clone herda as imperfeições. Nenhum clone vai me fazer soar como &ldquo;Fabio falando inglês perfeito&rdquo;, porque esse som não existe pra o modelo imitar.</p>
<p>Pra chegar na versão que tá rodando, gravei cinco amostras de treino diferentes ao longo do dia, cada uma com ritmo e roteiro diferentes, e rodei um A/B ao vivo comparando com o original em português. Nenhuma soou como nativo, e nunca foi esse o objetivo. A meta realista era mais modesta: soar reconhecivelmente como eu, ler conteúdo técnico sem tropeçar, e aguentar um episódio inteiro sem cansar o ouvinte. O vencedor acabou sendo a primeira iteração, a &ldquo;Akita English&rdquo; original. Longe de perfeito, mas suficiente pra colocar no ar. Trocar no futuro é literalmente uma linha no arquivo de configuração.</p>
<p>O que mais me surpreendeu no caminho foi perceber que o ritmo da amostra importa mais que o timbre. O clone aprende a cadência de quem gravou: a iteração 5 ficou 25% mais lenta que a iteração 2 lendo exatamente o mesmo texto, só porque eu gravei aquela amostra mais devagar. Pra dublagem de vídeo tech, o alvo certo é ritmo de explicação de YouTube, vivo, uns 150 palavras por minuto. Nada de ritmo de audiobook.</p>
<h3>Como eu alinho o áudio com o vídeo original<span class="hx:absolute hx:-mt-20" id="como-eu-alinho-o-áudio-com-o-vídeo-original"></span>
    <a href="#como-eu-alinho-o-%c3%a1udio-com-o-v%c3%addeo-original" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Um ponto não óbvio: texto em inglês tende a ser mais longo ao falar do que o português equivalente. Se você simplesmente gera o áudio de cada legenda e cola no tempo original, o dub vai se acumulando. Com 30 minutos de vídeo, você já tá vários segundos fora de sincronismo.</p>
<p>Minha abordagem foi atacar o problema em camadas. A primeira versão dividia o SRT em blocos menores, chamados de &ldquo;chunks&rdquo;. Cada chunk tinha no máximo 700 caracteres (pra v3 não alucinar) e só podia cortar em fim de frase, nunca no meio. Um algoritmo simples acumulava legendas num buffer até chegar perto do teto, depois voltava procurando a última legenda do buffer que terminava com ponto, exclamação ou interrogação, e fazia flush só até ali. O resto das legendas já acumuladas ficava pra compor o próximo chunk. Cada chunk guardava o timestamp de início e fim das legendas que cobria, pra a montagem saber exatamente onde posicionar aquele pedaço de áudio depois.</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-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Pra cada nova legenda que chega, checa se adicionar ela</span>
</span></span><span class="line"><span class="cl"><span class="c1"># estouraria o limite do chunk atual.</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">cue</span> <span class="ow">in</span> <span class="n">cues</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">projected</span> <span class="o">=</span> <span class="n">buffer_char_len</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">cue</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">projected</span> <span class="o">&gt;</span> <span class="n">max_chars</span> <span class="ow">and</span> <span class="n">buf</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># Procura a última legenda do buffer que termina</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># com pontuação final (&#39;.&#39;, &#39;!&#39;, &#39;?&#39;, &#39;…&#39;).</span>
</span></span><span class="line"><span class="cl">        <span class="n">sentence_end</span> <span class="o">=</span> <span class="n">last_sentence_end_index</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">sentence_end</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">buf</span> <span class="o">=</span> <span class="n">flush</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="n">sentence_end</span><span class="p">,</span> <span class="n">chunks</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># Run-on maior que max_chars sem fim de frase.</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># Raro, mas acontece. Avisa e corta mesmo assim.</span>
</span></span><span class="line"><span class="cl">            <span class="n">log</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&#34;run-on sentence &gt; </span><span class="si">%d</span><span class="s2"> chars — &#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s2">&#34;splitting mid-sentence as a last resort&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="n">max_chars</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">buf</span> <span class="o">=</span> <span class="n">flush</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">buf</span><span class="p">),</span> <span class="n">chunks</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">buf</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">cue</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Soft-break: se o buffer já tá pelo menos 60% cheio E</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># a legenda atual terminou uma frase, esvazia agora.</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Mantém os chunks balanceados em torno de 60 a 100% do max.</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">cue</span><span class="o">.</span><span class="n">ends_sentence</span> <span class="ow">and</span> <span class="n">buffer_char_len</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">max_chars</span> <span class="o">*</span> <span class="mf">0.6</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">buf</span> <span class="o">=</span> <span class="n">flush</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">buf</span><span class="p">),</span> <span class="n">chunks</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>
<p>Tecnicamente, esse foi o ponto de virada: em vez de deixar a estrutura da dublagem seguir a estrutura visual da legenda, o chunker passou a seguir a estrutura real dos parágrafos do roteiro. Não vou repetir aqui toda a novela de como cheguei nisso e por que isso acabou forçando rerender em massa, porque volto nessa história mais abaixo, na parte dos problemas que só apareceram depois do primeiro upload. O ponto técnico aqui é simples: quando a janela passou a representar um parágrafo falado de verdade, o áudio começou a soar natural e o alvo de stretch pôde subir de 92% pra 95%.</p>
<p>Feito isso, ainda sobra o problema do inglês ser mais longo ao falar que o português equivalente. Aqui a sacada é prever se um chunk vai estourar a janela alvo <strong>antes</strong> de gerar o áudio. Se a razão <code>caracteres / 16 caracteres-por-segundo</code> já passa da duração alvo com uma margem, a pipeline manda o parâmetro <code>speed</code> direto pra API da ElevenLabs, pedindo pro modelo gerar o áudio nativamente mais rápido. Isso preserva a prosódia muito melhor do que comprimir depois. O teto é 1.15× (acima disso a voz começa a soar atropelada).</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-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># antes de chamar a API, prevê se vai estourar</span>
</span></span><span class="line"><span class="cl"><span class="n">expected_sec</span> <span class="o">=</span> <span class="n">char_count</span> <span class="o">/</span> <span class="n">EXPECTED_CHARS_PER_SEC</span>  <span class="c1"># 16 chars/s</span>
</span></span><span class="line"><span class="cl"><span class="n">predicted_ratio</span> <span class="o">=</span> <span class="n">expected_sec</span> <span class="o">/</span> <span class="n">target_sec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">voice_speed</span> <span class="o">=</span> <span class="mf">1.0</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="n">predicted_ratio</span> <span class="o">&gt;</span> <span class="n">PREEMPTIVE_SPEED_THRESHOLD</span><span class="p">:</span>   <span class="c1"># 1.05</span>
</span></span><span class="line"><span class="cl">    <span class="n">voice_speed</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">predicted_ratio</span> <span class="o">*</span> <span class="mf">0.98</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                      <span class="n">PREEMPTIVE_SPEED_MAX</span><span class="p">)</span>         <span class="c1"># cap em 1.15</span>
</span></span><span class="line"><span class="cl">    <span class="n">voice_settings</span><span class="p">[</span><span class="s2">&#34;speed&#34;</span><span class="p">]</span> <span class="o">=</span> <span class="n">voice_speed</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>Mesmo com o <code>speed</code> preventivo ligado, às vezes o áudio gerado ainda fica um pouquinho mais longo do que a janela alvo. Pra isso existe uma segunda rede de proteção: medir o áudio real com <code>ffprobe</code> depois de gerado, comparar com a janela alvo, e aplicar o filtro <code>atempo</code> do <code>ffmpeg</code> pra comprimir no pós-processo se passou de 2% de tolerância, com teto de 1.20×. A combinação do <code>speed</code> nativo (1.15×) com o <code>atempo</code> (1.20×) dá uma compressão efetiva de até 1.38×, suficiente pra caber naturalmente mesmo nos casos mais extremos sem quebrar qualidade.</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-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># depois de gerar o chunk</span>
</span></span><span class="line"><span class="cl"><span class="n">actual</span> <span class="o">=</span> <span class="n">ffprobe_duration</span><span class="p">(</span><span class="n">chunk_path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">ratio</span> <span class="o">=</span> <span class="n">actual</span> <span class="o">/</span> <span class="n">target_sec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="n">ratio</span> <span class="o">&gt;</span> <span class="n">FIT_TOLERANCE</span><span class="p">:</span>       <span class="c1"># 1.02</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># comprime o áudio sem mexer no pitch</span>
</span></span><span class="line"><span class="cl">    <span class="n">ffmpeg_atempo</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">ratio</span><span class="p">,</span> <span class="n">FIT_MAX_ATEMPO</span><span class="p">)</span>   <span class="c1"># 1.20</span>
</span></span><span class="line"><span class="cl">    <span class="n">apply_atempo</span><span class="p">(</span><span class="n">chunk_path</span><span class="p">,</span> <span class="n">ffmpeg_atempo</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>
<p>Quando um chunk gerado fica mais curto que a janela alvo, o pipeline estende o áudio levemente (sem afetar pitch) pra reduzir o silêncio feio depois que ele termina. O objetivo não é preencher a janela inteira, uma pausa natural entre frases é boa, mas suavizar os casos mais gritantes de silêncio que dariam a impressão de &ldquo;áudio cortado&rdquo;.</p>
<p>Num episódio grande, 95 minutos, 194 chunks, o desvio cumulativo total ficou em -0,7%. Uns 43 segundos de drift ao longo do episódio inteiro, imperceptível enquanto você assiste.</p>
<p>O que salvou o orçamento nessa arquitetura é que cada chunk fica salvo individualmente no disco como um <code>.mp3</code> separado. A pipeline mantém um manifesto com o texto normalizado de cada chunk, e antes de chamar a API da ElevenLabs, compara o texto atual com o cache. Se o texto não mudou, reutiliza o áudio já gerado sem gastar crédito nenhum. Se eu reescrevo uma cue problemática, só os chunks afetados por aquela cue são regenerados — o resto do episódio fica intacto.</p>
<p>Isso é o que viabilizou as iterações. Eu rodava o batch, escutava trechos, identificava um problema (tradução longa demais, snippet de código que o TTS não conseguia pronunciar, chunking que cortou num ponto ruim), corrigia o SRT ou ajustava os parâmetros do chunker, e rodava de novo. Cada re-run consumia uma fração dos créditos e do tempo do run original, porque só os chunks alterados eram regenerados. Sem esse cache, cada iteração teria custado quase o mesmo que a primeira rodada, e o custo total do batch teria sido duas ou três vezes maior.</p>
<p>Essa mudança de chunking também teve impacto pesado no cache e no custo, mas deixo essa parte pro trecho mais abaixo onde explico a sequência de retrabalho. Aqui basta dizer que, do ponto de vista técnico, era a mudança certa.</p>
<h3>Quando o <code>atempo</code> não salva: reescrevendo cue antes do TTS<span class="hx:absolute hx:-mt-20" id="quando-o-atempo-não-salva-reescrevendo-cue-antes-do-tts"></span>
    <a href="#quando-o-atempo-n%c3%a3o-salva-reescrevendo-cue-antes-do-tts" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Nem tudo é questão de alinhamento de janela. Tem um tipo de cue que quebra o pipeline inteiro, onde nem <code>speed</code> preventivo nem <code>atempo</code> no pós-processo resolvem, e eu só esbarrei nisso quando comecei a rodar o batch nos episódios mais técnicos do canal.</p>
<p>O problema é o seguinte. O v3 lê a uns 16 caracteres por segundo quando você entrega texto normal de conversa. Mas quando você entrega uma cue recheada de URL literal, hash hexadecimal, string binária, uma lista de números ordenados ou um bloco de código shell, o modelo entra em modo &ldquo;soletrar letra por letra&rdquo; e despenca pra uns 9 caracteres por segundo. Uma cue de 500 caracteres que devia virar 30 segundos de áudio vira 55. A checagem de sanidade derruba (porque passou de 1.8×), o retry automático tenta de novo com os mesmos 500 caracteres, os cinco retries falham seguidos, e o chunk fica preso.</p>
<p>E isso não aconteceu por acaso. Eu escrevia desse jeito porque sabia que esses mesmos roteiros depois virariam post no blog, então fazia sentido deixar a URL crua, o comando completo, o hash inteiro, o detalhe técnico todo mastigado pro leitor. Em português isso funcionava bem porque era exatamente o meu fluxo original: gravar o vídeo e depois publicar o texto correspondente no blog. O que eu nunca tinha preparado era a etapa seguinte, de transformar esse mesmo material em dublagem automatizada pra inglês. Eu só fui perceber esse conflito quando a pipeline começou a falhar de verdade.</p>
<p>Peguei isso primeiro no ep052, o guia de Ubuntu pra devs iniciantes, onde duas cues traziam URLs do <code>github.com</code>, URLs <code>hkp://keyserver.ubuntu.com</code> e um hash GPG de 40 caracteres. Tentar resolver no pós-processo seria perda de tempo. O teto de 1.20× do <code>atempo</code> nunca vai comprimir 55 segundos em 30, e mesmo se conseguisse ia sair num chipmunk ilegível. A saída é atacar antes, no texto.</p>
<p>A solução foi reescrever a cue dizendo o que o comando faz, em vez de mostrar o comando literal:</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-diff" data-lang="diff"><span class="line"><span class="cl"><span class="gd">- Rode: apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 \
</span></span></span><span class="line"><span class="cl"><span class="gd">-   --recv-keys 0A6A3E7F79F93EF8AAB9E92BAEBB74C8B5A1E44D
</span></span></span><span class="line"><span class="cl"><span class="gi">+ Rode o comando completo que tá na descrição do vídeo pra importar
</span></span></span><span class="line"><span class="cl"><span class="gi">+ a chave de assinatura do repositório do keyserver do Ubuntu.
</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>A legenda em inglês no vídeo continua mostrando o comando inteiro na tela, então quem lê a legenda vê o que precisa digitar. O áudio dublado descreve a intenção em linguagem falada, que é o que o TTS entrega sem engasgar. A instrução pro ouvinte fica intacta, e o caractere-por-segundo volta pros 16 esperados, então o áudio gerado cabe na janela original sem precisar esticar nem comprimir nada no pós.</p>
<p>Saí caçando cue assim em todos os episódios do batch. Varri do ep052 ao ep146 procurando cues com densidade alta de caractere &ldquo;duro&rdquo; (dígitos, colchetes, operadores, URLs longas, binário, hex) e acabei reescrevendo umas 30 cues em 13 episódios:</p>
<ul>
<li>ep052 Ubuntu pra devs: URLs do GitHub e hash GPG de 40 caracteres</li>
<li>ep091 Hello World em C: exemplos binários</li>
<li>ep095 Memória 640kB: wrap de endereço, segment-offset</li>
<li>ep106 CodeMiner: endereço de e-mail soletrado</li>
<li>ep113 Compressão: strings de binário puro, 75% de caractere duro</li>
<li>ep115 SQL Server: lista longa de números ordenados</li>
<li>ep120 Internet: endereços IP com pontos</li>
<li>ep121 Sockets: dois blocos de código JavaScript</li>
<li>ep122 Proxies: headers User-Agent do Chrome</li>
<li>ep123 Rede segura: one-liners shell, flags do Docker</li>
<li>ep126 Gentoo: demo de <code>chroot</code> em C</li>
<li>ep136 Containers: URL de release do GitHub</li>
<li>ep144 Criptografia: endereço de signing key</li>
</ul>
<p>O padrão foi sempre o mesmo: mantém a legenda exibindo o código, a URL ou o hash na íntegra, e reescreve o texto pro narrador descrever o que aquilo faz. Eu podia ter automatizado a reescrita, deixando um LLM ler a cue e propor uma substituição no voo, só que achei mais seguro revisar tudo manualmente. É exatamente o tipo de coisa onde o modelo resolve &ldquo;melhorar&rdquo; um comando pra deixá-lo mais limpo e sai com shell errado. A varredura manual levou umas duas horas. A automática teria custado o mesmo tempo em revisão, com o bônus da ansiedade de ter deixado passar algum comando mutilado.</p>
<p>Teve também um caso estrutural esquisito no ep146, sobre Docker Compose. Duas cues ficaram grudadas por causa de uma linha em branco faltando no SRT, e o <code>pysrt</code> tratava as duas como uma única cue gigante. O TTS nem chegava a processar, o chunker engasgava antes. Corrigi à mão adicionando a linha em branco que faltava. Fix de um caractere, meia hora pra rastrear.</p>
<h3>Reconstruindo SRTs truncadas<span class="hx:absolute hx:-mt-20" id="reconstruindo-srts-truncadas"></span>
    <a href="#reconstruindo-srts-truncadas" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Outra armadilha apareceu quando fui rodar o batch completo: três episódios tinham legendas em inglês curtas demais em relação à duração real do vídeo. O ep056, sobre Rails, era o caso mais absurdo. Dezenove minutos de legenda pra um vídeo de 80 minutos. Sessenta e dois minutos de conteúdo sem legenda nenhuma. O ep057 (WSL 2) tinha 14 minutos faltando, e o ep068 (Git Direito) tinha 2.</p>
<p>Isso é rastro do meu fluxo de tradução antigo. Em algum momento eu comecei a revisar a legenda manualmente, parei no meio, e o arquivo <code>.en.srt</code> ficou salvo truncado no ponto onde eu parei. Não dá pra dublar um vídeo de 80 minutos com legenda de 19. O chunker gera áudio até onde consegue ler e simplesmente não sabe o que fazer com o resto do vídeo.</p>
<p>A solução virou um script novo. Ele faz diff entre o <code>.en.srt</code> truncado e o <code>.pt-orig.srt</code> (o auto-caption bruto do YouTube, que sempre cobre o vídeo inteiro), pega as cues que existem só em português, manda pro Claude Sonnet 4.6 com um schema JSON rígido pedindo tradução cue a cue, e cola o resultado de volta no fim do arquivo em inglês. O schema é o detalhe que importa. Quando eu tentei pedir a resposta em texto no formato <code>N|texto</code>, o Claude deixava cair umas 20% das cues no caminho. Com um schema JSON estrito, a taxa de drop caiu pra zero nos três reparos.</p>
<p>O resultado em números:</p>
<ul>
<li>ep068 Git Direito: +50 cues / 2 minutos reconstruídos</li>
<li>ep057 WSL 2: +368 cues / 14 minutos</li>
<li>ep056 Rails: +1445 cues / 62 minutos (e ainda drop de 5 cues falsas que o tradutor antigo tinha inventado no fim pra tampar a saída)</li>
</ul>
<p>Depois dos reparos, os três episódios entraram no batch normalmente e foram dublados como qualquer outro. Tipo de ferramenta que você espera nunca precisar, só que quando precisa, compensa escrever uma vez e resolver o problema inteiro de uma vez.</p>
<h3>Tags de emoção automáticas<span class="hx:absolute hx:-mt-20" id="tags-de-emoção-automáticas"></span>
    <a href="#tags-de-emo%c3%a7%c3%a3o-autom%c3%a1ticas" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Enquanto eu tava testando, resolvi adicionar mais um passo no pipeline: um &ldquo;emotion tagger&rdquo; que lê o SRT em inglês antes de mandar pro TTS e insere tags tipo <code>[sarcastic]</code>, <code>[thoughtful]</code>, <code>[emphatic]</code>, <code>[deadpan]</code> em pontos onde um narrador humano naturalmente mudaria o tom. A ideia é imitar o que um ator profissional faria, colocar ênfase nos momentos certos, sem transformar o vídeo num teatro de emoções exageradas.</p>
<p>Essa parte é delicada por dois motivos. O primeiro: deixar um LLM solto editando o SRT tem risco real de ele &ldquo;melhorar&rdquo; o texto (trocar uma palavra aqui, reescrever uma frase ali) e você acabar com uma dublagem que não bate com a legenda. O segundo: LLM adora exagerar. Se você pedir pra marcar emoção, ele vai colocar tag em toda segunda frase. Pra evitar os dois, eu fixei uma lista pequena de tags permitidas e rodo uma validação de round-trip depois que a resposta do Claude chega:</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-python" data-lang="python"><span class="line"><span class="cl"><span class="n">ALLOWED_TAGS</span><span class="p">:</span> <span class="nb">frozenset</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;[sarcastic]&#34;</span><span class="p">,</span> <span class="s2">&#34;[thoughtful]&#34;</span><span class="p">,</span> <span class="s2">&#34;[emphatic]&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;[deadpan]&#34;</span><span class="p">,</span> <span class="s2">&#34;[serious]&#34;</span><span class="p">,</span> <span class="s2">&#34;[amused]&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;[sighs]&#34;</span><span class="p">,</span> <span class="s2">&#34;[exasperated]&#34;</span><span class="p">,</span> <span class="s2">&#34;[confident]&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;[matter-of-fact]&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">validate_tagged</span><span class="p">(</span><span class="n">original</span><span class="p">,</span> <span class="n">tagged</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Garante que o SRT com tags preserva o original sem drift.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">original</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">tagged</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">raise</span> <span class="n">TagValidationError</span><span class="p">(</span><span class="s2">&#34;cue count mismatch&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">o</span><span class="p">,</span> <span class="n">t</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">original</span><span class="p">,</span> <span class="n">tagged</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># O index e o timestamp têm que bater byte a byte.</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">o</span><span class="o">.</span><span class="n">index</span> <span class="o">!=</span> <span class="n">t</span><span class="o">.</span><span class="n">index</span> <span class="ow">or</span> <span class="n">o</span><span class="o">.</span><span class="n">timestamp</span> <span class="o">!=</span> <span class="n">t</span><span class="o">.</span><span class="n">timestamp</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">raise</span> <span class="n">TagValidationError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;cue </span><span class="si">{</span><span class="n">o</span><span class="o">.</span><span class="n">index</span><span class="si">}</span><span class="s2">: header drift&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1"># Qualquer tag fora da whitelist invalida tudo.</span>
</span></span><span class="line"><span class="cl">        <span class="n">bad</span> <span class="o">=</span> <span class="n">find_disallowed_tags</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">bad</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">raise</span> <span class="n">TagValidationError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;cue </span><span class="si">{</span><span class="n">o</span><span class="o">.</span><span class="n">index</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">bad</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1"># O texto sem as tags tem que ser idêntico ao original.</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># Se o LLM trocou uma palavra, reescreveu algo, a</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># validação quebra e a resposta é rejeitada.</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">strip_tags</span><span class="p">(</span><span class="n">o</span><span class="o">.</span><span class="n">text</span><span class="p">)</span> <span class="o">!=</span> <span class="n">strip_tags</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">text</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="k">raise</span> <span class="n">TagValidationError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;cue </span><span class="si">{</span><span class="n">o</span><span class="o">.</span><span class="n">index</span><span class="si">}</span><span class="s2">: text drift&#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>
<p>Quando a validação quebra, a pipeline ignora a resposta e reemite o request (ou, se falhar muito, sobe o SRT sem tags mesmo). Sobre a quantidade de tags, o prompt que vai pro Claude diz explicitamente: mira em <code>N/10</code> tags pra um SRT de N legendas, chão de 1 tag a cada 12, teto de 1 tag a cada 7, distribuição equilibrada entre os quatro quartos do episódio, nunca duas tags adjacentes a menos de 4 legendas uma da outra. Esse conjunto de regras foi a sexta iteração — as cinco anteriores ou enchiam tudo de tag ou concentravam no começo do vídeo.</p>
<h3>Não deixe a v3 alucinar<span class="hx:absolute hx:-mt-20" id="não-deixe-a-v3-alucinar"></span>
    <a href="#n%c3%a3o-deixe-a-v3-alucinar" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Um detalhe crítico que só aparece em produção: a ElevenLabs v3 tende a alucinar quando você manda blocos de texto muito longos. Já peguei blocos onde o texto tinha uns 1.500 caracteres e o modelo gerou um áudio com <strong>nove minutos</strong> quando o esperado era um minuto e meio. O modelo simplesmente resolve continuar falando sozinho, inventando conteúdo.</p>
<p>A documentação oficial da ElevenLabs recomenda manter cada chamada abaixo de 800 caracteres pra evitar isso. Eu fui mais conservador e cortei em 700, sempre em fim de frase (nunca no meio de uma sentença, porque o corte no meio soa horrível quando concatena). Depois disso, subi o parâmetro <code>stability</code> pra 0.9 (modo Robust, mais estável porém menos responsivo a tags de emoção), liguei o <code>apply_text_normalization</code> pra o modelo pronunciar números e siglas direito, e adicionei uma verificação de sanidade que rejeita qualquer áudio gerado que passe de 1.8× da duração esperada.</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-python" data-lang="python"><span class="line"><span class="cl"><span class="n">DEFAULT_VOICE_SETTINGS</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;stability&#34;</span><span class="p">:</span> <span class="mf">0.9</span><span class="p">,</span>          <span class="c1"># modo Robust</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;similarity_boost&#34;</span><span class="p">:</span> <span class="mf">0.95</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;style&#34;</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;use_speaker_boost&#34;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">EXPECTED_CHARS_PER_SEC</span> <span class="o">=</span> <span class="mf">16.0</span>
</span></span><span class="line"><span class="cl"><span class="n">CHUNK_SANITY_MAX_FACTOR</span> <span class="o">=</span> <span class="mf">1.8</span>   <span class="c1"># rejeita se actual &gt; 1.8× esperado</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>Depois dessas mitigações, um episódio de 95 minutos (194 blocos) rodou do começo ao fim sem nenhuma alucinação. Exatamente um bloco falhou por erro 502 transitório da API, que o retry automático pegou na tentativa seguinte.</p>
<h3>Masterização pro YouTube<span class="hx:absolute hx:-mt-20" id="masterização-pro-youtube"></span>
    <a href="#masteriza%c3%a7%c3%a3o-pro-youtube" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O YouTube não publica número oficial, mas o consenso da indústria é que a normalização de volume dele na hora da reprodução mira em -14 LUFS. Se você entregar áudio mais alto que isso, o YouTube baixa; se entregar mais baixo, ele deixa como tá. Pra bater o alvo exato, o pipeline roda o filtro <code>loudnorm</code> do <code>ffmpeg</code> em duas passadas. A primeira mede o áudio inteiro e imprime as estatísticas (<code>input_i</code>, <code>input_tp</code>, <code>input_lra</code>, <code>input_thresh</code>) em formato JSON no stderr. A segunda passada lê essas estatísticas de volta e aplica um ganho estático linear pra pousar exato em -14 LUFS, -1.5 dBTP:</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="c1"># Passada 1: medir</span>
</span></span><span class="line"><span class="cl">ffmpeg -i final_en.mp3 <span class="se">\
</span></span></span><span class="line"><span class="cl">  -af <span class="s2">&#34;highpass=f=80,loudnorm=I=-14:TP=-1.5:LRA=9:print_format=json&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  -f null -
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Passada 2: aplicar ganho linear com os valores medidos</span>
</span></span><span class="line"><span class="cl">ffmpeg -i final_en.mp3 <span class="se">\
</span></span></span><span class="line"><span class="cl">  -af <span class="s2">&#34;highpass=f=80,loudnorm=I=-14:TP=-1.5:LRA=9\
</span></span></span><span class="line"><span class="cl"><span class="s2">:measured_I=-18.3:measured_TP=-3.1:measured_LRA=5.4\
</span></span></span><span class="line"><span class="cl"><span class="s2">:measured_thresh=-28.7:offset=1.2:linear=true&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  -ar <span class="m">48000</span> -ac <span class="m">2</span> -c:a pcm_s16le final_en_mastered.wav</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>Duas passadas em vez de uma porque o modo de passada única roda em compressão dinâmica e acaba &ldquo;bombeando&rdquo; o ganho em trechos com muito silêncio. Com <code>linear=true</code> na passada 2, o ganho fica estático em cima das medições da passada 1, então não tem bombeamento. O resultado pousa dentro de ±0.1 LU do alvo, que é praticamente inaudível. O filtro <code>highpass=f=80</code> na frente derruba rumble de ar-condicionado e hum de rede elétrica abaixo de 80 Hz, que o ouvido humano não escuta mas mexe nas medições de pico.</p>
<h3>O ponto em que eu achei que estava pronto. E não estava.<span class="hx:absolute hx:-mt-20" id="o-ponto-em-que-eu-achei-que-estava-pronto-e-não-estava"></span>
    <a href="#o-ponto-em-que-eu-achei-que-estava-pronto-e-n%c3%a3o-estava" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Aqui entra a parte mais chata, e mais educativa, do projeto.</p>
<p>Eu realmente achei que tinha acertado a mão na primeira grande rodada. A pipeline fechou os 146 episódios, eu subi tudo, e parecia resolvido. A duração batia, os arquivos estavam todos lá, o processo inteiro tinha finalmente atravessado o lote completo de quase 96 horas de vídeo. Só que foi justamente depois do upload que comecei a perceber problemas que eu simplesmente não tinha antecipado.</p>
<p>O primeiro susto foi a situação dos jingles. Eu já sabia que muitos episódios do Akitando começam com aquele jingle instrumental curto antes de eu começar a falar, mas subestimei o problema. O <code>.srt</code> do YouTube praticamente não ajuda nisso, porque jingle não é fala. Às vezes ele marca como <code>[Música]</code>, às vezes não marca nada útil, às vezes a janela fica torta. Na primeira montagem, teve episódio onde o jingle sumiu, episódio onde ele entrou duplicado, e episódio onde o source-fill do áudio original já trazia o jingle certo e o meu splice vinha por cima, empurrando todo o resto pra frente. Foi o tipo de bug que só aparece quando você para pra escutar a master final de verdade, não quando olha só pra duração total.</p>
<p>A solução foi abandonar a esperança de que a legenda me diria onde estava o jingle e ir direto pra fonte. Montei um detector usando os próprios áudios originais dos vídeos e jingles de referência, com auditoria e repair pass em cima dos masters já gerados. Isso acabou virando um mini-sistema próprio: detector, auditoria, reassemble por cache, correção por janela exata. No fim dessa novela, o batch de episódios alterados caiu num conjunto de reupload bem definido e o problema dos jingles ficou finalmente sob controle. Foi um daqueles casos clássicos de produção: a primeira solução parecia suficiente até bater no acervo inteiro.</p>
<p>Só que aí veio a segunda pancada, e essa foi mais cara: eu tinha esquecido de um detalhe fundamental sobre legendas de YouTube. SRT é feita pra ser lida na tela, não pra virar roteiro de fala. Então uma ideia que no meu texto original era um parágrafo inteiro aparecia quebrada em várias cues pequenas, cada uma com sua microjanela de tempo. Na primeira versão da pipeline eu estava usando essas cues como unidade de geração na ElevenLabs. Resultado: o TTS gerava áudio em blocos coerentes localmente, mas a montagem introduzia silêncios artificiais no meio da frase. Tecnicamente alinhado, humanamente esquisito.</p>
<p>O conserto foi doloroso porque exigiu voltar várias casas. Em vez de respeitar a estrutura das cues do SRT, precisei voltar pros meus textos originais e reconstruir o chunking com base nos parágrafos que eu realmente li quando gravei os vídeos. Quase todo episódio do Akitando tem o post correspondente com a seção <code>## Script</code>, e isso salvou o projeto. Como eu fui meticuloso na época em que produzi os vídeos — escrevendo os roteiros antes, lendo exatamente aquilo na gravação e arquivando tanto os vídeos quanto os scripts — eu tinha a fonte de verdade. Então deu pra mapear os parágrafos do script aos timings do <code>.pt-BR.srt</code>, reagrupar o <code>.en.srt</code> em cima disso e regenerar os chunks no formato certo.</p>
<p>O problema é que essa mudança destrói o cache anterior. Mesmo quando o texto quase não muda, se a fronteira do chunk muda, a chamada ao TTS muda junto: muda contexto, muda prosódia, muda começo, muda fim. Então não era um retoquezinho. Era uma regeneração completa de tudo de novo. Foi aí que o custo começou a sair do meu controle inicial.</p>
<p>E quando eu achei que agora sim tinha terminado, veio a terceira paulada: os clipes externos. Muitos vídeos do canal têm trechos inseridos de outras fontes. No episódio de Ruby on Rails, por exemplo, tem 37signals, Apple, comerciais, pedaços externos no meio da narrativa. O <code>.srt</code> do YouTube não sabia lidar direito com isso. Em alguns pontos ele simplesmente alucinava texto, em outros os timings ficavam completamente tortos, em outros a fala original não tinha nada a ver com a legenda que eu estava usando de base. De novo: olhando só pra automação parecia tudo bem; escutando a master final, não estava.</p>
<p>A correção, mais uma vez, foi sair da legenda e voltar pro material original. Montei um detector de janelas de clipe externo a partir de gaps de alinhamento entre transcript, <code>.pt-BR.srt</code>, cues sem fala útil e chunks que atravessavam essas janelas. Depois, em vez de tentar dublar o que não fazia sentido dublar, o processo passou a recuperar o áudio original do vídeo exatamente nesses trechos e preencher a master com o source correto. Foi isso que consertou os casos de 37signals, Apple Education, comercial de Mac vs PC e outros inserts parecidos que eu tinha esquecido que existiam.</p>
<p>Esse foi o aprendizado mais importante dessa segunda metade do projeto: automação te leva muito longe, mas o acervo completo sempre tem mais cantos escuros do que você imagina no primeiro passe.</p>
<h2>Os números do batch de dublagem (e por que doeu mais do que eu imaginei)<span class="hx:absolute hx:-mt-20" id="os-números-do-batch-de-dublagem-e-por-que-doeu-mais-do-que-eu-imaginei"></span>
    <a href="#os-n%c3%bameros-do-batch-de-dublagem-e-por-que-doeu-mais-do-que-eu-imaginei" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Eu preciso me corrigir de novo. Não errei só a primeira conta. Errei também o grau de confiança que eu tinha depois da primeira rodada.</p>
<p>Quando subi pro plano Business da ElevenLabs, eu achei que finalmente estaria com folga. Na prática, não fiquei. O screenshot mais recente do dashboard mostra <strong>10.046.279 créditos consumidos de um limite de 11.000.000</strong>, sobrando <strong>953.721</strong>:</p>
<p><img src="elevenlabs-credits-dashboard.png" alt="Dashboard da ElevenLabs mostrando 10.046.279 créditos consumidos de 11.000.000"  loading="lazy" /></p>
<p>Em português claro: eu torrei mais de 91% do limite do workspace Business. E isso ajuda a entender o que &ldquo;10 milhões de créditos&rdquo; realmente significa nesse contexto. Não é só &ldquo;renderizei 146 episódios uma vez&rdquo;. É renderizar 146 episódios, descobrir um problema estrutural, voltar, corrigir, regenerar chunks, descobrir outro problema estrutural, voltar, reconstruir masters, auditar jingles, reparar janelas de clipes externos, reupar de novo. Cada rodada a mais custa. E quando a mudança invalida o cache, custa muito.</p>
<p>O custo também não para na ElevenLabs. Todo o trabalho de curadoria das legendas, reescrita de cues problemáticas, reconstrução de SRTs truncadas, auditorias de jingle, detector de clipes externos e o resto rodou via Claude Code no plano Claude Max 20×. Somando isso com a tradução em massa do blog pra inglês que eu descrevi no <a href="/2026/04/09/20-anos-de-blog-o-ano-em-que-a-ia-finalmente-me-deixou-traduzir-tudo/">artigo de aniversário</a>, o limite semanal do Claude Max 20× bateu 100%, com gasto extra acima de R$ 300. Pra quem acha que IA generativa vira grátis depois que você assinou o plano, os boletos discordam.</p>
<p>Mesmo assim, continuo achando que vale a pena. Estamos falando de 146 episódios, quase 96 horas de conteúdo técnico, mais de 5 anos de acervo do canal. Fazer isso manualmente em estúdio, com ator, direção, pickup e revisão humana em tudo, custaria uma ordem de grandeza completamente diferente.</p>
<p>O que mudou foi minha visão do projeto. No começo eu tava olhando pra isso como &ldquo;um batch grande&rdquo;. No fim, era outra coisa. Era mexer num acervo inteiro, achar exceção escondida, consertar ferrugem antiga, refazer master, rerender, reouvir.</p>
<p>O primeiro batch completo levou pouco menos de dois dias e me fez pensar que eu tinha resolvido tudo. Não tinha. A segunda rodada, com chunking por parágrafo, já foi cara. A terceira, com os reparos de jingle e os consertos de masters, mais cara ainda. E a quarta pancada veio dos clipes externos que eu não tinha modelado direito na primeira automação.</p>
<p>Mas agora, finalmente, eu acho que acabou. Ou melhor: eu espero que tenha acabado. Tudo foi enviado de novo, pela última vez. Não está perfeito no sentido absoluto da palavra. Está tão bom quanto eu consigo deixar com script, auditoria e automação, sem entrar num inferno de intervenção manual vídeo por vídeo.</p>
<p>E se isso tudo foi possível, é porque anos atrás eu tive a disciplina de produzir os vídeos do jeito certo: escrever primeiro, ler o roteiro quando gravava, e arquivar os materiais depois. Sem os vídeos originais e sem os scripts originais, eu não teria como descobrir onde o <code>.srt</code> mentia, onde o timing estava torto, onde o clipe externo entrava, onde o parágrafo original começava e terminava. Essa organização antiga foi o que permitiu consertar o projeto agora.</p>
<p>Então sim: a dublagem dos 146 episódios está pronta. Não perfeita. Mas fechada. Pelo menos, eu sinceramente espero que agora sim esteja.</p>
<h2>O primeiro teste, assista<span class="hx:absolute hx:-mt-20" id="o-primeiro-teste-assista"></span>
    <a href="#o-primeiro-teste-assista" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Fiz um vídeo teste pra provar que funciona. Dois avisos antes: primeiro, o embed abaixo já carrega com a legenda em inglês ligada por padrão, então esse lado dá pra resolver via URL. Segundo, o áudio é chato: o YouTube removeu o seletor de faixa de áudio dos players embedados lá por março desse ano. Então dentro do embed você não vai encontrar essa opção no menu de engrenagem mesmo, só roda em português. Pra ouvir a dublagem em inglês de verdade, clica em <strong><a href="https://www.youtube.com/watch?v=QNLd8TZ_JQc"target="_blank" rel="noopener">assistir direto no YouTube</a></strong>, que a página principal do YouTube ainda tem o seletor de faixa de áudio no menu de engrenagem.</p>
<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/QNLd8TZ_JQc?cc_load_policy=1&amp;cc_lang_pref=en&amp;hl=en"
    title="Akitando dublado em inglês (teste)"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>
<p>Se você tá acostumado com a dublagem automática do YouTube ou com as dublagens de IA de TikTok, compara. A diferença é gritante. A voz é a minha, com sotaque americano trabalhado, e a sincronização com o vídeo original fica dentro de 1 a 2% de desvio cumulativo, praticamente imperceptível em 95 minutos de vídeo.</p>
<h2>E o que faltava: traduzir as thumbnails<span class="hx:absolute hx:-mt-20" id="e-o-que-faltava-traduzir-as-thumbnails"></span>
    <a href="#e-o-que-faltava-traduzir-as-thumbnails" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Quando eu estava fechando esse post, me caiu a ficha de que tinha deixado uma ponta solta. As 146 thumbnails do meu canal estão em português, muitas com título em caixa alta grande tipo &ldquo;9 DICAS PARA PALESTRANTES&rdquo; ou &ldquo;7 RECOMENDAÇÕES DE SHOWS PARA PESSOAS DE TECH&rdquo;. De nada adianta áudio em inglês perfeito se a imagem que aparece na busca é um bloco de texto ilegível pra quem não lê português. O YouTube permite subir uma thumbnail alternativa por idioma, então eu precisava gerar versões em inglês, mantendo o resto da arte idêntico, trocando só o texto.</p>
<p>A ferramenta usa duas peças. <strong><code>yt-dlp</code></strong> é o fork moderno do antigo <code>youtube-dl</code>, uma CLI em Python que baixa qualquer coisa do YouTube (vídeos, áudios, legendas, thumbnails) sem precisar de API key. <strong>Nano Banana Pro</strong> (<code>nano-banana-pro-preview</code> na API) é o modelo de edição de imagem mais recente do Google Gemini — aceita uma imagem de entrada com um prompt e devolve a imagem editada, preservando o resto da composição quando você pede pra mexer só numa parte.</p>
<p>O pipeline tem dois passos. Passo 1: <code>yt-dlp</code> pega a thumbnail em <code>.jpg</code>, sem baixar o vídeo:</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">yt-dlp --skip-download <span class="se">\
</span></span></span><span class="line"><span class="cl">       --write-thumbnail <span class="se">\
</span></span></span><span class="line"><span class="cl">       --convert-thumbnails jpg <span class="se">\
</span></span></span><span class="line"><span class="cl">       -o <span class="s2">&#34;thumbnails/originals/&lt;slug&gt;/&lt;video_id&gt;&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">       <span class="s2">&#34;https://www.youtube.com/watch?v=&lt;video_id&gt;&#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>Passo 2: mandar cada imagem pro Gemini Nano Banana Pro com um prompt que é um contrato rígido de requisitos duros, não só um &ldquo;traduz isso&rdquo;:</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">TASK:
</span></span><span class="line"><span class="cl">Detect every piece of Portuguese text visible on this image and
</span></span><span class="line"><span class="cl">translate it to clear, natural American English. Replace the
</span></span><span class="line"><span class="cl">Portuguese text with the English translation in the same visual
</span></span><span class="line"><span class="cl">position.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">STRICT REQUIREMENTS — follow every one:
</span></span><span class="line"><span class="cl">- Preserve EVERY non-text element identically: face, pose,
</span></span><span class="line"><span class="cl">  expression, background, color palette, lighting, icons, logos,
</span></span><span class="line"><span class="cl">  decorative shapes, borders, layout. Only the text changes.
</span></span><span class="line"><span class="cl">- The English translation must be IDIOMATIC and CONFIDENT — not
</span></span><span class="line"><span class="cl">  a literal word-for-word rewrite. It&#39;s a YouTube thumbnail for a
</span></span><span class="line"><span class="cl">  tech audience, so use punchy phrasing a native English-speaking
</span></span><span class="line"><span class="cl">  tech YouTuber would write.
</span></span><span class="line"><span class="cl">- Match the original text&#39;s font family, weight, size, color,
</span></span><span class="line"><span class="cl">  stroke outline, drop shadow, and any decorative treatment.
</span></span><span class="line"><span class="cl">- If there is no Portuguese text at all on the image, return the
</span></span><span class="line"><span class="cl">  original image unchanged.</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>A cláusula &ldquo;return the original image unchanged&rdquo; é o que salva os primeiros episódios do canal, que não têm texto na thumbnail, só minha cara. Sem ela, o modelo invariavelmente ia &ldquo;melhorar&rdquo; a composição, trocar a iluminação, etc.</p>
<p>Olha o resultado em dois exemplos (episódios 10 e 11):</p>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 16px 0;">
<div><strong>Original (PT)</strong><br><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260409_thumb_ep010_pt.jpg" alt="Thumbnail original em português: 7 Recomendações de Shows para pessoas de Tech" style="width: 100%;"></div>
<div><strong>Traduzida (EN)</strong><br><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260409_thumb_ep010_en.jpg" alt="Thumbnail traduzida em inglês: 7 TV Shows You Must Watch If You're In Tech" style="width: 100%;"></div>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 16px 0;">
<div><strong>Original (PT)</strong><br><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260409_thumb_ep011_pt.jpg" alt="Thumbnail original em português: 9 Dicas para Palestrantes: venda sua caneta" style="width: 100%;"></div>
<div><strong>Traduzida (EN)</strong><br><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260409_thumb_ep011_en.jpg" alt="Thumbnail traduzida em inglês: 9 Tips for Speakers: sell your pen" style="width: 100%;"></div>
</div>
<p>Repara no detalhe do episódio 10. O modelo não traduziu &ldquo;7 Recomendações de Shows para Pessoas de Tech&rdquo; literal pra &ldquo;7 Show Recommendations for Tech People&rdquo;, que seria a versão tradutor automático. Ele reformulou pra &ldquo;7 TV Shows You Must Watch If You&rsquo;re In Tech&rdquo;, como um tech YouTuber americano de verdade escreveria. O resto da imagem fica idêntico pixel a pixel. No episódio 11, &ldquo;9 DICAS PARA PALESTRANTES: venda sua caneta&rdquo; vira &ldquo;9 TIPS FOR SPEAKERS: sell your pen&rdquo;, com fonte, caixa alta e posição preservadas. Se você não soubesse que o original era em português, não dava pra adivinhar que é uma edição automática feita por IA.</p>
<p>Custo do lado Gemini: alguns centavos por imagem, poucos dólares totais pro batch inteiro. Trivial perto dos $1.500+ do dub. Com a thumbnail resolvida, a conversão do canal pra inglês fica fechada — áudio clonado pela ElevenLabs v3 em cima das legendas curadas em <code>.srt</code>, e a imagem editada pelo Nano Banana Pro pra o título bater com o resto.</p>
<h2>A conclusão, que é o título desse post<span class="hx:absolute hx:-mt-20" id="a-conclusão-que-é-o-título-desse-post"></span>
    <a href="#a-conclus%c3%a3o-que-%c3%a9-o-t%c3%adtulo-desse-post" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Quando o Qwen3 TTS saiu, o hype dizia que era &ldquo;ElevenLabs killer&rdquo;. Passei semanas tentando viver com essa premissa na prática, com conteúdo real no ar toda semana. E o que eu descobri é que open source de TTS ainda tá muito longe da ElevenLabs. A diferença é grande, e ela aparece justamente quando você sai do tweet de demo de 5 segundos e coloca o modelo pra rodar um podcast semanal de 30 minutos de verdade.</p>
<p>Na prática, o Qwen3 nem bate o modelo v2 da ElevenLabs. O v3, que é o atual, fica um degrau acima do v2 ainda. A prosódia sai melhor, as tags de emoção no meio do texto funcionam em português e em inglês sem esforço, e a API fica de pé sem você precisar manter servidor nenhum. O custo por caractere é um pouco mais alto, mas pro meu volume atual ele fica confortavelmente dentro do orçamento e me devolve horas que eu gastava cuidando de GPU.</p>
<p>A lição aqui é a mesma que a galera de LLMs tá aprendendo devagar. Demo de tweet de 30 segundos é uma coisa, produção é outra coisa completamente diferente. Open source tem seu nicho, principalmente quando você tem dado sensível que não pode sair de casa, ou quando você tem muita GPU ociosa e pouco orçamento recorrente. Só que pra uso sério de TTS em produto comercial, aqui em abril de 2026, a ElevenLabs segue imbatível. O Qwen3 não matou ninguém.</p>
<p>E não esquece: assina o <a href="https://open.spotify.com/show/7MzG2UB7IAkC3GAwEXEIVD"target="_blank" rel="noopener">The M.Akita Chronicles no Spotify</a> pra não perder episódio novo desses, feito com a nova pipeline.</p>
]]></content:encoded><category>midia-generativa</category><category>modelos-locais</category><category>reviews</category></item><item><title>Review: Minisforum MS-S1 Max | AMD AI Max+ 395 com 96GB de VRAM</title><link>https://akitaonrails.github.io/2026/03/31/review-minisforum-ms-s1-max-amd-ai-max-395/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/03/31/review-minisforum-ms-s1-max-amd-ai-max-395/</guid><pubDate>Tue, 31 Mar 2026 15:00:00 -0300</pubDate><description>&lt;p&gt;Quem acompanha meus posts sobre &lt;a href="https://akitaonrails.github.io/2024/04/03/meu-netflix-pessoal-com-docker-compose/"&gt;home server&lt;/a&gt; sabe que eu rodava tudo num Intel NUC Core i7 com 32GB de RAM. Funcionava. Mas com o crescimento dos modelos de IA open source, o NUC virou um gargalo. Sem GPU dedicada, qualquer inferência de LLM ia pra CPU e ficava inutilizável.&lt;/p&gt;
&lt;p&gt;Eu comprei um Minisforum MS-S1 Max com o novo chip AMD Ryzen AI Max+ 395 por um motivo específico: esse chip suporta até 128GB de RAM unificada, e eu posso alocar 96GB como VRAM pro iGPU. Isso me dá mais VRAM do que qualquer placa gamer comercial, incluindo a RTX 5090 (32GB). E isso muda o que eu consigo rodar localmente.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Quem acompanha meus posts sobre <a href="/2024/04/03/meu-netflix-pessoal-com-docker-compose/">home server</a> sabe que eu rodava tudo num Intel NUC Core i7 com 32GB de RAM. Funcionava. Mas com o crescimento dos modelos de IA open source, o NUC virou um gargalo. Sem GPU dedicada, qualquer inferência de LLM ia pra CPU e ficava inutilizável.</p>
<p>Eu comprei um Minisforum MS-S1 Max com o novo chip AMD Ryzen AI Max+ 395 por um motivo específico: esse chip suporta até 128GB de RAM unificada, e eu posso alocar 96GB como VRAM pro iGPU. Isso me dá mais VRAM do que qualquer placa gamer comercial, incluindo a RTX 5090 (32GB). E isso muda o que eu consigo rodar localmente.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/blog/2026/03/31/minisforum-desk.jpg" alt="Minisforum MS-S1 Max na mesa"  loading="lazy" /></p>
<h2>Por que trocar o Intel NUC<span class="hx:absolute hx:-mt-20" id="por-que-trocar-o-intel-nuc"></span>
    <a href="#por-que-trocar-o-intel-nuc" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O NUC serviu bem como servidor Docker por dois anos. Mas a limitação era clara: sem GPU com VRAM suficiente, eu não conseguia rodar LLMs localmente de forma usável. O <a href="https://github.com/akitaonrails/FrankYomik"target="_blank" rel="noopener">Frank Yomik</a>, meu sistema de tradução automática de mangás, precisava de OCR via CPU (lento) e conectava remotamente no Ollama do meu desktop (AMD 7950X3D + RTX 5090) pra tradução. Funcionava, mas significava que meu desktop precisava estar ligado pro servidor funcionar.</p>
<p><img src="https://raw.githubusercontent.com/akitaonrails/FrankYomik/master/docs/sample_translate.png" alt="Frank Yomik - tradução automática de mangás"  loading="lazy" /></p>
<p>Com o Minisforum, o Frank Yomik roda inteiramente no servidor. O worker agora usa ROCm pra OCR com a iGPU, e o Ollama roda local com 96GB de VRAM. Zero dependência do desktop.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/blog/2026/03/31/minisforum-nuc-compare.jpg" alt="Comparação: Intel NUC (esquerda) vs Minisforum MS-S1 Max (direita)"  loading="lazy" /></p>
<p>Na foto dá pra ter uma ideia do tamanho. O NUC é aquele cubinho pequeno na esquerda. O Minisforum é maior, mas ainda é um mini-PC. Cabe na prateleira do rack embaixo do Synology NAS sem problema.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/blog/2026/03/31/minisforum-shelf.jpg" alt="Minisforum instalado na prateleira, ao lado do NAS"  loading="lazy" /></p>
<h2>As specs<span class="hx:absolute hx:-mt-20" id="as-specs"></span>
    <a href="#as-specs" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/blog/2026/03/31/minisforum-fastfetch.png" alt="fastfetch do Minisforum"  loading="lazy" /></p>
<p>O chip é o AMD Ryzen AI Max+ 395: 16 cores / 32 threads Zen 5, com iGPU Radeon 8060S integrada e 128GB de LPDDR5X unificada. No BIOS, eu configurei UMA Frame Buffer Size pra 96GB, o que deixa ~30GB de RAM pro sistema operacional e containers. Mais os parâmetros de kernel pra TTM (sem eles, o ROCm só enxerga 15.5GB mesmo com a alocação do BIOS).</p>
<p>O sistema operacional é openSUSE MicroOS (mais sobre isso no <a href="/2026/03/31/migrando-meu-home-server-com-claude-code/">próximo post</a>). O consumo de energia da máquina inteira fica abaixo de 100W, o que é absurdo pra quem está acostumado com GPUs dedicadas que puxam 450W+ sozinhas.</p>
<h2>Minisforum vs meu desktop: benchmarks<span class="hx:absolute hx:-mt-20" id="minisforum-vs-meu-desktop-benchmarks"></span>
    <a href="#minisforum-vs-meu-desktop-benchmarks" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Eu rodei um <a href="https://github.com/akitaonrails/homelab-docs/tree/master/benchmarks"target="_blank" rel="noopener">conjunto de benchmarks</a> comparando o Minisforum com meu desktop (AMD 7950X3D, 96GB DDR5, RTX 5090 32GB GDDR7). Os resultados são claros.</p>
<h3>CPU<span class="hx:absolute hx:-mt-20" id="cpu"></span>
    <a href="#cpu" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><table>
  <thead>
      <tr>
          <th>Teste</th>
          <th>7950X3D</th>
          <th>AI Max+ 395</th>
          <th>Vantagem</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Prime sieve (single-core)</td>
          <td>0.021s</td>
          <td>0.018s</td>
          <td>Strix Halo +14%</td>
      </tr>
      <tr>
          <td>Float pi (single-core)</td>
          <td>1.335s</td>
          <td>1.706s</td>
          <td>7950X3D +28%</td>
      </tr>
      <tr>
          <td>Multi-core sieve (32 threads)</td>
          <td>0.181s</td>
          <td>0.118s</td>
          <td>Strix Halo +53%</td>
      </tr>
      <tr>
          <td>SHA-256 throughput</td>
          <td>2.714 MB/s</td>
          <td>2.488 MB/s</td>
          <td>7950X3D +9%</td>
      </tr>
      <tr>
          <td>AES-256-CBC throughput</td>
          <td>1.613 MB/s</td>
          <td>1.410 MB/s</td>
          <td>7950X3D +14%</td>
      </tr>
  </tbody>
</table>
<p>Resultados mistos. O AI Max+ 395 é melhor em paralelismo puro (sieve multi-core), provavelmente por conta da latência menor na arquitetura de memória unificada. O 7950X3D ganha em float e crypto por causa dos clocks mais altos e do 3D V-Cache.</p>
<h3>Inferência de LLMs (modelos que cabem nos dois)<span class="hx:absolute hx:-mt-20" id="inferência-de-llms-modelos-que-cabem-nos-dois"></span>
    <a href="#infer%c3%aancia-de-llms-modelos-que-cabem-nos-dois" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Aqui é onde a coisa fica interessante. Pra modelos que cabem nos 32GB da RTX 5090, a comparação é puramente de bandwidth de memória:</p>
<table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th>Tamanho</th>
          <th>RTX 5090 (tok/s)</th>
          <th>Strix Halo (tok/s)</th>
          <th>Vantagem 5090</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>phi4</td>
          <td>9.1 GB</td>
          <td>155.1</td>
          <td>23.2</td>
          <td>6.7x</td>
      </tr>
      <tr>
          <td>qwen3:14b</td>
          <td>9.3 GB</td>
          <td>138.9</td>
          <td>22.6</td>
          <td>6.1x</td>
      </tr>
      <tr>
          <td>phi4-reasoning</td>
          <td>11.1 GB</td>
          <td>130.2</td>
          <td>19.1</td>
          <td>6.8x</td>
      </tr>
      <tr>
          <td>qwen3:32b</td>
          <td>20.2 GB</td>
          <td>66.9</td>
          <td>10.0</td>
          <td>6.7x</td>
      </tr>
  </tbody>
</table>
<p>A RTX 5090 é ~7x mais rápida. A explicação é simples: GDDR7 tem ~1.792 GB/s de bandwidth. LPDDR5X tem ~256 GB/s. A razão (7x) bate quase exatamente com a diferença de velocidade medida (6.7x). Inferência de LLM é um problema dominado por bandwidth de memória. Quem lê pesos mais rápido, gera tokens mais rápido.</p>
<h3>E o prompt processing?<span class="hx:absolute hx:-mt-20" id="e-o-prompt-processing"></span>
    <a href="#e-o-prompt-processing" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th>RTX 5090 (tok/s)</th>
          <th>Strix Halo (tok/s)</th>
          <th>Vantagem 5090</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>phi4</td>
          <td>~1.933</td>
          <td>~212</td>
          <td>9.1x</td>
      </tr>
      <tr>
          <td>qwen3:14b</td>
          <td>~1.474</td>
          <td>~155</td>
          <td>9.5x</td>
      </tr>
      <tr>
          <td>qwen3:32b</td>
          <td>~767</td>
          <td>~68</td>
          <td>11.3x</td>
      </tr>
  </tbody>
</table>
<p>Prompt processing é ainda pior: 7-11x mais lento. Faz sentido, porque o prompt precisa ser processado inteiro antes de gerar o primeiro token, e é uma operação ainda mais bandwidth-intensiva.</p>
<h3>Onde o Strix Halo ganha: modelos grandes<span class="hx:absolute hx:-mt-20" id="onde-o-strix-halo-ganha-modelos-grandes"></span>
    <a href="#onde-o-strix-halo-ganha-modelos-grandes" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Agora vem a razão pela qual eu comprei esse PC. Modelos que não cabem na RTX 5090:</p>
<table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th>Tamanho</th>
          <th>Strix Halo (tok/s)</th>
          <th>Notas</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>gpt-oss:20b</td>
          <td>13.8 GB MXFP4</td>
          <td>48.9</td>
          <td>MoE, mais rápido que esperado</td>
      </tr>
      <tr>
          <td>qwen3.5:35b</td>
          <td>23.9 GB</td>
          <td>43.2</td>
          <td>MoE, apenas ~4B params ativos</td>
      </tr>
      <tr>
          <td>qwen3-coder-next</td>
          <td>51.7 GB</td>
          <td>29.5</td>
          <td>MoE, 50GB+</td>
      </tr>
      <tr>
          <td>qwen3.5:122b</td>
          <td>81.4 GB Q4_K_M</td>
          <td>19.2</td>
          <td>122B params, MoE</td>
      </tr>
      <tr>
          <td>glm-4.7-flash:bf16</td>
          <td>59.9 GB</td>
          <td>17.9</td>
          <td>Full precision bf16</td>
      </tr>
      <tr>
          <td>qwen2.5:72b</td>
          <td>47.4 GB Q4_K_M</td>
          <td>4.5</td>
          <td>Dense 72B, bandwidth-limited</td>
      </tr>
  </tbody>
</table>
<p>O qwen3.5:122b com 81GB de pesos rodando a 19 tok/s. Num mini-PC. Isso simplesmente não é possível numa RTX 5090. Na placa da NVIDIA, esse modelo teria que fazer offload de camadas pra RAM do sistema, caindo pra 2-3 tok/s. Na prática, inutilizável.</p>
<p>A diferença entre modelos MoE e densos é brutal. O qwen3.5:35b roda a 43 tok/s porque, apesar de ter 35B de parâmetros totais, só ~4B ficam ativos por token. Um modelo denso de 72B como o qwen2.5:72b precisa ler 40GB+ de pesos por token, e a 256 GB/s de bandwidth, o máximo teórico é ~6.7 tok/s. Os 4.5 medidos representam ~67% de eficiência, que é o esperado pra iGPU (overhead de bus compartilhado e drivers).</p>
<h3>Resumo: quando usar cada máquina<span class="hx:absolute hx:-mt-20" id="resumo-quando-usar-cada-máquina"></span>
    <a href="#resumo-quando-usar-cada-m%c3%a1quina" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><table>
  <thead>
      <tr>
          <th>Caso de uso</th>
          <th>Melhor máquina</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Chat/coding interativo (modelos &lt;32GB)</td>
          <td>RTX 5090 (6-7x mais rápido)</td>
      </tr>
      <tr>
          <td>Modelos grandes (50GB+)</td>
          <td>Strix Halo (única opção)</td>
      </tr>
      <tr>
          <td>Modelos densos 70B+</td>
          <td>Strix Halo (única opção)</td>
      </tr>
      <tr>
          <td>Full-precision bf16</td>
          <td>Strix Halo (única opção)</td>
      </tr>
      <tr>
          <td>Batch processing com contexto longo</td>
          <td>Strix Halo (mais VRAM pra KV cache)</td>
      </tr>
      <tr>
          <td>API serving com baixa latência</td>
          <td>RTX 5090 (sub-150ms TTFT)</td>
      </tr>
  </tbody>
</table>
<h3>Um bug de ROCm que ainda existe<span class="hx:absolute hx:-mt-20" id="um-bug-de-rocm-que-ainda-existe"></span>
    <a href="#um-bug-de-rocm-que-ainda-existe" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Nem tudo funciona. Modelos como deepseek-r1:70b, llama3.3:70b e llama4:scout crasham com um bug no ggml (<code>GGML_ASSERT(ggml_nbytes(src0) &lt;= INT_MAX) failed</code>). O tensor de embedding desses modelos excede 2GB e o kernel de cópia do ROCm usa inteiro de 32 bits pro tamanho. No CUDA (NVIDIA) já foi corrigido, mas no ROCm ainda não. Esperando o fix no Ollama 0.20.0+.</p>
<h2>LPDDR5X vs GDDR7: por que essa diferença<span class="hx:absolute hx:-mt-20" id="lpddr5x-vs-gddr7-por-que-essa-diferença"></span>
    <a href="#lpddr5x-vs-gddr7-por-que-essa-diferen%c3%a7a" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A pergunta que vem é: por que a LPDDR5X é tão mais lenta?</p>
<p>GDDR7 é memória dedicada de GPU. Ela fica soldada na placa de vídeo, conectada por um barramento largo (384 ou 512 bits na RTX 5090) com clocks altos. O único trabalho dela é alimentar a GPU com dados. LPDDR5X é memória unificada que serve pra tudo: sistema operacional, aplicações, e GPU ao mesmo tempo. O barramento é mais estreito e compartilhado.</p>
<p>Na prática: GDDR7 entrega ~1.792 GB/s dedicados pra GPU. LPDDR5X entrega ~256 GB/s que ainda precisam ser divididos entre CPU e GPU. Inferência de LLM é basicamente &ldquo;leia todos os pesos do modelo da memória, multiplique pelo token atual, gere o próximo token, repita&rdquo;. Quem lê mais rápido, gera mais rápido. Não tem atalho.</p>
<p>A vantagem do Strix Halo não é velocidade. É capacidade. 96GB de VRAM num chip de 100W que custa uma fração de uma GPU profissional. A RTX 5090 é 7x mais rápida, mas trava em 32GB. Modelos que não cabem, não rodam.</p>
<h2>As alternativas: quem mais faz isso?<span class="hx:absolute hx:-mt-20" id="as-alternativas-quem-mais-faz-isso"></span>
    <a href="#as-alternativas-quem-mais-faz-isso" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se 96GB não é suficiente ou se você quer mais velocidade, as opções são poucas.</p>
<p>O Framework Desktop usa o mesmo chip AI Max+ 395 com até 128GB de RAM. Mesma plataforma, mesma performance, mas com o diferencial de ser modular e reparável (é o Framework, afinal). Na prática é equivalente ao Minisforum em specs e preço.</p>
<p>Acima disso, a alternativa é o Mac Studio com M3 Ultra. O chip M3 Ultra suporta até 512GB de memória unificada, com bandwidth de ~819 GB/s (mais de 3x o Strix Halo). A Apple fabrica os chips de memória no package, então a latência e a bandwidth são superiores. Você poderia potencialmente alocar ~400GB como VRAM e rodar modelos que não cabem em lugar nenhum fora de servidores com GPUs profissionais.</p>
<p>O NVMe interno da Apple também é outro nível: ~7.4 GB/s de leitura sequencial no M3 Ultra, comparado com ~14 GB/s do Crucial T700 (PCIe 5.0). O T700 é mais rápido em throughput bruto, mas a latência do NVMe da Apple tende a ser menor em I/O aleatório por causa da integração com o SoC.</p>
<table>
  <thead>
      <tr>
          <th>Spec</th>
          <th>Minisforum MS-S1 Max</th>
          <th>Mac Studio M3 Ultra (max)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>RAM máxima</td>
          <td>128 GB LPDDR5X</td>
          <td>512 GB unified</td>
      </tr>
      <tr>
          <td>VRAM alocável</td>
          <td>~96 GB</td>
          <td>~400 GB</td>
      </tr>
      <tr>
          <td>Memory bandwidth</td>
          <td>~256 GB/s</td>
          <td>~819 GB/s</td>
      </tr>
      <tr>
          <td>CPU</td>
          <td>Zen 5, 16C/32T</td>
          <td>Apple M3 Ultra, 32C</td>
      </tr>
      <tr>
          <td>GPU compute</td>
          <td>ROCm (gfx1151, experimental)</td>
          <td>Metal (mlx, mature)</td>
      </tr>
      <tr>
          <td>Consumo</td>
          <td>~100W</td>
          <td>~135W</td>
      </tr>
      <tr>
          <td>NVMe</td>
          <td>PCIe 5.0 (slot padrão)</td>
          <td>Custom Apple (~7.4 GB/s)</td>
      </tr>
      <tr>
          <td>Preço (EUA)</td>
          <td>~$1.500-2.000</td>
          <td>~$9.999 (512GB config)</td>
      </tr>
      <tr>
          <td>Preço estimado (Brasil)</td>
          <td>~R$ 12.000-15.000</td>
          <td>~R$ 110.000+ (importação)</td>
      </tr>
  </tbody>
</table>
<p>O preço no Brasil é o elefante na sala. A configuração máxima do Mac Studio custa $9.999 nos EUA. Com impostos de importação (~60% + ICMS estadual), passa dos R$ 110.000. O Minisforum com 128GB sai por R$ 12.000-15.000. A diferença de quase 8x no preço compra muita coisa.</p>
<p>Se você precisa de mais de 96GB de VRAM pra modelos realmente enormes (DeepSeek-V3 com 671B parâmetros cabe em ~400GB Q4, por exemplo), o Mac Studio com 512GB é a única opção consumer. A alternativa seria GPUs profissionais NVIDIA A6000 (48GB VRAM, ~$6.000 cada, e você precisaria de várias em NVLink). Pra tudo que cabe em 96GB, o Minisforum faz o trabalho por uma fração do custo.</p>
<h2>E projetos que prometem rodar LLMs grandes em GPUs pequenas?<span class="hx:absolute hx:-mt-20" id="e-projetos-que-prometem-rodar-llms-grandes-em-gpus-pequenas"></span>
    <a href="#e-projetos-que-prometem-rodar-llms-grandes-em-gpus-pequenas" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Existe o conceito de &ldquo;layer offloading&rdquo; que projetos como llama.cpp já suportam. A ideia é: se o modelo não cabe inteiro na VRAM, mantém algumas camadas na GPU e o resto na RAM do sistema. A GPU processa as camadas que estão nela, transfere pro CPU processar o resto, e volta.</p>
<p>Na prática, não funciona bem. O gargalo é o PCIe: a velocidade de transferência entre RAM do sistema e VRAM da GPU é de ~32 GB/s (PCIe 5.0 x16). Cada token gerado precisa transferir dados ida e volta. O resultado é que você cai de 150 tok/s (tudo na VRAM) pra 2-8 tok/s (offload parcial). É lento demais pra uso interativo.</p>
<p>A VRAM é a limitação fundamental porque inferência de LLM é memory-bandwidth-bound, não compute-bound. A GPU tem compute sobrando. O que falta é capacidade de ler os pesos do modelo rápido o suficiente. Quando parte dos pesos está em RAM via PCIe, o pipeline inteiro espera pela transferência.</p>
<p>É por isso que memória unificada (como no Strix Halo ou no Apple Silicon) faz diferença. Não tem PCIe no meio. CPU e GPU acessam a mesma memória física. Os 256 GB/s do Strix Halo são lentos comparados com GDDR7, mas são 8x mais rápidos que ficar fazendo offload via PCIe.</p>
<h2>Avanços em otimização de LLMs (até 2026)<span class="hx:absolute hx:-mt-20" id="avanços-em-otimização-de-llms-até-2026"></span>
    <a href="#avan%c3%a7os-em-otimiza%c3%a7%c3%a3o-de-llms-at%c3%a9-2026" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra entender por que alguns modelos rodam tão melhor que outros no Strix Halo, precisa entender o que mudou no ecossistema nos últimos dois anos.</p>
<h3>Mixture of Experts (MoE)<span class="hx:absolute hx:-mt-20" id="mixture-of-experts-moe"></span>
    <a href="#mixture-of-experts-moe" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Se você roda modelos locais, MoE é o avanço que mais importa. Um modelo MoE tem parâmetros totais altos (ex: 122B no qwen3.5:122b), mas ativa apenas uma fração deles por token (ex: ~4B). Os pesos inativos ficam na VRAM mas não são lidos a cada token, o que reduz drasticamente a bandwidth necessária.</p>
<p>Nos benchmarks do Strix Halo, modelos MoE rodam 3-10x mais rápido que modelos densos do mesmo tamanho. O qwen3.5:35b (MoE, ~4B ativos) roda a 43 tok/s enquanto o qwen2.5:72b (denso, 72B ativos) roda a 4.5 tok/s.</p>
<h3>DeepSeek e a otimização de treinamento<span class="hx:absolute hx:-mt-20" id="deepseek-e-a-otimização-de-treinamento"></span>
    <a href="#deepseek-e-a-otimiza%c3%a7%c3%a3o-de-treinamento" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O DeepSeek V3 (dezembro 2024) mostrou que era possível treinar modelos de 671B parâmetros com custo uma ordem de magnitude menor que o previsto. Eles combinaram MoE com quantização FP8 durante o treinamento (não só na inferência), treinamento multi-estágio com curriculum learning, e várias otimizações de comunicação entre GPUs. O impacto: todo mundo copiou. Qwen, GLM, MiniMax, todos adotaram variações dessa técnica.</p>
<h3>Quantização: de FP16 pra Q4 sem perder muito<span class="hx:absolute hx:-mt-20" id="quantização-de-fp16-pra-q4-sem-perder-muito"></span>
    <a href="#quantiza%c3%a7%c3%a3o-de-fp16-pra-q4-sem-perder-muito" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Quantização comprime os pesos do modelo de 16 bits (FP16) pra formatos menores: 8 bits (Q8), 4 bits (Q4), ou até 2 bits. Um modelo de 70B que ocuparia ~140GB em FP16 cabe em ~40GB em Q4_K_M. A perda de qualidade existe, mas nos formatos modernos (GGUF Q4_K_M, AWQ, EXL2) é pequena o suficiente pra uso prático.</p>
<p>O GGUF (formato do llama.cpp) se tornou o padrão pra inferência local. AWQ e GPTQ são alternativas com calibração mais sofisticada, mas o ecossistema convergiu pro GGUF porque ele funciona em CPU, CUDA e ROCm sem recompilação.</p>
<h3>Destilação: modelos menores que sabem mais<span class="hx:absolute hx:-mt-20" id="destilação-modelos-menores-que-sabem-mais"></span>
    <a href="#destila%c3%a7%c3%a3o-modelos-menores-que-sabem-mais" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Destilação é treinar um modelo pequeno usando as respostas de um modelo grande como professor. O Phi-4 da Microsoft (14B) foi treinado com destilação do GPT-4 e compete com modelos de 70B em vários benchmarks. O Qwen3 fez o mesmo: o qwen3:14b é surpreendentemente capaz pro tamanho.</p>
<h3>Flash Attention e KV Cache otimizado<span class="hx:absolute hx:-mt-20" id="flash-attention-e-kv-cache-otimizado"></span>
    <a href="#flash-attention-e-kv-cache-otimizado" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Flash Attention (Tri Dao, 2022) mudou como attention é computada: em vez de materializar a matriz inteira de attention na memória, processa em blocos mantendo os dados no SRAM on-chip da GPU, reduzindo consumo de memória de O(n²) pra O(n). Sem isso, contextos de 128K+ tokens seriam impraticáveis. Já passou pelas versões 2 e 3, com otimizações pra FP8 e operações assíncronas no H100. O PagedAttention (vLLM, UC Berkeley) fez o mesmo pro KV cache durante serving: aplica conceitos de memória virtual ao cache, eliminando fragmentação e melhorando throughput 2-4x.</p>
<p>No Ollama, eu configurei <code>OLLAMA_FLASH_ATTENTION=1</code> e <code>OLLAMA_KV_CACHE_TYPE=q8_0</code> no servidor. O primeiro ativa flash attention, o segundo usa KV cache em 8-bit em vez de fp16, cortando a bandwidth necessária pela metade por token. São otimizações que custam zero em hardware e melhoram throughput mensurável.</p>
<h3>O que Qwen, Kimi, MiniMax e GLM estão fazendo<span class="hx:absolute hx:-mt-20" id="o-que-qwen-kimi-minimax-e-glm-estão-fazendo"></span>
    <a href="#o-que-qwen-kimi-minimax-e-glm-est%c3%a3o-fazendo" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O Qwen (Alibaba) tem sido consistentemente o melhor custo-benefício em modelos open source. O Qwen3:14b é denso e forte; o Qwen3.5:122b é MoE e roda surpreendentemente bem em 96GB. O GLM-4.7 (Zhipu AI) é notável por oferecer versões bf16 full precision que rodam inteiras em 96GB. O MiniMax experimentou com contextos longos (até 4M tokens). O Kimi (Moonshot AI) focou em context windows grandes com arquiteturas lineares.</p>
<h3>O que roda bem em 96GB de VRAM<span class="hx:absolute hx:-mt-20" id="o-que-roda-bem-em-96gb-de-vram"></span>
    <a href="#o-que-roda-bem-em-96gb-de-vram" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Com 96GB no Strix Halo, os modelos que funcionam bem pra uso diário:</p>
<table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th>Tamanho</th>
          <th>tok/s</th>
          <th>Uso</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>qwen3.5:35b</td>
          <td>24 GB</td>
          <td>43.2</td>
          <td>Uso geral, excelente</td>
      </tr>
      <tr>
          <td>qwen3-coder-next</td>
          <td>52 GB</td>
          <td>29.5</td>
          <td>Código, MoE</td>
      </tr>
      <tr>
          <td>qwen3.5:122b</td>
          <td>81 GB</td>
          <td>19.2</td>
          <td>Pesado mas usável</td>
      </tr>
      <tr>
          <td>glm-4.7-flash:bf16</td>
          <td>60 GB</td>
          <td>17.9</td>
          <td>Full precision</td>
      </tr>
      <tr>
          <td>qwen2.5-coder:32b</td>
          <td>20 GB</td>
          <td>10.2</td>
          <td>Código, denso</td>
      </tr>
      <tr>
          <td>deepseek-r1:32b</td>
          <td>20 GB</td>
          <td>7.4</td>
          <td>Raciocínio</td>
      </tr>
  </tbody>
</table>
<p>Modelos densos de 70B+ (deepseek-r1:70b, llama3.3:70b) ainda estão bloqueados pelo bug do ROCm que mencionei. Quando for corrigido, devem rodar a ~4-6 tok/s, usáveis pra batch mas não pra chat interativo.</p>
<h2>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Eu comprei o Minisforum pra rodar modelos que não cabem em GPU gamer nenhuma. Pra isso, funciona. Não é rápido. 19 tok/s num modelo de 122B não é a experiência que você tem com Claude ou ChatGPT. Mas é local, é privado, e roda na minha prateleira consumindo menos energia que uma lâmpada antiga.</p>
<p>Pra quem pergunta sobre o Mac Studio: se você tem orçamento, é a melhor máquina pra rodar LLMs locais. 512GB de memória unificada, 819 GB/s de bandwidth, ecossistema Metal/mlx maduro. Dá pra rodar DeepSeek-V3 inteiro em Q4. Mas no Brasil, com importação, passa dos R$ 110 mil. O Minisforum com 128GB por R$ 12-15 mil é a opção realista.</p>
<p>E pra quem acha que dá pra contornar a limitação de VRAM com offloading de camadas: não dá. PCIe é lento demais. O modelo precisa caber inteiro na VRAM pra inferência ser usável. É o motivo pelo qual GPUs gamers com 32GB de GDDR7 ultra-rápida continuam limitadas em tamanho de modelo, e por que a memória unificada do Strix Halo e do Apple Silicon mudou a equação.</p>
<p>No <a href="/2026/03/31/migrando-meu-home-server-com-claude-code/">próximo post</a> eu conto como migrei todo o home server pro Minisforum usando Claude Code, os problemas que encontrei, e como o openSUSE MicroOS se comporta como sistema operacional de servidor Docker.</p>
]]></content:encoded><category>hardware</category><category>modelos-locais</category><category>performance</category><category>reviews</category></item><item><title>Meus Teclados Modernos Favoritos</title><link>https://akitaonrails.github.io/2024/10/24/meus-teclados-modernos-favoritos/</link><guid isPermaLink="true">https://akitaonrails.github.io/2024/10/24/meus-teclados-modernos-favoritos/</guid><pubDate>Thu, 24 Oct 2024 11:05:00 -0300</pubDate><description>&lt;p&gt;Pra quem acompanhou meu canal no YouTube, deve ter visto a trilogia de videos onde contei a história por trás de teclados, desmistifiquei os teclados mecânicos, os diversos componentes, modelos mais populares da época. E hoje estou de volta pra terminar falando dos meus teclados modernos mais interessantes e qual eu realmente uso todo dia.&lt;/p&gt;
&lt;p&gt;Se não assistiu, recomendo que assista a trilogia de videos depois:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=tEXX1jdpZN8"target="_blank" rel="noopener"&gt;Entendendo Teclados Mecânicos | Minha coleção - Parte 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=57axLgXkS_M"target="_blank" rel="noopener"&gt;Teclados Mecânicos Exóticos | Minha coleção - Parte 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=78aw1muYWQM"target="_blank" rel="noopener"&gt;Caminho pro Melhor Teclado do Mundo!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Primeiro Aviso:&lt;/strong&gt; antes que os chatos comentem. Sim, teclados mecânicos são caros. MUITO CAROS. Sim, dá pra escrever livros inteiros num teclado de 50 reais da Multilaser comprado na Kalunga. Não precisa ter switches mecânicos, não precisa de tecla PBT double-shot. Não precisa mudar de layout, qwerty staggered tradicional funciona muito bem. Não precisa de unibody de alumínio. Não precisa de RGB. Não precisa gastar R$ 2.500 num modelo topo de linha. Definitivamente não precisa. Quem faz a obra-prima é o autor e não o teclado.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Pra quem acompanhou meu canal no YouTube, deve ter visto a trilogia de videos onde contei a história por trás de teclados, desmistifiquei os teclados mecânicos, os diversos componentes, modelos mais populares da época. E hoje estou de volta pra terminar falando dos meus teclados modernos mais interessantes e qual eu realmente uso todo dia.</p>
<p>Se não assistiu, recomendo que assista a trilogia de videos depois:</p>
<ul>
<li><a href="https://www.youtube.com/watch?v=tEXX1jdpZN8"target="_blank" rel="noopener">Entendendo Teclados Mecânicos | Minha coleção - Parte 1</a></li>
<li><a href="https://www.youtube.com/watch?v=57axLgXkS_M"target="_blank" rel="noopener">Teclados Mecânicos Exóticos | Minha coleção - Parte 2</a></li>
<li><a href="https://www.youtube.com/watch?v=78aw1muYWQM"target="_blank" rel="noopener">Caminho pro Melhor Teclado do Mundo!</a></li>
</ul>
<p><strong>Primeiro Aviso:</strong> antes que os chatos comentem. Sim, teclados mecânicos são caros. MUITO CAROS. Sim, dá pra escrever livros inteiros num teclado de 50 reais da Multilaser comprado na Kalunga. Não precisa ter switches mecânicos, não precisa de tecla PBT double-shot. Não precisa mudar de layout, qwerty staggered tradicional funciona muito bem. Não precisa de unibody de alumínio. Não precisa de RGB. Não precisa gastar R$ 2.500 num modelo topo de linha. Definitivamente não precisa. Quem faz a obra-prima é o autor e não o teclado.</p>
<p>Isso dito, sim, dá pra ir de São Paulo pra Bahia num Fusca. Ele vai servir sua função de levar do ponto A ao ponto B, como meu pai faria quando era jovem, como meu avô faria na época dele. Funciona perfeitamente bem. Mas, alguns de nós preferem fazer o mesmo trajeto com ar-condicionado, poltronas ergonômicas, som de qualidade, mais velocidade e mais segurança. Nada disso é obrigatório. Ir do ponto A ao ponto B pode ser feito de várias formas diferentes. Se pra você isso não inclui investir em carros caros, não precisa. Use seu Fusca e seja feliz. Este artigo é somente pra quem gosta de Porsche e vê valor nisso.</p>
<p><strong>Segundo Aviso:</strong> a maioria das fotos que mostro no artigo estão em alta resolução original. Pra ver mais detalhes, botão direito e &ldquo;abrir imagem e nova aba&rdquo;. Faz bastante diferença.</p>
<p><strong>Terceiro Aviso:</strong> sim, o artigo é SUPER longo, por isso dá pra navegar pras seções principais usando os links abaixo:</p>
<ul>
<li><a href="#layouts-qmk">Layouts e QMK</a></li>
<li><a href="#treinamento">Treinamento</a></li>
<li><a href="#solucoes-diy">Soluções DIY</a></li>
<li><a href="#ortolineares-gk6">Ortolineares - GK6</a></li>
<li><a href="#ortolineares-q15">Ortolineares - Q15</a></li>
<li><a href="#voyager">Meu Teclado Favorito - Voyager</a></li>
<li><a href="#pulso">Ortolinear vs Colunar</a></li>
<li><a href="#framework">O Futuro - Framework</a></li>
</ul>
<p>Fim dos avisos. No terceiro video eu começo a explicar a diferença pro melhor tipo de teclado do mundo: os ortolineares ou colunares. Não vou explicar tudo de novo, mas em resumo, eles se livram do legado histórico do layout limitado pelas máquinas de escrever mecânicas e repensam o que seria o melhor layout pensando na posição de verdade dos seus dedos, inclusive levando em conta que você tem dedos mais longos e dedos mais curtos (os colunares pensam nisso, os ortolineares não).</p>
<p>Naquele video eu tinha acabado de migrar pra um <a href="https://www.zsa.io/moonlander"target="_blank" rel="noopener">ZSA Moonlander</a>. Até hoje ainda é um dos melhores teclados que eu já experimentei. Mas tem dois problemas fundamentais: primeiro que é extremamente caro, faixa de USD 400. Pra nós, brasileiros, é pior ainda porque vai incidir quase 100% de impostos mais transporte, então estamos falando de um teclado de pelo menos USD 800, mais caro que um PS5, quase o preço de um iPhone 16 Pro comprado nos EUA, faixa de preço de um notebook completo.</p>
<p>Mesmo se dinheiro não for um empecilho pra você, o segundo problema, é que ele é fisicamente gigantesco. Ocupa um espaço absurdo na mesa. Mesmo que tenha uma mesa espaçosa, ele vai ser um &ldquo;trambolhão&rdquo;, olha só como é:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/jn6bce1tishe4tgocps39gtvlvlq" alt="Moonlander"  loading="lazy" /></p>
<p>Mas como disse, a construção da ZSA é de extrema qualidade, os materiais usados incluem metais como alumínio, portanto é tudo muito firme. Os plásticos também são de ótima qualidade. Os switches são removíveis então você pode experimentar um conjunto silencioso como Reds lineares ou barulhentos como Brown ou Blue.</p>
<p>Note também como ele tem inclinação (<a href="https://www.youtube.com/watch?v=oGQhiURh6Tw"target="_blank" rel="noopener">tenting</a>), que faz o meio ser mais alto, pra evitar pronação dos seus pulsos (um dos maiores ofensores em LER ou tendinite), e por isso também tem apoio pros punhos embaixo. É de longe o mais ergonômico. Além disso tem buraco pra parafuso padrão igual de câmera fotográfica, o que permite encaixar em tripés, caso queira experimentar estilos mais exóticos de postura.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/1l8uo8a8opjlj7ova41ld96idhca" alt="Moonlander perfil"  loading="lazy" /></p>
<p>O canal do <a href="https://www.youtube.com/@BenVallack"target="_blank" rel="noopener">Ben Vallack</a> explica melhor isso. Lembrando que o canal dele é extremo, não é pra todo mundo, precisa de muita dedicação pra conseguir se acostumar ao estilo dele, mas é legal ter com referência o que é possível fazer pra casos especiais.</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/II3Wm5P6fOU"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Portanto sim, se pra você o tamanho e o preço não importam, este é de longe o teclado mais customizável, ergonômico e de melhor qualidade possível. Muitos vem me perguntar de modelos como o Kinesis - que também é gigante - mas eu prefiro o Moonlander, nessa categoria. Se formato do Kinesis, em particular, for importante, no final vou falar dele rapidinho.</p>
<p><a name="layouts-qmk"></a></p>
<h2>Layouts e QMK<span class="hx:absolute hx:-mt-20" id="layouts-e-qmk"></span>
    <a href="#layouts-e-qmk" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Mas o Moonlander tem um problema praqueles que querem mesmo cruzar a linha da ergonomia extrema: digitar sem tirar os dedos da &ldquo;home row&rdquo; a linha do meio, onde ficam as teclas &ldquo;F&rdquo; e &ldquo;J&rdquo;. O ideal é ter apenas 3 linhas, uma linha pra cima e outra pra baixo da &ldquo;home row&rdquo;, mas o Moonlander tem 2 linhas acima e 2 linhas abaixo, além de dois thumb-clusters enormes de 4 teclas cada, o que garante que, se tentar usar todas as teclas, vai acabar movendo a mão pra cima e pra baixo mais do que deveria, perdendo o ritmo e velocidade e, principalmente, a ergonomia.</p>
<p>Este passo não é pra todo mundo, mas depois de muito treinar e experimentar, acabei concordando que o formato mais &ldquo;balanceado&rdquo; pra maioria das pessoas que tem intenção de otimizar pra melhor, é o <strong>Corne colunar staggered 40%</strong>.</p>
<p>Se trata de um teclado colunar, ou seja, as teclas estão alinhadas verticalmente, em vez de zig-zaguear entre as linhas, como num convencional. Também são staggered, mas na vertical, ou seja, segue mais ou menos a proporção vertical de comprimento dos dedos. A coluna do meio vai mais pro alto porque o dedo médio é mais longo. Ortolineares são colunares que não são staggered. Já falo mais deles na próxima seção.</p>
<p>Um Corne 40% tem 40% das teclas que um teclado grande convencional - que costuma ter por volta de 103 teclas. Portanto umas 42 teclas. Como são split, divididas no meio, 21 teclas pra cada lado. Alguns preferem remover as duas últimas colunas de teclas nos dois lados mais extremos do teclado, onde ficam &ldquo;tab&rdquo; ou &ldquo;ctrl&rdquo;, reduzindo o total pra 18 teclas de cada lado, ou 36 teclas. E tem alguns como o Ben Vallack que conseguem ir ainda abaixo disso, mas já acho extremo demais e pouco prático pra maioria das pessoas.</p>
<p>Mas como usa um teclado com tão poucas teclas? Como faz pra caber tudo? E esse é o ponto: não faz. Em vez de tentar ter todas as teclas, divide-se em camadas virtuais, com uma tecla modificadora que muda a função de cada tecla. Por exemplo, a maioria dos firmwares de teclados bons hoje são baseados em padrões como QMK ou ZMK. Não quero entrar em detalhes, veja o repositório no GitHub do <a href="https://github.com/qmk/qmk_firmware"target="_blank" rel="noopener">QMK Firmware</a>, mas podemos usar sites como o <a href="https://config.qmk.fm/"target="_blank" rel="noopener">QMK Configurator</a> pra editar o arquivo JSON de layout, visualmente. Por exemplo:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/08zvubti1x2noddivb97pu7678j2" alt="corne layer 1"  loading="lazy" /></p>
<p>Este é o layer 0, sem fazer nada, se só sair digitando no meu teclado, são essas as teclas configuradas por padrão. Aqui nada de novidade, mas note embaixo, no &ldquo;thumb cluster&rdquo;, onde fica o dedão, tem uma tecla dizendo &ldquo;MO(1)&rdquo; que significa <em>&ldquo;Momentarily Turn Layer On&rdquo;</em>, ou seja, se deixar essa tecla apertada, enquanto estiver apertada, ele vai mudar pro layout na camada 1, que está configurada assim:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/6wwjkn4ei6qltt4mbk8g1d1xo50o" alt="corne layer 1"  loading="lazy" /></p>
<p>Tá vendo? É assim que, no meu caso, eu tenho acesso a teclas como &ldquo;page up&rdquo; ou &ldquo;page down&rdquo; ou setas de direção. Quem é de NeoVIM deve ter notado que é a configuração de setas de VIM. Se eu tirar o dedão daquela tecla &ldquo;MO(1)&rdquo;, volta pra camada 0 anterior, e lá, tem outra tecla modificadora, a &ldquo;MO(2)&rdquo; que muda pro seguinte layout:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/0igkt6wac5u5tfdsg2ws3glkbwul" alt="corne camada 2"  loading="lazy" /></p>
<p>É nesta camada que tenho acesso a caracteres especiais como &ldquo;@&rdquo; ou &ldquo;&amp;&rdquo;, sem precisar esticar meu mindinho até o shift no canto, como se faz num teclado convencional. Uso meu dedão. E com o dedão também tenho acesso a acentos e pontuações. Isso é muito subjetivo e cada um pode configurar como quiser, mas preferi fazer meu dedão trabalhar mais. Num teclado convencional, o dedão esquerdo serve pra dar espaço, mas o dedão direito não serve pra nada. E eles são os dedos mais fortes da sua mão. Por outro lado os dois mindinhos ficam encarregados por shift, acentos, pontuação e, em português, é ainda pior que em inglês, porque temos muito mais acentos.</p>
<p>Digitar em português é, na média, mais lento do que em inglês por conta de acentos e palavras mais longas. Mas no meu caso, dividi melhor e dei mais trabalho pro dedão. Veja meu thumb cluster, na camada 0:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/hfnc3l660frcoayvq8oiz110h1kd" alt="camada 0 thumb cluster"  loading="lazy" /></p>
<p>Além de barra de espaço, que coloquei na direita, os dedões ainda tem a função das teclas modificadoras &ldquo;MO(1)&rdquo; e &ldquo;MO(2)&rdquo; além de delete, backspace e enter. Isso tira muito trabalho dos mindinhos, e me parece uma divisão de trabalho mais justa, que leva em conta a força dos dedos. Essa é a principal vantagem de usar um teclado customizável com firmwares como QMK.</p>
<p>Existem dezenas de sugestões de outros layouts, mas leve em consideração que português, por ter acentos, não pode ser igual aos recomendados por norte-americanos. Onde você vai configurar acentos, vai mudar a velocidade e quantidade erros de sua digitação.</p>
<p>O problema é que precisa ter a mente aberta. Aceite que sua memória de teclados convencionais vai ser inutilizada e vai precisar treinar do zero. Então, em vez de tentar colocar teclas onde já está acostumado, pense em mudar pra onde faz mais sentido pro seu workflow. Por exemplo, alguém de data science ou contabilidade, pode querer colocar as teclas numéricas no formato de calculadora, como num teclado convencional grande, e isso pode ser feito numa das camadas extras. Eu tinha uma camada virtual somente com combinações de teclas pra Da Vinci Resolve, pra acelerar meu workflow de editar videos. O mesmo pode ser feito pra programar específicos como Photoshop ou Premiere.</p>
<p><a name="treinamento"></a></p>
<h2>Treinamento<span class="hx:absolute hx:-mt-20" id="treinamento"></span>
    <a href="#treinamento" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra aprender, não tem outro jeito, precisa treinar, horas e horas, dias e dias. Ajustar as teclas em cada camada não é uma coisa que se faz uma só vez. É um processo. Você muda, começa a treinar e vê se realmente está numa posição adequada. Se não estiver, muda, regrava o firmware, e treina mais algumas horas. Até ficar bom pras suas mãos. Esse processo leva dias. Não tente só copiar layouts de outras pessoas. Use de inspiração, mas pense no seu uso particular.</p>
<p>E treinar não é usar 1 hora e acabou. Migrar de teclado staggered convencional, pra colunar, e com layout diferente, vai levar <strong>no mínimo</strong> 40 horas de treino. Se você vai dividir 8 horas de treino por 5 dias ou 20 horas de treino em 2 dias, não importa, mas ninguém consegue ficar bom em menos de 40 horas. Pra maioria das pessoas, pense mais em torno de 50 a <strong>100 horas</strong>.</p>
<p>Eu digo isso porque muitos usam só alguns minutos e já falam <em>&ldquo;ah, isso não é pra mim, nunca vou conseguir&rdquo;.</em> Lógico, alguns minutos não é suficiente. Só depois de umas 10 horas você começa a sentir se quer ou não continuar, antes disso é pura frescura e preguiça.</p>
<p>No começo, logo que migrei, não conseguia digitar mais que 20 palavras por minuto. Treinando mais de 20 horas em 2 dias, num fim de semana, consegui subir pra 70 palavras por minuto e ao final da primeira semana, consegui voltar à minha média antiga de 90 a 100 palavras por minuto (wpm).</p>
<p>E eu tenho mais de 40 anos. Não tem nada a ver com idade. Tem a ver com dedicação em treinar. Isso dito, como treinar? Recomendo os mesmos sites que todo mundo, começando pelo bom e velho <a href="https://monkeytype.com/"target="_blank" rel="noopener">Monkey Type</a>.</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/ivWq2jwQOM0"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Esse site é excepcional, dá pra treinar em quase todas as línguas do mundo. Em inglês dá pra treinar com vocabulário simples e evoluir pra dicionários de palavras bem mais avançadas, dá pra mudar o layout de teclado, cores, temas, tudo. Vale fuçar bastante as opções dele.</p>
<p>Outro site bem conhecido é o <a href="https://www.keybr.com/"target="_blank" rel="noopener">KeyBr</a> que é parecido com o MonkeyType mas não sei porque, parece que sempre vou mais lento aqui. Também tem bastante customização e vale fuçar. É bom quando estiver cansado de olhar pra cara do MonkeyType e quiser novos ares pra variar.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/5owpsnfs2vq75a3nm9k6651xifql" alt="keybr"  loading="lazy" /></p>
<p>E quando estiver se sentindo confortável (especialmente quando conseguir achar posições rápidas pra teclas de acento), experimente competir com outros usuários no bom e velho <a href="https://play.typeracer.com/"target="_blank" rel="noopener">Type Racer</a>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/mu5h5g2lez67fj6zzw1c1sb4qumv" alt="Type Racer"  loading="lazy" /></p>
<p>Diferente do MonkeyType e KeyBr, que não se preocupam tanto com textos que façam sentido e nem pontuação, aqui eles usam trechos de livros e artigos online. Então são trechos de textos de verdade. Também dá pra escolher diversas línguas diferentes. Inicia uma corrida, espera outros usuários aparecerem, e depois de uns 10 segundos já começa a competir.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/mlmhl8g24q3wr0wqdxgfh7d84gbl" alt="Type Racer Resultado"  loading="lazy" /></p>
<p>Em inglês normalmente se fala em WPM ou &ldquo;palavras por minuto&rdquo;, que é uma métrica que eu não gosto muito, porque palavras em inglês são muito mais curtos que em português, então 100 wpm em português é muito mais rápido do que 100 wpm em inglês. Já o TypeRacer usa &ldquo;CPM&rdquo; que é &ldquo;caracteres por minuto&rdquo;, que eu já acho mais justo.</p>
<p>E mesmo assim, em português, parte dos caracteres requerem duas teclas, uma pro acento e outro pra sílaba. Uma palavra como &ldquo;coração&rdquo; tem 7 caracteres, mas precisou de 9 toques no teclado pra escrever. Lembrem-se disso se forem treinar mais em português.</p>
<p>Finalmente, existem vários jogos gratuitos pra navegador, em javascript, pra treinar digitação e na Steam tem dois jogos pagos que recomendo pra brincar:</p>
<p><a href="https://store.steampowered.com/curator/24395108-Typing-Games/?appid=393330"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/n3wytx0g7tfs93kcpdm2vh952qu7" alt="Jogos Steam"  loading="lazy" /></a></p>
<p><strong>Epistory</strong> é bem bonitinho, uma aventura pra relaxar, dá pra crianças jogarem de boa e vai servir pra incentivar a aprender a digitar direito. Já o <strong>The Typing of the Dead Overkill</strong> é um clássico que tinha nos arcades japoneses (e tinha teclado no arcade!!) e teve versão pra Dreamcast, com um teclado pro console, feito pela Sega e agora dá pra jogar no seu PC. É levinho e divertido e tem muito gore, então não é pra todo mundo. Ambos são baratinhos, por isso recomendo.</p>
<p><a name="solucoes-diy"></a></p>
<h2>Soluções DIY<span class="hx:absolute hx:-mt-20" id="soluções-diy"></span>
    <a href="#solu%c3%a7%c3%b5es-diy" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Infelizmente, teclados ortolineares, colunares, mecânicos no geral, são muito caros. Por isso já explico: não, usar um teclado desses não vai fazer ninguém digitar 10 vezes mais rápido, nem nada disso. É uma opção de conforto, você tem que se importar com isso pra investir. Se pra você um tecladinho genérico da Multilaser já atende, e não sente vontade de mudar, tá ótimo. Continue lendo só pra saber que existem opções, mas não se sinta mal por não estar mudando hoje. Quem sabe mais pra frente.</p>
<p>Pra quem realmente quer mudar mas quer gastar o mínimo possível de dinheiro, precisa gastar mais tempo pesquisando. Lógico, tudo que custa mais caro está embutido o preço da conveniência, já vem tudo montado, bonitinho, é só ligar e usar. Mas quem quer gastar pouco, tem que aprender a opção &ldquo;DIY&rdquo; (<em>Do It Yourself</em>) e montar o seu.</p>
<p>Faz algum tempo que eu recomendo as redes sociais do <strong>Felipe/Tupinikeebs</strong>, tanto no <a href="https://x.com/neversaytop"target="_blank" rel="noopener">X</a> quanto no <a href="https://www.instagram.com/tupinikeebs/"target="_blank" rel="noopener">Instagram</a>. Ele manja tudo sobre montagem de teclados, sabe como e onde pedir todas as peças e, se pagar um extra, faz o serviço todo de encomendar, montar e te mandar já montado. Nas redes sociais dele dá pra achar tudo que é tipo de modelo diferente e exótico.</p>
<p><a href="https://www.instagram.com/tupinikeebs/"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/lnwgh8q6ywg4w5maxmenpps4chkd" alt="Tupinikeebs"  loading="lazy" /></a>
Segue ele, dá uma pesquisada no que já postou, e se quiser encomendar, manda DM. O cara é gente boa. Não incomoda com bobagem, por favor, ele tem mais o que fazer.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/71dok29u4vw25bxyuazu7sfy1pce" alt="corne, hillside"  loading="lazy" /></p>
<p>Na foto anterior temos 3 modelos similares. Dois <strong>Cornes</strong> e um <strong>Hillside</strong> (que é tipo um Corne com espaço pra um Rotary, que é aquele cilindro que dá pra girar, como pra volume).</p>
<p>Os dois primeiros usam teclas de impressora 3D, acho que de resina na verdade, uma com perfil mais de Cherry, mais alto e gordo. O segundo mais low profile e fino. O terceiro são teclas Choc low profile comerciais mesmo. Apesar de todos serem bons, eu realmente prefiro teclas industrializadas, de preferência PBT double shot. Não entendeu nada? É porque não assistiu os videos do meu canal (!!)</p>
<p>Só o do meio fui eu que montei meio que do zero, o primeiro e o terceiro foram o Felipe quem me mandou. Você pode tentar assistir tutoriais no YouTube e pesquiser em sites como o <a href="https://www.boardsource.xyz/products/Corne"target="_blank" rel="noopener">BoardSource</a>. Daí comprar diretamente todos os componentes pra montar. Tem que ficar de olho porque nem sempre tem estoque de todos os componentes.</p>
<p>O primeiro e segundo Corne da foto acho que usam o controlador <strong>Nice!Nano 2.0</strong> e o terceiro, o Hillside, usa controlador <strong>RP2040</strong>, que é mais novo e mais avançado. Eu não sou especialista em todos os modelos, mas isso é importante porque varia o tipo de firmware que suportam. Modelos mais parrudos aguentam firmwares mais complexos, com mais customizações. Por isso é bom pesquisar a respeito. O Hillside, por exemplo, tem os rotary, daí precisa ter suporte a tecla que rotaciona.</p>
<p>Quando faz clone do projeto <strong>QMK Firmware</strong> do GitHub, tem um diretório &ldquo;keyboards&rdquo; com todos os modelos conhecidos. No meu caso, fui em &ldquo;keyboards/hillside/48/keymaps/akitaonrails&rdquo; e editei o &ldquo;keymap.c&rdquo; pra ter este trecho:</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-c" data-lang="c"><span class="line"><span class="cl"><span class="cm">/* The encoder_update_user is a function.
</span></span></span><span class="line"><span class="cl"><span class="cm"> * It&#39;ll be called by QMK every time you turn the encoder.
</span></span></span><span class="line"><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="cl"><span class="cm"> * The index parameter tells you which encoder was turned. If you only have
</span></span></span><span class="line"><span class="cl"><span class="cm"> * one encoder, the index will always be zero.
</span></span></span><span class="line"><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="cl"><span class="cm"> * The clockwise parameter tells you the direction of the encoder. It&#39;ll be
</span></span></span><span class="line"><span class="cl"><span class="cm"> * true when you turned the encoder clockwise, and false otherwise.
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kt">bool</span> <span class="nf">encoder_update_user</span><span class="p">(</span><span class="kt">uint8_t</span> <span class="n">index</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">clockwise</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="cm">/* With an if statement we can check which encoder was turned. */</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="n">index</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* First encoder */</span>
</span></span><span class="line"><span class="cl">    <span class="cm">/* And with another if statement we can check the direction. */</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">clockwise</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="cm">/* This is where the actual magic happens: this bit of code taps on the
</span></span></span><span class="line"><span class="cl"><span class="cm">         Page Down key. You can do anything QMK allows you to do here.
</span></span></span><span class="line"><span class="cl"><span class="cm">         You&#39;ll want to replace these lines with the things you want your
</span></span></span><span class="line"><span class="cl"><span class="cm">         encoders to do. */</span>
</span></span><span class="line"><span class="cl">      <span class="nf">tap_code</span><span class="p">(</span><span class="n">KC_PGDN</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="cm">/* And likewise for the other direction, this time Page Down is pressed. */</span>
</span></span><span class="line"><span class="cl">      <span class="nf">tap_code</span><span class="p">(</span><span class="n">KC_PGUP</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="cm">/* You can copy the code and change the index for every encoder you have. Most
</span></span></span><span class="line"><span class="cl"><span class="cm">     keyboards will only have two, so this piece of code will suffice. */</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">index</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* Second encoder */</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">clockwise</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nf">tap_code</span><span class="p">(</span><span class="n">KC_UP</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nf">tap_code</span><span class="p">(</span><span class="n">KC_DOWN</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><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>
<p>O código não é importante agora, só pra vocês terem uma idéia. Isso foi neste caso específico. Na maioria dos casos mais simples, só precisa editar um JSON, e ajuda ter um editor visual como o <strong>QMK Configurator</strong> via Web que falei antes. Daí coloca o JSON no diretório do seu modelo de teclado e segue a documentação pra compilar o binário do firmware. Não quero ter que explicar passo a passo aqui, mas tem tutorial em todo lugar, depois dêem uma fuçada no Google e YouTube.</p>
<p>Na dúvida, hoje em dia acho que o padrão é comprar <a href="https://pandakb.com/products/parts/others/promicro-nrf52840/"target="_blank" rel="noopener">Pro Micro</a> e só se não tiver o <a href="https://nicekeyboards.com/nice-nano/"target="_blank" rel="noopener">Nice!Nano v2.0</a>. Esses chips são o que na foto aparecem no centro de cada teclado. É onde fica o cérebro que controla tudo, onde se conecta o cabo USB e o cabo de áudio P1 que conecta as duas metades. Também é onde se ligaria Wi-fi e bateria em alguns modelos. Aí faz mais diferença porque quanto mais potente, mais bateria gasta, menos tempo dura. Então precisa balancear se realmente precisa do chip mais potente.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/cgdxylg28aexie1wk6xpvtg2hiwo" alt="Controlador Nice!Nano"  loading="lazy" /></p>
<p>Olha o meu acima, é wireless, e tem bateria pequena instalada embaixo, acho que é uma Nice!Nano. O acabamento dos fios não ficou grande coisa. Está usando tanto switches Choc quanto teclas low profile estilo Choc, são lineares red, bem finos. Tem gente que prefere um teclado mais alto, eu prefiro mais baixo quanto possível.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/3vrmkf4dxd51zn9hj34sg6r2w1g4" alt="case impressão 3d mais grosso"  loading="lazy" /></p>
<p>Olha essa que o Felipe montou pra mim, com case feito em impressora 3D, bem mais grosso, com switches e teclas de tamanho normal, bem mais alto. O certo é ter apoio de pulso ou acostumar a digitar sem encostar os pulsos na mesa, senão vai dar tendinite rapidinho com essa altura. E tem esses dois buracos na direita onde dá pra colocar parafusos altos, pra fazer &ldquo;tenting&rdquo;, que nem expliquei no Moonlander. Então é boa opção pra quem não quer ou não pode pronar os pulsos (que é justamente onde &ldquo;pinça&rdquo; o nervo e dá tendinite).</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/itiib5ic6pyv5w97566ya6bre7wc" alt="hillside de perto"  loading="lazy" /></p>
<p>Essa Hillside, na verdade, tinha vindo com as teclas low profile pretas. A minha de antes era que estavam com as teclas brancas low profile Choc, mas fiquei trocando pra experimentar (maus Felipe!! kkkk). Na real, esse conjunto de teclas brancas são as que mais gosto. Note o case mais &ldquo;lean&rdquo; roxo que o Felipe fez pra esse board, e o principal, o botão giratório rotary. Dá pra programar pra muita coisa, no momento é só volume, mas acho que dá pra customizar em apps como Photoshop ou edição de video e coisas assim. Eu mesmo não cheguei a tentar, mas pra quem tem essa necessidade, é uma ótima opção.</p>
<p><a name="ortolineares-gk6"></a></p>
<h2>Ortolineares - GK6<span class="hx:absolute hx:-mt-20" id="ortolineares---gk6"></span>
    <a href="#ortolineares---gk6" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Moonlander, Corne, Hillside e outros são todos teclados colunares, staggered, e split. Eu recomendo fortemente acostumar a usar split. Primeiro porque não precisa aproximar as duas mãos, elas podem ficar afastadas, que é o mais natural.</p>
<p>Segundo, pra aprender a fazer cada mão usar as teclas corretas de cada metade, sem uma mão ficar invadindo a metade da outra. Novamente, faz parte do treino forçar isso. É outra vida quando cada dedo aprende a usar a tecla certa. Muito menos esforço, muito menos cansaço, muito menos dores e ainda aumenta velocidade e diminui quantidade de erros. Só tem vantagem.</p>
<p>Na época que fiz meu video, só tinha um modelo ortolinear que era razoável, o <strong>Planck</strong>. Planck acho que é o nome do layout, mas tinha mais de um fabricante, como a Drop (antiga MassDrop) e a própria ZSA.</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/TYTnjGOQrdU"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Se quiser comprar as peças separadas pra montar você mesmo, compre a versão <a href="https://drop.com/buy/planck-mechanical-keyboard?defaultSelectionIds=988297"target="_blank" rel="noopener">Drop + OLKB</a>. E acho que vai ser a única opção porque a ZSA anunciou em Agosto de 2023 que <a href="https://blog.zsa.io/2307-goodbye-planck-ez/"target="_blank" rel="noopener">vai parar de fabricar os Planck EZ</a>, o que é uma pena. Parece que não vendia o suficiente pra justificar continuar fazendo.</p>
<p>A única vantagem dele frente aos outros que mostrei até agora, é a <strong>mobilidade</strong>. Ele é todo de plástico. É muito bem feito e bem construído, não tem cara de plástico barato. Mas por isso é bem leve, e super compacto. De dimensões, se compara a um Nintendo Switch, só mais grosso. Então é muito fácil de carregar numa mochila.</p>
<p>Assim como seu irmão maior, o Moonlander, mas diferente dos Cornes e outros modelos mais baratos, o Planck EZ tinha LEDs coloridos em cada tecla. Parece bobagem, mas agora que você entendeu que dá pra configurar diversas camadas, imagine como é mais intuitivo de encontrar o que procura se, quando apertar um modificador como o &ldquo;MO(1)&rdquo;, acender em cores customizadas que te ajudam a lembrar o que era o que.</p>
<p>Por exemplo, no video acima, dá pra ver uma camada que acende parecendo uma calculadora. Veja como acendem embaixo dos 9 números principais, daí 3 teclas na direita e 3 na esquerda com funções como adição, multiplicação, etc, igual à configuração que fiz no Oryx abaixo, entenderam a utilidade?</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/en1vwj0ukc98fvddja8jgnzijsxz" alt="Oryx, calc"  loading="lazy" /></p>
<p>O problema é que uma vez que se acostuma com split, voltar pra um monolito como esse é muito chato. Trazer as mãos pra perto e ter que angular os pulsos é cansativo. É exatamente o cansaço que se tem todo dia num teclado convencional. Seus pulsos não foram feitos pra serem nem dobrados e nem rotacionados. Um teclado convencional faz exatamente tudo que seus pulsos odeiam.</p>
<p><strong>A solução é tenting e split</strong>. Mesmo se tenting ocupar muito espaço, no mínimo split já vai fazer muita diferença. Mas enfim, existe esse meio do caminho entre teclado convencional e teclado colunar, que não exige se acostumar ao split logo de cara. É esse layout <strong>ortolinear</strong>, que é um colunar não-staggered, ou seja, onde linhas e colunas estão perfeitamente alinhadas, ortogonais e alinhadas (orto-linear, entenderam?), sem levar em consideração o diferente comprimento de cada dedo.</p>
<p>Nessa categoria existem dois modelos que gostei muito. O primeiro é da <a href="https://www.gizmo.engineering/"target="_blank" rel="noopener">Gizmo Engineering, o GK6</a>. No meu caso, o modelo Imperial Panda. Todo fã de anime dos anos 2000 gosta do esquema de cor de Panda, como em Initial D.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/xifzigq5wf3c1h1ykwo31co4bcy5" alt="Moonlander vs GK6"  loading="lazy" /></p>
<p>Na foto coloquei embaixo do Moonlander, pra demonstrar o que falei antes: uma das desvantagens do Moonlander é ser um trambolho na mesa, e não é exagero. Agora, esse GK6, é extremamente bem construído, uma obra de arte na mesa.</p>
<p>O case dele é um unibody de alumínio, nível Apple de qualidade. Internamente tem espuma pra &ldquo;dampening&rdquo; do som (não vir aquele &ldquo;ping&rdquo; oco), as teclas são de extrema qualidade, dá pra sentir nos dedos a diferença. Cada posição de switch na placa mãe tem LED RGB. O único problema é que esses materiais todos são pesados. No final o teclado tem mais de 800g, <strong>quase 1 quilo</strong>, e dá pra sentir. Pra carregar na mochila já dá pra sentir bem mais pesado. É quase o dobro do peso do antigo Planck EZ que era quase todo de plástico.</p>
<p>Em termos de layout, comparado com o Corne que é 40%, este é 60%, tem 59 teclas, porque a barra de espaço ocupa dois espaços - dá pra tirar o estabilizador e dividir em duas teclas, se quiser. A diferença principal pro Corne é que tem uma linha a mais no topo, a linha de teclas numéricas. Pra quem está acostumado a usar teclados <strong>Tenkey-less</strong> (teclado convencional sem teclado numérico, como da maioria dos notebooks), tende a não ter tanto problema pra se adaptar a este layout.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/x7d1hlkksi7an3i4iyl2eb4o657r" alt="GK6 close up"  loading="lazy" /></p>
<p>É possível usar assim, mas recomendo mudar as teclas de lugar. Como um bom teclado moderno, o GK6 tem firmware que podemos customizar. Está tudo documentado <a href="https://www.gizmo.engineering/firmware"target="_blank" rel="noopener">nesta página</a> no site deles e, claro, é baseado em QMK, então podemos mudar coisas que não fazem sentido, como o &ldquo;backspace&rdquo; que fica no canto superior direito e jogar, por exemplo, pra uma das teclas do dedão, economizando seu mindinho direito. Tem gente que não gosta de fazer isso, mas recomendo tentar. Mesma coisa o enter/return, mudar pra um dos dedões.</p>
<p>O maior problema do GK6 é que sempre está fora de estoque, e o preço é bem salgado: USD 250, sem contar transporte nem impostos. Tem várias cores muito boas pra escolher, então, fiquem de olho pra quando voltar o estoque.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/zjhjrzuvtd4azlf61v613oi7me0u" alt="GK6 bottom"  loading="lazy" /></p>
<p>Sério, olha essa foto, a traseira deste teclado é mais bonita do que a frente da grande maioria dos teclados comerciais. Isso é unibody de alumínio com o nome do teclado esculpido em relevo baixo.</p>
<p><a name="ortolineares-q15"></a></p>
<h2>Ortolineares - Q15<span class="hx:absolute hx:-mt-20" id="ortolineares---q15"></span>
    <a href="#ortolineares---q15" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Mas se não tem paciência e tem dinheiro sobrando, sempre tem a opção da <strong>Keychron</strong>, que se estabelece com a marca de teclados com a maior variedade de todas. Pense num estilo, eles tem. De todos os tamanhos, de todas as qualidades, mas todos muito caros. Pelo menos, sempre costuma ter estoque.</p>
<p>E na linha ortolinear, temos que ver o <a href="https://keychronbrasil.com.br/products/keychron-q15-max-qmk-teclado-mecanico-custom-wireless"target="_blank" rel="noopener">Keychron Q15 max</a> que tem no Brasil mas está a bagatela de nada menos que R$ 2.229,00, quase USD 400 dólares. É BEM caro.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/dkrgad9ki9irl5v51erlbff2q3h3" alt="Keychron Q15 Max"  loading="lazy" /></p>
<p>Mesma coisa, comparando o tamanho com o monstruoso Moonlander. Mas veja que também é compacto. Em termos de dimensões é muito próximo do Gizmo GK6. Mas muito mais pesado, em vez de 800g, esse tem <strong>1.2 quilo</strong>. É 50% mais pesado e dá pra sentir carregando. Este, definitivamente seus ombros vão chorar quando carregar na mochila. É literalmente o peso de um Macbook Air inteiro!</p>
<p>Ele é mais caro e mais pesado porque realmente tem muito mais material. Faz o GK6 parecer teclado de hobbista. Também tem case em unibody de alumínio, múltiplas camadas, design double-gasket, espuma de dampening, camada de latex, etc. Olha isso, direto do site deles:</p>
<p><img src="https://cdn.shopify.com/s/files/1/0578/7815/1346/files/Q15-Max-structur.jpg?v=1723147312" alt="Q15 layers"  loading="lazy" /></p>
<p>Além disso tem <strong>dois rotary</strong>, um em cada canto superior, que nem o Hillside que o Felipe tinha montado pra mim, mas este tem acabamento bem profissional. Serve não só pra controlar volume, mas é muito desejável em workflows de Photoshop, Premiere, Da Vinci Resolve. Toda vez que precisar lidar com timelines, gradientes, coisas que modificam ranges de valores com precisão. Pra isso esses rotary são muito melhores do que só mouse ou combinação de teclas.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/4oja3or2pjk97ex482s7a8dont6k" alt="Q15 close up"  loading="lazy" /></p>
<p>Além disso, notem como tem teclas duplas e triplas. Ele vem com teclas extras, e essas teclas maiores tem estabilizadores, dá pra tirar e dividir em mais teclas menores. Dá pra customizar de vários jeito diferentes e, pra variar, também tem firmware baseado em QMK e um aplicativo visual pra ficar mais fácil de mudar o layout só com mouse, em vez de ter que editar um arquivo JSON.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/t0wr29gfjxsw0av8vjd9tkh6l7z5" alt="Q15 bottom"  loading="lazy" /></p>
<p>Eu elogiei a traseira do GK6, mas o Q15 Max não fica atrás. Novamente, unibody de alumínio. Parafusos de bronze, se não me engano. Textura impecável. É uma obra de arte também. E dá pra ver a grossura extra desse teclado, é um pouco mais alto no topo, então é um pouco inclinado em vez de totalmente reto com o GK6. Este teclado já começa a exigir um apoio de pulso.</p>
<p>Agora, esse peso todo, e tantas camadas, também resultam num som muito mais encorpado e robusto, ouçam só:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/l-dLYSNyDKk"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Ouviram o barulho do peso do Q15 no chão? E conseguem entender a diferença nos sons? O Q15 não ecoa nada, o &ldquo;dampening&rdquo; dele é muito bom. O som é grave e encorpado. O GK6 também é muito bom, mas tem menos camadas. Em comparação dá pra sentir um pouquinho de eco no fim. Já os últimos dois são mais ocos por dentro, sem espuma, com materiais menos robustos, aí já tem um barulho um pouco mais agudo e ecoado. O ideal é o som do Q15. Nenhum deles é particularmente ruim, mas o Q15 é superior mesmo.</p>
<div class="video-container">
<video controls preload="auto"> <source src="https://cdn.shopify.com/videos/c/o/v/8f053eebc79f4e07a923e477e38d04d0.mp4" type="video/mp4"> Your browser does not support the video tag. </video>
</div>
<p>O exemplo acima é do próprio site da Keychron, mostrando como eles tem um aplicativo visual pra editar os layouts, parecido com o Oryx da ZSA também. Apesar de ser bom ter a liberdade de fazer o que quiser no nível da linguagem C com o QMK, pra teclados, eu realmente prefiro que exista uma opção visual assim. Nem todo mundo que vai comprar é programador e vai saber configurar terminal, python, git, etc. O ideal é ter as duas opções, mas o default ser plug-and-play, só plugar na USB, o aplicativo sobe o firmware e já era.</p>
<p><a name="voyager"></a></p>
<h2>Meu Melhor Teclado - Voyager<span class="hx:absolute hx:-mt-20" id="meu-melhor-teclado---voyager"></span>
    <a href="#meu-melhor-teclado---voyager" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Apesar de todos os elogios que vim fazendo a todos os teclados anteriores, eu não uso nenhum deles hoje em dia. Na verdade, recebi o Q15 Max e não tinha nem tirado da caixa até ter que tirar as fotos pra este artigo. Um dos problemas desse tipo de teclado é que já me acostumei ao meu layout, com minhas próprias camadas customizadas, então todo novo teclado, preciso passar pelo cansativo processo de editar layouts tudo de novo. Aí não tive paciência e acabei nem usando.</p>
<p>Se nenhum dos modelos comerciais existisse, o teclado ideal seria alguma variação de Corne. São pequenos e compactos, não ocupam quase nenhum espaço na mesa. Somado a switches e teclas Choc, ficam bem low profile. O PCB (placa controladores) não exige uso de case, pode ficar direto na mesa porque não tem nada embaixo que dá curto. Isso o torna  extremamente &ldquo;flat&rdquo; na mesa, não precisando usar nenhum tipo de apoio de pulso.</p>
<p>Além disso, é colunar staggered, que leva em consideração comprimento diferente dos dedos, e é split, que permite deixar as duas mãos bem separadas, evitando rotações desnecessárias. Finalmente, é totalmente customizável via QMK, onde posso colocar todas as camadas do jeito que eu quero. Ou seja, é o teclado perfeito.</p>
<p>Mas a ZSA, fabricante do descontinuado Planck EZ e do monstruoso Moonlander, resolveu criar um novo modelo, o <a href="https://www.zsa.io/voyager"target="_blank" rel="noopener">Voyager</a>. Eu acho que muito desse modelo veio do feedback de pessoas com o Ben Vallack. Sério, maratonem os videos do canal dele onde mostra passo a passo a pesquisa que fez pra determinar como o teclado perfeito deveria ser. E até vai além do ponto, ao extremo de criar um teclado com nada menos do que míseras 18 teclas (!!)</p>
<p>Não é prático, mas é ultrapassando os limites que sabemos onde está o limite:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/c18vkHG_7tY"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Ele começou a fazer os protótipos usando o Moonlander como base, removendo teclas, fazendo experimentos. E chegou à conclusão que o Moonlander seria ainda mais ergonômico e muito mais produtivo se fosse muito menor e com muito menos teclas. E a ZSA ouviu.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/wr7r2w8spl4kitmtr8oyg3si21tw" alt="Moonlander vs Voyager"  loading="lazy" /></p>
<p>Ele tem mais ou menos as mesmas dimensões do GK6 ou Q15, mas em formato &ldquo;split&rdquo;, dividido ao meio, o que possibilita mais flexibilidade e ergonomia. Note que a cor branca vai encardindo com o tempo. Ainda não sei o que é melhor pra limpar, mas o meu já está amarelando de tanto usar. Recomendo comprar a versão preta.</p>
<p>O Voyager é o Moonlander 2.0, um Corne comercial. É um pouco maior do que um Corne 40% porque tem a linha superior numérica. Eu acho que nem precisaria, mas não chega a atrapalhar. Ao contrário do meu Corne montado de forma caseira, o Voyager é &ldquo;slick&rdquo;, com cara de algo que a Apple construiria. Plásticos duros de alta qualidade, placa de metal atrás dando suporte, peso e rigidez, mas sem aumentar demais o peso total. Espessura fina, usando switches e teclas low profile, parecidas com as Choc que falei que gosto, e ainda com LEDs RGB em cada tecla. Tem tudo que gosto no Corne e mais um pouco.</p>
<p>Claro, assim como tudo nessa categoria, o Voyager também é bem caro. USD 365, sem contar transporte nem impostos. É a mesma faixa de preço do Q15 Max. Por isso falei: se preço menor for importante, um Corne montado manualmente faz a mesma coisa, e pode custar metade do preço ou menos! Falem com o Felipe!</p>
<p>Em comparação com o Corne, tem 2 teclas a menos em cada thumb-cluster. Isso foi um pouquinho chato no começo de me acostumar, mas hoje eu acho que foi a decisão certa: cada dedão não precisa de mais do que duas teclas. Este é um caso onde limitações são libertadoras. O senso-comum diz que ter mais teclas é melhor, mas os dedos precisam se mexer mais e é mais fácil de errar.</p>
<p>Isso vale a pena explicar. Vamos revisar o layout do meu Corne:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/hfnc3l660frcoayvq8oiz110h1kd" alt="camada 0 thumb cluster"  loading="lazy" /></p>
<p>Aqui cada dedão precisa lembrar a posição de 3 teclas. As mais usadas são backspace e barra de espaço, por isso coloco mais na ponta. Assim eu sempre sei que precisa esticar o dedão e nunca vou errar. Já &ldquo;delete&rdquo; e &ldquo;enter¨ se usa um pouco menos, deixo no meio, onde é só abaixar o dedão, sem esticar. Era assim que eu usava no Moonlander, Planck, Corne e outros.</p>
<p>Mas o Voyager só tem 2 teclas em cada dedão, como faz?</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/r0jooa947kshzk2gc35wphqlem2m" alt="oryx camada 0"  loading="lazy" /></p>
<p>Esta é a camada 0 (zero) do meu Voyager. Tem só backspace e espaço nas teclas maiores do thumb-cluster, mas note que acima tem as teclas &ldquo;hold&rdquo;, que é a mesma coisa que o &ldquo;MO(1)&rdquo; e &ldquo;MO(2)&rdquo; do QMK, lembram? Servem pra deixar apertado e mudar pra outra camada virtual. Se apertar esse &ldquo;hold 1&rdquo;, vai virar o seguinte:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/gn29nzx8jwsoakjf3em29d3dxg2t" alt="oryx camada 1"  loading="lazy" /></p>
<p>Agora sim, com o &ldquo;hold 1&rdquo; apertado na esquerda, posso apertar &ldquo;enter&rdquo; com dedão direito.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/05xfa8qfyjt7hpebv6ru9rmyxkf0" alt="oryx camada 2"  loading="lazy" /></p>
<p>Por outro lado, se deixar apertado &ldquo;hold 2&rdquo; com dedão direito, agora o backspace vira &ldquo;delete&rdquo; na esquerda. E com isso as mesmas funções estão disponíveis, mesmo tendo fisicamente menos teclas. É só aprender isso de camadas.</p>
<p>Mais do que camadas, tem coisas não uso tanto, com <em>&ldquo;tap-to-hold&rdquo;</em>. Você Dá pra apertar rápido uma vez e depois segurar a mesma tecla, e isso dá gatilho em outro evento. No caso da ferramenta de configuração Oryx, da ZSA, tem opções de configurar o que acontece só quando aperta e tira o dedo (<em>&ldquo;held&rdquo;</em>), ou quando aperta rápido duas vezes (<em>&ldquo;double-tapped&rdquo;</em>), ou quando aperta rápido uma vez e aperta de novo (<em>&ldquo;tapped and then held&rdquo;</em>) e deixa segurando. Ou seja, dá pra configurar no mínimo <strong>3 ações diferentes em cada tecla, em cada camada, e dá pra ter múltiplas camadas!</strong> São centenas de opções!</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/qou3zcgjw79mawagyatme0b0mbc2" alt="Oryx Voyager"  loading="lazy" /></p>
<p>Assim como a Keychron, a ZSA também tem um aplicativo visual via web. É muito mais cômodo do que editar um arquivo JSON. Ele tem já embutido botão pra compilar o firmware e, quando conectar seu teclado no modo de upload, o navegador consegue detectar e é plug-and-play pra subir o firmware. Não precisa instalar nada extra na sua máquina. É esse tipo de poimento comercial que uma opção mais barata como Corne não vai ter. O mais próximo é o QMK Configurator.</p>
<p>E diferente do Corne, o Voyager também tem LEDs RGB. Tá vendo no Oryx como tem opção de <em>&ldquo;set color&rdquo;</em>? Assim fica muito mais fácil pra lembrar onde que tá qual tecla, em qual camada. Até pra saber em que camada estamos neste momento. Muito melhor do que ter que memorizar tudo e não ter feedback nenhum. Acho muito importante o hardware ter alguma forma de comunicar seu estado atual.</p>
<p>Portanto, a experiência do software me faz querer experimentar mais com o Voyager ou Moonlander do que o GK6 que é QMK puro, por exemplo.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/ss2jz5lwpi19mwivpxj0mq4iqhkv" alt="Voyager close up"  loading="lazy" /></p>
<p>Novamente, olhem na minha mão como é fino. Cada metade tem pouco mais de 200g. Com os cabos, o total é menos de <strong>700g</strong>. É próximo do GK6, metade do Q15, mas parece ainda mais leve. O balanço do peso é muito bom.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/dco0ukkdnhi17i4y77x6mk80kbhp" alt="Voyager bottom"  loading="lazy" /></p>
<p>A traseira do Voyager não chega a ser tão elegante quanto do GK6 ou Q15, mesmo assim é bonito o suficiente e funcional, uma vibe mais industrial, com metal e parafusos à mostra e pontos de montagem pra anexar em suportes, caso queira usar em tripé, braço de cadeira ou em &ldquo;tenting&rdquo;. Eu não tentei nenhuma dessas opções, prefiro reto na mesa mesmo.</p>
<p>Mas tem <a href="https://www.reddit.com/r/ErgoMechKeyboards/comments/17fwd57/zsa_voyager_tenting_experiment/"target="_blank" rel="noopener">sub-reddits</a> com projetos de impressão 3D e coisas assim pra quem quiser experimentar tenting no Voyager. Veja um exemplo de lá:</p>
<p><a href="https://www.printables.com/model/597882-zsa-voyager-stand"target="_blank" rel="noopener"><img src="https://preview.redd.it/zsa-voyager-tenting-experiment-v0-kdfxc7d4x9wb1.jpg?width=640&amp;crop=smart&amp;auto=webp&amp;s=5615ebece5db23212ce5fda464039f6847cfcfc9" alt="Voyager tenting"  loading="lazy" /></a>
Tem esta outra opção usando um tripé chamado <a href="https://preview.redd.it/voyager-tenting-with-manfrotto-pocket-tripods-v0-49xxqiada5sb1.jpg?width=640&amp;crop=smart&amp;auto=webp&amp;s=bb095a3a9c18da455e661400e082e0cbaff513f3"target="_blank" rel="noopener">&ldquo;Manfrotto&rdquo;</a>:</p>
<p><img src="https://preview.redd.it/voyager-tenting-with-manfrotto-pocket-tripods-v0-49xxqiada5sb1.jpg?width=5712&amp;format=pjpg&amp;auto=webp&amp;s=cac876389d4ff94206b6b120446a90ae260db688" alt="Manfrotto tripod"  loading="lazy" /></p>
<p>Essa é uma opção que me vejo usando. E tem <a href="https://www.reddit.com/r/ErgoMechKeyboards/comments/16k7p4x/voyager_tenting/"target="_blank" rel="noopener">mais opções</a>. Eu gosto de tenting, é a única coisa que só o Moonlander faz de fábrica. Eu sentiria mais falta se ainda precisasse digitar muito todos os dias, mas como não preciso mais, prefiro o Voyager puro pra ser mais bonito e ocupar menos espaço na minha mesa.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/ducayps3ys884gq2hucn7nl19ppf" alt="minha mesa com voyager"  loading="lazy" /></p>
<p>Esta é minha mesa em Outubro de 2024 e como tem sido por pelo menos 1 ano. Eu troco por outros teclados pra testar, mas sempre acabo voltando nesta configuração, por tudo que já expliquei antes. Eu uso o mouse na mão esquerda (porque minha mão direita dói mais, então me acostumei a usar com a esquerda pra doer os dois igual kkkk). Tenho um Apple Touchpad na direita pra coisas que exigem &ldquo;scrolling&rdquo; (dói muito menos do que &ldquo;scroll-wheel&rdquo; de mouse). E note como uso as duas metades do teclado bem afastados. Essa é uma distância boa, mas dá pra abrir bem mais se quiser.</p>
<p><a name="pulso"></a></p>
<h2>Ortolinear vs Colunar<span class="hx:absolute hx:-mt-20" id="ortolinear-vs-colunar"></span>
    <a href="#ortolinear-vs-colunar" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra ficar claro, achei melhor ilustrar o que significa esse papo todo de pulso. Veja como ficam suas mãos num teclado de uma única peça, um monolito:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/44ia6l5v13w8z5wz9vyhi8hda0c4" alt="pulso rotacionado"  loading="lazy" /></p>
<p>Está claro? Quando o teclado não é split, somos obrigados a trazer as duas mãos super pra perto. Obviamente a única forma de posicionar assim é dobrando os pulsos de uma forma não-natural. Somado à rotação (por não ser tenting), estamos pinçando os nervos e causando micro-lesões, todas as vezes.</p>
<p>Sim, pra quem usa pouco, esporadicamente, não faz diferença mesmo. Isso é pra nós, programadores, escritores, pessoas que digitam horas seguidas. Se você não for essa pessoa não me venha comentar <em>&ldquo;ain, eu não sinto isso&rdquo;</em>. Lógico, você digita pouco.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/8aab5kmzzyym6wr1dq4q8j365d8y" alt="voyager, perto"  loading="lazy" /></p>
<p>Se a intenção for construir um teclado monolito pelo fato de ser mais fácil de carregar na mochila ou algo assim, no mínimo, as duas metades deveriam estar num ângulo, como na foto acima. Dessa forma as mãos teriam que continuar próximas, mas não seria necessário dobrar os pulsos.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/rpe3wdfjduwim2aihulb2pf8sb4h" alt="Voyager, afastado"  loading="lazy" /></p>
<p>Claro, o ideal é split: duas metades que podem ser afastadas. Assim seus braços podem permanecer numa posição natural, reta, sem precisar dobrar nada, sem fazer esforço desnecessário. Isso permite ficar horas digitando sentindo pouca ou nenhuma dor. Se somar a um suporte embaixo, pra elevar o meio do teclado, criando tenting, aí sim, os braços ficam na posição mais neutra possível. E é por isso que eu prefiro este tipo de teclado: <strong>split-colunar-staggered</strong>.</p>
<p><a name="framework"></a></p>
<h2>O Futuro - Framework<span class="hx:absolute hx:-mt-20" id="o-futuro---framework"></span>
    <a href="#o-futuro---framework" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Este artigo foi só porque eu estava com esses teclados parados aqui. E não, não adianta mandar no comentário pra sortear, vender, nem nada disso. São parte da minha coleção, eu deixo na minha prateleira porque acho bonito e posso usar quando der na telha. Não vou me desfazer de nenhum. Não insistam!</p>
<p>Mas se tem uma coisa que me frustra são notebooks. Nenhum tem opção ortolinear. Então sempre preciso conectar um externo via USB ou então digitar mais devagar usando o layout convencional. Mas minhas esperanças aumentaram quando surgiu a empresa Framework.</p>
<div class="video-container">
<video controls preload="auto"> <source src="https://customer-gbu4wsrjcdamtxzc.cloudflarestream.com/864433f3f504c98ddc2d5837b4f081f9/downloads/default.mp4" type="video/mp4"> Your browser does not support the video tag. </video>
</div>
<p>Eles só tem dois modelos, o Laptop 13 e o Laptop 16. Meu ideal seria um 14&rdquo; com formato 3:2 como os Surface, mas o de 13&quot; é mais que suficiente. Eu conheci eles pelo canal <strong>Linus Tech Tips</strong>, pois o Linus Sebastian se tornou um dos primeiros patrocinadores/sócios do projeto.</p>
<p>A ideia parece simples, mas até hoje ninguém conseguiu fazer algo que não só funcione, mas dure anos. Esse laptop é todo modular. E não só nas coisas triviais como trocar uma porta HDMI externa por uma porta Ethernet ou USB 4. Mas também fazer upgrade de memória, e até de placa-mãe, GPU, monitor e &hellip; teclado!!</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Jack at <a href="https://twitter.com/OrtholinearKB?ref_src=twsrc%5Etfw">@OrtholinearKB</a> prepared a mockup of an ortholinear keyboard module for the Framework Laptop 16! Modularity opens up some incredible possibilities. <a href="https://t.co/hKqT3AMU7t">pic.twitter.com/hKqT3AMU7t</a></p>— Framework (@FrameworkPuter) <a href="https://twitter.com/FrameworkPuter/status/1648371892062130176?ref_src=twsrc%5Etfw">April 18, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>Olha só isso. Parece que já faz pelo menos um ano que estão trabalhando numa opção ortolinear! Isso seria meu sonho de consumo! Um teclado de notebook não é mais que um teclado com USB interno. Deveria ser simples de trocar, é mais uma questão de design industrial do que de tecnologia.</p>
<p>Eu estou quase já comprando um Framework Laptop 13 quando for pros EUA este ano, e quando sair o teclado, posso importar só ele (vai custar impostos, óbvio, mas pelo menos vai ser só o teclado). Aí eu terei o notebook definitivo pra digitadores profissionais!!</p>
<p>Esta é a última coisa que falta. Espero que realmente lancem logo e inspirem outros fabricantes a pensar em opções assim: destacáveis e modulares.</p>
<p>Como expliquei nos meus videos, em particular no primeiro video da trilogia, até hoje usamos layouts de teclados absolutamente ruins pras nossas mãos, pulsos e braços. Muitos que trabalham o dia todo digitando vão sofrer com LER e tendinite, mais cedo ou mais tarde. Tudo porque todo mundo tem preguiça de aprender coisas modernas.</p>
<p>Todos acham que é muito difícil, mas é só <strong>preguiça</strong> mesmo. Eu aprendi com mais de 40 anos. Não precisa ser um adolescente pra aprender essas coisas. É só parar de achar que não vai conseguir e fazer, sem pensar nas consequências. Melhor: se conseguir, a consequência é que vai digitar mais rápido, com menos erros e sem forçar suas mãos, evitando dores e doenças ortopédicas.</p>
<p>A Apple, o ápice do que usamos como referência quando pensamos em tecnologia moderna, só tem uma parte que tem fedor de velho: o teclado. Se ela fosse realmente corajosa, como Phil Schiller achava que era, o Macbook tinha que ser assim:</p>
<p><img src="https://preview.redd.it/concept-ortholinear-apple-silicon-macbook-pro-v0-kw2duliaxrea1.png?width=2440&amp;format=png&amp;auto=webp&amp;s=e899a4e2029b24620ecb3c34a1d0ab03ad7dda97" alt="Macbook Ortolinear"  loading="lazy" /></p>
<p>Isso sim, seria um Macbook do século 21, deixando as limitações do layout de máquina de escrever do começo do século 20 pra trás. Por agora, já me dou por satisfeito com meu ZSA Voyager, que é meu &ldquo;daily-driver&rdquo; e faz tudo exatamente do jeito que preciso. Não pretendo descer abaixo dos 40% e ficar fazendo malabarismo.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/015nq7sqccm833ttzeqymrbxe3j8" alt="Coleção"  loading="lazy" /></p>
<p>Eu falei de &ldquo;Corne&rdquo;, mas é só porque é o nome mais popular. Falei que o Felipe me fez um Hillside que é um Corne com rotary, mas existem dezenas de variações como Lily58, Skeletyl, CRKBD, Scylla, Sofie, Totem e muito mais.</p>
<p>Sabe onde consegue ver várias delas? No perfil de Instagram do amigo <a href="https://www.instagram.com/tupinikeebs/"target="_blank" rel="noopener">Felipe/Tupinikeebs</a>. Ele sempre posta um <em>keeb</em> novo por lá, então fique de olho, leve em consideração tudo que falei sobre tamanho, peso, mobilidade, bateria, layouts, 60% vs 40% vs 30%, tenting, split, e encontre a combinação que faz mais sentido pro seu uso particular.</p>
<p>Modelos diferentes existem porque cada pessoa tem usos diferentes. Um escritor de livros é diferente de um programador que é diferente de um contador que é diferente de um cientista de dados e assim por diante. Não existe um teclado universal que funciona perfeitamente pra todo mundo. Sem contar a estética, cores, RGB, tipos de switch, materiais de teclas, etc. Não seja limitado, seja aberto às opções.</p>
<p>Novamente, praqueles que vão insistir em comentar sobre o lendário <strong>Kinesis</strong>, ele é diferente de todos que já mostrei. Eu sei. Tem o formato de uma bacia no centro de cada metade, É uma outra forma de otimizar pra comprimentos diferentes em cada dedo. Em vez de Corne, o que vocês querem é o <strong>Scylla</strong>. Adivinha quem já postou sobre isso? O Felipe:</p>
<p><a href="https://www.instagram.com/p/DBHSdDrR_bR/?utm_source=ig_web_button_share_sheet&amp;igsh=MzRlODBiNWFlZA=="target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/ch3u7epuje0xfk395jikxi95jijy" alt="Scylla"  loading="lazy" /></a>
E por hoje é isso aí, espero que tenham gostado. Não deixem de assistir os videos da trilogia onde explico muito mais detalhes de tudo isso. Só depois pensem em mandar perguntas nos comentários!</p>
]]></content:encoded><category>teclados</category><category>hardware</category><category>reviews</category></item><item><title>[Akitando] #134 - Top 3 Distros Linux | Qual Recomendo?</title><link>https://akitaonrails.github.io/2022/12/23/akitando-134-top-3-distros-linux-qual-recomendo/</link><guid isPermaLink="true">https://akitaonrails.github.io/2022/12/23/akitando-134-top-3-distros-linux-qual-recomendo/</guid><pubDate>Fri, 23 Dec 2022 09:18:00 -0300</pubDate><description>&lt;div class="embed-container"&gt;
&lt;iframe
src="https://www.youtube.com/embed/unpJgmjTLEg"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Como video de fim de 2022, vou participar de uma corrente chamada &amp;ldquo;Top 3 Distros Linux&amp;rdquo;. Vou eleger 3 distros Linux que gosto e depois falar sobre distros Linux em geral.&lt;/p&gt;
&lt;p&gt;E aqui vão os &amp;ldquo;summon&amp;rdquo; pra participar da corrente:&lt;/p&gt;
&lt;p&gt;@HackerVilela
@pikuma
@ManualdoCodigo&lt;/p&gt;
&lt;h2&gt;Conteúdo&lt;span class="hx:absolute hx:-mt-20" id="conteúdo"&gt;&lt;/span&gt;
&lt;a href="#conte%c3%bado" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;00:00 - Intro&lt;/li&gt;
&lt;li&gt;00:49 - As Regras da Corrente dos Top 3&lt;/li&gt;
&lt;li&gt;02:04 - Número 3&lt;/li&gt;
&lt;li&gt;03:28 - Número 2&lt;/li&gt;
&lt;li&gt;05:38 - Número 1!&lt;/li&gt;
&lt;li&gt;08:34 - Como eu enxergo Distros Linux&lt;/li&gt;
&lt;li&gt;12:56 - Recomendação pra Iniciantes?&lt;/li&gt;
&lt;li&gt;15:11 - Summon 1: Vitor&lt;/li&gt;
&lt;li&gt;15:55 - Summon 2: Pikuma&lt;/li&gt;
&lt;li&gt;16:59 - Summon 3: Douglas&lt;/li&gt;
&lt;li&gt;17:56 - Bloopers&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Links&lt;span class="hx:absolute hx:-mt-20" id="links"&gt;&lt;/span&gt;
&lt;a href="#links" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diolinux.com.br/video/top-3-distro-linux.html"target="_blank" rel="noopener"&gt;https://diolinux.com.br/video/top-3-distro-linux.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://toastytech.com/guis/mkde.html"target="_blank" rel="noopener"&gt;http://toastytech.com/guis/mkde.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://batocera.org/"target="_blank" rel="noopener"&gt;https://batocera.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Mandriva_Linux"target="_blank" rel="noopener"&gt;https://en.wikipedia.org/wiki/Mandriva_Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.redhat.com/en/about/press-releases/press-redhat42"target="_blank" rel="noopener"&gt;https://www.redhat.com/en/about/press-releases/press-redhat42&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;SCRIPT&lt;span class="hx:absolute hx:-mt-20" id="script"&gt;&lt;/span&gt;
&lt;a href="#script" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Olá pessoal, Fabio Akita&lt;/p&gt;</description><content:encoded><![CDATA[

<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/unpJgmjTLEg"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Como video de fim de 2022, vou participar de uma corrente chamada &ldquo;Top 3 Distros Linux&rdquo;. Vou eleger 3 distros Linux que gosto e depois falar sobre distros Linux em geral.</p>
<p>E aqui vão os &ldquo;summon&rdquo; pra participar da corrente:</p>
<p>@HackerVilela
@pikuma
@ManualdoCodigo</p>
<h2>Conteúdo<span class="hx:absolute hx:-mt-20" id="conteúdo"></span>
    <a href="#conte%c3%bado" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><ul>
<li>00:00 - Intro</li>
<li>00:49 - As Regras da Corrente dos Top 3</li>
<li>02:04 - Número 3</li>
<li>03:28 - Número 2</li>
<li>05:38 - Número 1!</li>
<li>08:34 - Como eu enxergo Distros Linux</li>
<li>12:56 - Recomendação pra Iniciantes?</li>
<li>15:11 - Summon 1: Vitor</li>
<li>15:55 - Summon 2: Pikuma</li>
<li>16:59 - Summon 3: Douglas</li>
<li>17:56 - Bloopers</li>
</ul>
<h2>Links<span class="hx:absolute hx:-mt-20" id="links"></span>
    <a href="#links" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><ul>
<li><a href="https://diolinux.com.br/video/top-3-distro-linux.html"target="_blank" rel="noopener">https://diolinux.com.br/video/top-3-distro-linux.html</a></li>
<li><a href="http://toastytech.com/guis/mkde.html"target="_blank" rel="noopener">http://toastytech.com/guis/mkde.html</a></li>
<li><a href="https://batocera.org/"target="_blank" rel="noopener">https://batocera.org/</a></li>
<li><a href="https://en.wikipedia.org/wiki/Mandriva_Linux"target="_blank" rel="noopener">https://en.wikipedia.org/wiki/Mandriva_Linux</a></li>
<li><a href="https://www.redhat.com/en/about/press-releases/press-redhat42"target="_blank" rel="noopener">https://www.redhat.com/en/about/press-releases/press-redhat42</a></li>
<li></li>
</ul>
<h2>SCRIPT<span class="hx:absolute hx:-mt-20" id="script"></span>
    <a href="#script" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Olá pessoal, Fabio Akita</p>
<p>Normalmente eu não participaria de correntes, mas por acaso o assunto bateu com alguns dos meus videos mais recentes então decidi participar. Ainda mais porque fui &ldquo;sumonado&rdquo;, praticamente intimado pelo Diolinux no video dele de &ldquo;Top 4 Distros de Todos os Tempos&rdquo;, que por sua vez foi &ldquo;sumonado&rdquo; pelo Slackjeff e assim por diante. A idéia é falar sobre as 3 distribuições Linux que mais me impactaram mas não vale falar da distro que estou usando neste momento. E no final tem que provocar mais pessoas pra continuar a corrente. Este video vai ser curtinho, só pra fechar o ano, então vamos lá!</p>
<p>(&hellip;)</p>
<p>Ironicamente, não pode falar da distro que estou usando neste momento. O problema é que estou usando 4 distros ao mesmo tempo. Deixa explicar, o principal é o Manjaro Gnome, que uso no PC de casa, e é minha máquina de trabalho. Mas tenho vários ambientes virtuais. Quem me acompanha no Instagram sabe disso, e vai ser tema de um próximo video que já estou escrevendo. Mas como ambiente pra retrogames eu tava usando o Garuda Linux numa máquina virtual. Assim como o Manjaro é derivado de ArchLinux também, mas vem mais estilizado e pré-configurado pra gamers. É uma distro bem pesada, feita pra máquinas mais parrudas.</p>
<p>Também tenho um Ubuntu 22 virtualizado pra alguns testes então não vou falar dele e tenho o Windows Subsystem for Linux, ou WSL rodando ArchLinux em cima, que uso no meu notebook porque lá o OS principal é Windows mesmo. Alguns modelos de notebook aceitam Linux de boa, alguns nem tanto, e esse Zephyrus G14 dá probleminhas com coisas como Bluetooth então decidi ficar no Windows mesmo já que uso mais pra viajar.</p>
<p>Então nada de Manjaro, nem Garuda, nem Ubuntu e nem Arch. Pois bem, vou falar primeiro o tema da corrente, as Top 3 distros que acho mais interessantes e depois o que acho que todo mundo realmente queria saber que são as distros que eu usaria como minha principal mesmo. Vamos lá, começando pelo número 3.</p>
<p>A número 3 é a distro que mais usei nos anos 90, e foi a francesa Mandrake Linux que depois se fundiu com a brasileira Conectiva e virou Mandriva, que começou em 1998 e morreu em 2011. Mandrake pra mim sempre pareceu um RedHat mais amigável, mais ou menos como um Ubuntu nasceu como um Debian mais amigável, só que quase uma década antes.</p>
<p>Mandrake vinha com KDE por padrão, e o principal é que tinha um instalador gráfico muito mais interessante que a versão em ncurses padrão dos RedHats. E pra quem não sabe o que é a distro RedHat, depois ele virou CentOS que é mais usado em servidores de empresas e o Fedora que é a versão mais usada em desktops. Além disso tinha o Mandriva Control Center, meio parecido com a proposta do Yast do OpenSuse de ter um painel de controle completo pra configurar o sistema em vez de ter que fazer muita coisa pelo terminal.</p>
<p>O gerenciador de pacote não lembrava o nome, mas pesquisando achei que era o &ldquo;urpmi&rdquo; que funciona como um wrapper pra RPM. Eu jurava que ele usava direto RPMs, que é o formato de pacotes RedHat Package Manager, que ainda é usado no CentOS e Fedora e gerenciado pela ferramenta &ldquo;DNF&rdquo;. O Mandrake, Conectiva e depois Mandriva foi onde realmente comecei a aprender Linux, aprender a programar com Perl, PHP, aprender sobre servidores web, configurar Apache e coisas assim. Eu usei outras distros daquela época, mas sempre voltava pro Mandrake.</p>
<p>O Top 2 acho bacana pra quem só conhece Ubuntus da vida porque é largamente usado e ninguém sabe disso, o Alpine Linux. Se você lida com infraestrutura, principalmente se é devops de Kubernetes e outras plataformas de containers, deve usar Alpine ou Debian. A idéia do Alpine é o oposto de um Fedora ou Ubuntu. Enquanto distribuições pra desktop tentam colocar um monte de software pra tornar a máquina mais fácil de usar, um Alpine tem como objetivo ser o mais leve e o mais seguro possível, vindo só com realmente o mínimo necessário pra um container funcionar.</p>
<p>Acho que tem louco que tenta usar Alpine como desktop, mas ele não foi feito pra isso. Dá? Dá, mas não tem vantagem em desktop, só em containers. Ele deriva de uma linhagem anterior de distros como o antigo LRP ou Linux Router Project ou &ldquo;Linux on a Floppy&rdquo;, cuja idéia era ter uma distro tão pequena que caberia num disquete antigo. Esse tipo de distro é útil pra bootar coisas como roteadores ou firewalls.</p>
<p>Sabe o modem de internet que você tem aí na sua casa? É um Linux dessa família, não necessariamente o Alpine, mas parecido. Ele vem com o kernel, os drivers mínimos pra coisas como placa de rede, nenhum tipo de interface gráfica pesada como KDE, e só um servidor web como Apache pra fornecer uma aplicação web que você acessa pelo navegador do seu PC ou via um app no celular.</p>
<p>Pra quem sobe Docker ou Podman, normalmente puxa imagens cuja base original era um Alpine. Por exemplo, este é repositório onde tem o Dockerfile que gera a imagem de Postgres que você usa nas suas aplicações. Ele tem duas versões, uma gerada a partir de Debian e outra a partir de Alpine. Se olharmos o repositório da imagem de python, o Dockerfile dele também começa com a opção de Alpine e depois Debian.</p>
<p>Debian ainda é bem usado pra essas coisas por causa da sua reputação lendária de estabilidade e maturidade. Mas o Alpine tá lá pau a pau. Diferente de Ubuntu ou Debian que usa a ferramenta &ldquo;apt&rdquo; pra gerenciar pacotes, Alpine usa &ldquo;apk&rdquo; e hoje em dia tem apk pra tudo que precisamos no mundo de servidores ou sistemas embarcados. Como programador, é importante aprender como o Alpine funciona e quais as diferenças com outras distros mais antigas como Debian.</p>
<p>E agora, meu Top 1 é pra dar uma troladinha, mas só pra sair do comum. Acho que é válido falar do Batocera. Quando falamos em distros pra gamers, muitos pensam no PopOS, ou Garuda ou mesmo o meu Manjaro, mas a maioria esquece do Batocera.</p>
<p>Eu uso Batocera num Raspberry Pi ligado neste setup que tenho em casa. Eu sempre quis um arcadezão de madeira que nem tinha antigamente, mas na prática, no meu apartamento pequeno, seria um trambolhão ocupando muito espaço. Daí resolvi repensar o conceito e ter um arcade minimalista. Eu já tinha um raspberry pi sobrando, tinha comprado este joystick de arcade da 8bitdo, que não é nem de longe bom pra competir numa EVO da vida, mas pra jogar casual é excelente. Daí comprei esse monitor portátil, super fino e leve. Tão leve que coloquei fita dupla face da 3M atrás e grudei na parede.</p>
<p>No Raspberry Pi antigamente instalava o RetroPie, que é outra distro dedicada a retrogaming, mas o Batocera acho evoluiu mais rápido e tem o melhor acabamento. Você baixa a imagem dele, instala num SD Card, coloca no Raspberry e já era, tudo funciona. Olha só o boot dele. Já vem com emuladores como RetroArch configurado, já vem com o front-end EmulationStation configurado pra ficar bonito que é esse que estou mostrando, já tem todos os perfis de controles de arcade e gamepads, então é tudo plug and play, não precisa abrir terminal pra ficar gambiarrando nada. Só copiar os arquivos de ROMs dos jogos e jogar. É excelente pra máquinas fracas ou raspberry pra virar central de games antigos.</p>
<p>Eu particularmente gosto muito desse novo mercado de consoles portáteis pra retrogames, como os feitos pela Ambernic ou Retroid. Este é meu Ambernic RG552, e dá pra instalar Batocera nele também. Este é meu Miyoo Mini, mas nesse o recomendado é instalar o Onion OS que é mais configurado pra este hardware em particular. E este é meu Aya Neo Next Pro que tá com Windows mesmo, mas esse é potente demais e seria meio desperdício usar Batocera nele. É basicamente a performance de um notebook. Se eu ligar um teclado e mouse, posso substituir meu notebook em viagens.</p>
<p>Se quiserem reviews de consoles portáteis, como configurar Batocera, Onion e muito mais, assinem os canais Retro Game Corp, Taki Udon, ETA Prime e Retro Dodo, que são os que eu assisto. Eles tem falado de Steam Deck, Aya Neo, Ayn Odin, e muito mais.</p>
<p>Pronto, terminei minha missão: os Top 1 e Top 2 foram pra abrir a curiosidade de vocês em ir conhecer distros Linux especiais pra usos específicos que não só desktop. Acho esse assunto bem mais fascinante do que ficar discutindo tema mais bonitinho de KDE ou GNOME. E agora que terminei meus Top 3 da corrente, deixa eu fazer alguns comentários sobre o que acho de outras distros.</p>
<p>Pra mim o mundo de distros se divide assim. Primeiro tem as distros OG, as originais ou derivadas das originais. Coisas como Slackware, que foi minha primeiro distro, ou Gentoo, que poderíamos dizer que é o menos velho dessa categoria. Mas são as distros que exigem que você tenha mais intimidade com a máquina e com baixo nível da kernel e configurações mais cabeludas. Não foram feitas pra serem amigáveis, foram feitas pra quem sabe o que está fazendo. Debian pra mim se encaixa nesse grupo. Se quiserem ver como é Slackware e Gentoo eu fiz um video pra cada recentemente, dêem uma olhada depois.</p>
<p>Daí existe a RedHat, que nos anos 90 despontou como a melhor solução de Linux comercial, oferecendo garantias, suporte técnico e tudo mais. Em paralelo apareceu a alemã Suse que hoje é OpenSuse e foi competidor de outros comerciais como Caldera Linux da Novell ou VA Linux que foi o primeiro IPO de Linux no meio da bolha da Internet do fim dos anos 90. RedHat junto com a Suse foram os únicos que sobreviveram. Dela derivam Fedora e CentOS que se usa até hoje.</p>
<p>Na virada do século nasce o Ubuntu, que é derivado de Debian e usa o mesmo formato de pacotes DEB e o mesmo gerenciador de pacotes apt. Ubuntu é o Debian menos estável, porque trás pacotes mais novos. Normalmente em servidor ou embarcado você não quer os pacotes mais novos, você quer os mais testados, estáveis, maduros e livres de bug.</p>
<p>Parte da popularidade do Ubuntu se deve a ele ter sido mais pragmático. Debian segue a filosofia de software livre mais à risca. Nada de binários sem código-fonte ou código que não tenha licença realmente livre. Já Ubuntu preferiu ser mais amigável e incluiu coisas como codecs de mp3, de video, drivers binários de hardware como NVIDIA e tudo mais. Isso facilita a vida do usuário médio, mas já não segue mais a idéia de software livre. Muitas distros hoje fazem a mesma coisa.</p>
<p>Em desktop não tem tanto problema instalar um pacote com bug e esperar alguns dias pra aparecer a correção. Mas em embarcado ou servidor, isso é um grande problema. Imagina um bug que é automaticamente instalado em centenas de servidores e causa crash pra todos os usuários. Seria uma catástrofe. Por isso um Debian da vida oferece pacotes mais &ldquo;velhos&rdquo; mas que sabemos que funcionam sólidos.</p>
<p>Tem gente que não curte o Ubuntu da Canonical. Seja porque não gosta de laranja, seja porque não gosta de Snap ou seja lá o que for, seja porque não curtem Unity ou GNOME. Daí surgiram dezenas de distribuições derivadas de Ubuntu. Nessa categoria temos o PopOS, Linux Mint, Elementary, Zorin OS, Budgie, Feren, Lubuntu, KDE Neon e vários outros. O que muda é a interface gráfica, quais pacotes já vem pré-instalados, configurações e tuning do sistema. Mas pra mim é tudo Ubuntu.</p>
<p>Tem uma coisa que eu não curto em APT, que é o gerenciador de pacotes que todos usam, e ter que instalar e configurar PPAs pra instalar pacotes de terceiros. Acho um saco, acho manual demais, acho bugado. Por isso passei a preferir derivados de ArchLinux pra desktop. Arch é o oposto de Debian: o mais instável possível porque ele instala tudo que sai de novo. E eu sou o tipo de cara que gosta de novidades o quanto antes.</p>
<p>ArchLinux funciona no sistema de rolling updates. Não tem isso de upgrade de Ubuntu 20 pra 21, de 21 pra 22, ele vai só se atualizando constantemente. O problema disso é que quase todo dia tem atualização. Quem se incomoda com isso vai odiar. E também por causa disso, vira e mexe pode vir uma novidade pouco testada que causa bugs.</p>
<p>E pra piorar ainda temos o AUR que é o Arch User Repository, onde qualquer um pode subir qualquer pacote de qualquer coisa. A vantagem disso é que todo software que imaginar provavelmente alguém subiu lá e tá fácil pra instalar. A desvantagem é que todo mundo pode subir qualquer coisa e vira e mexe sobe mal feito e mal testado: você instala e dá pau.</p>
<p>Essa não é uma distro pra amadores. Vira e mexe vai ter que consertar alguma coisa na não. Por isso existem derivados de Arch que tentam estabilizar um pouco mais as coisas e aí chegamos no meu Manjaro. Em vez de liberar pacote novo toda hora, o Manjaro dá uma segurada pra dar tempo da comunidade testar um pouco mais, subir correções e só depois eles liberam tudo de uma vez só.</p>
<p>Ele atualiza com menos frequência e quando vem atualização não quebra catastroficamente. E Manjaro passou a oferecer o sistema de arquivos BTRFS já na instalação, em vez de ext4, então temos suporte a snapshots, que oferece outra camada de proteção caso a gente instale um pacote bugado. Vou falar disso em outro video.</p>
<p>Isso tudo dito, pra um iniciante que não sabe bem que distro usar, posso recomendar ou Manjaro, seja KDE ou GNOME, ou PopOS que acho que é um dos derivados de Ubuntu mais bem feitinhos. Ou direto o próprio Ubuntu. A vantagem é que a maioria dos posts de blog e tutoriais documentam como fazer as coisas em Ubuntu. Raramente você vai achar um post que ensina como fazer as coisas em Gentoo ou Slackware, mas pra Ubuntu é mais fácil. Por isso que falamos que é mais indicado pra iniciante: porque tem mais chances de achar documentado como resolver um problema específico.</p>
<p>ArchLinux e Gentoo tem outra coisa legal: o Wiki deles são a melhor documentação de Linux ever. Sério, tudo que imaginar tem documentado lá. Se não tiver na Wiki do Arch, vai ter na Wiki do Gentoo. Se não tiver mesmo lá, parabéns, você achou alguma coisa que ninguém no mundo viu ainda. Mas esse Wiki pode intimidar os iniciantes, porque é bem detalhado.</p>
<p>Mas na prática o que todo mundo quer mesmo saber é qual interface gráfica usar, independente da distro por baixo. KDE que você gasta algum tempo configurando temas e plugins, costuma ser o mais bonito, mas também meio pesadão. Recomendo brincar com gerenciadores de tiling window, onde as janelas ficam automaticamente uma do lado da outra em vez de uma em cima da outra. Quem popularizou isso foi o i3, o próprio PopOS trás essa funcionalidade de forma opcional que é legal pra começar, mas pra ser mais hardcore tentem usar o Sway ou XMonad.</p>
<p>Sway é mais ou menos a mesma coisa que o i3 mas feito pra rodar em Wayland. Se tiver GPU que não seja NVIDIA, provavelmente é a que vai rodar melhor. E o mais avançado acho que é XMonad. São interfaces gráficas feitas pra operar sem mouse. É pra programador hardcore de Vim ou Emacs que não tira os dedos das teclas pra nada. Eu já usei, e se minha rotina ainda fosse só programar, certamente usaria um dos dois. Mas como não é mais, fico no GNOME, que é o mais simples, não precisa customizar muito, e se comporta mais parecido com os antigos MacOS.</p>
<p>No geral é isso, por hoje é só. Diferente fazer um video curto assim. Pra continuar a corrente, preciso dar summon em outros canais pra passar o bastão. Eu realmente não assisto muitos canais de programação nem Linux no YouTube, então vou chamar dois que já interagi pelo Twitter e um terceiro que me indicaram. Eles fazem coisas bacanas que vocês vão gostar.</p>
<p>O primeiro é o Vitor Vilella. O moleque é hardcore, ele pega binários de ROMs de jogos de Super NES que tem problemas de lentidão, como Gradius III, por exemplo, e ativa chips de aceleração do Super NES como o SA-1. Ele faz assembly de chip de Super NES, e a ROM resultante dá até pra gravar num chip de cartucho de verdade e jogar no hardware original.</p>
<p>Encontrei ele por causa do projeto de Super Mario World em widescreen. Sério, ele ajustou o jogo todo pra ter mais espaço na direita e na esquerda e dar pra ver mais da fase ao mesmo tempo, sem quebrar nada. Só baixar um emulador como o BSNES que tem suporte a esse tipo de hack e jogar. Eu assino o Patreon dele. Dêem uma olhada. O canal de YouTube ainda é pequeno mas vale a pena.</p>
<p>O segundo que me veio à cabeça é o Pikuma &hellip; paikuma? pikuma? Eu acho que ele é professor brasileiro que trabalha na Inglaterra. Ele vende cursos online. E eu sei, logo eu anti-curso recomendando curso é foda, e já deixando claro que ele não me pagou pra dizer isso, mas os temas dos cursos dele são interessantes.</p>
<p>Segundo o site dele, o objetivo é ensinar as fundações da programação de verdade, que eu sempre falo que ninguém ensina, como álgebra linear, trigonometria, matemática discreta e análise numérica, cálculo. Só que em vez de serem aulas teóricas chatas, ele faz isso aplicando na construção de um motor de jogos 2D em C++, ou programando em assembly do antigo Atari VCS, ou replicando o sistema de raycasting usado nos primeiros jogos de tiro como Wolfenstein.</p>
<p>Eu não cheguei a assistir nenhum dos cursos, estou chutando que sejam bons pelo tema e pelos capítulos que li. Claro que não dá pra explicar a ciência da computação inteira só nesses cursos, mas com aplicações reais e divertidas, deve incentivar o pessoal a procurar se aprofundar depois. Vocês podem me dizer nos comentários se gostaram.</p>
<p>O terceiro canal me foi recomendado pelo Twitter  e esbarrei no Manual do Código do Douglas. Esse cara tem centenas de videos de temas interessantes de programação. Ele deveria ter muito mais seguidores. Vão lá dar uma moral pra ele. Assim como o Pikuma, também fala de programação de videogames antigos, tem javascript, tem python, tem megadrive, tem muita coisa pra quem curte programação.</p>
<p>E é isso aí, agora é com vocês, claro que é opcional participar da corrente, mas acho que foi uma boa oportunidade pra falar de outros canais aqui do Brasil que tão fazendo mais do que repetir as mesmas coisas cansadas de Python ou Javascript. Quem conhecer outros canais parecidos e quiser recomendar, não deixem de postar nos comentários abaixo. Se curtiram o video mandem um joinha, assinem o canal e compartilhem o video com seus amigos. E você assistindo, mesmo não tendo sido intimado aqui, faça um video de Top 4 distros também e compartilhem. Boas Festas, Feliz Natal e a gente se vê em 2023, Feliz Ano Novo!</p>
]]></content:encoded><category>linux</category><category>reviews</category><category>akitando</category></item><item><title>[Akitando] #129 - Apanhando do Gentoo | Melhor Linux???</title><link>https://akitaonrails.github.io/2022/10/11/akitando-129-apanhando-do-gentoo-melhor-linux/</link><guid isPermaLink="true">https://akitaonrails.github.io/2022/10/11/akitando-129-apanhando-do-gentoo-melhor-linux/</guid><pubDate>Tue, 11 Oct 2022 09:47:00 -0300</pubDate><description>&lt;div class="embed-container"&gt;
&lt;iframe
src="https://www.youtube.com/embed/cSyTjCUFx2A"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Finalmente vamos tentar instalar e configurar uma das distros Linux mais trabalhosas de todas. O lendário Gentoo foi pensado pra você tirar o máximo proveito do seu hardware, customizando e compilando tudo do zero especificamente pra sua máquina. A primeira parte do video vai cobrir um pouco o que significa instalar uma distro assim. E na segunda e última parte vamos discutir se vale a pena todo o trabalho.&lt;/p&gt;</description><content:encoded><![CDATA[

<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/cSyTjCUFx2A"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Finalmente vamos tentar instalar e configurar uma das distros Linux mais trabalhosas de todas. O lendário Gentoo foi pensado pra você tirar o máximo proveito do seu hardware, customizando e compilando tudo do zero especificamente pra sua máquina. A primeira parte do video vai cobrir um pouco o que significa instalar uma distro assim. E na segunda e última parte vamos discutir se vale a pena todo o trabalho.</p>
<p>== Errata</p>
<p>Os capítulos 9 e 10 aparecem errado no video mas está correto no índice de tempo abaixo.</p>
<p>== Conteúdo</p>
<ul>
<li>00:00 - Intro</li>
<li>01:03 - CAP 1 - Mesma coisa que Slackware - Instalando Gentoo</li>
<li>06:22 - CAP 2 - CHROOT - Quebrando a Prisão</li>
<li>11:32 - CAP 3 - Depois do Stage3 - Terminando a instalação</li>
<li>17:59 - CAP 4 - Compilando a Kernel - Customizando seu Gentoo</li>
<li>25:34 - CAP 5 - Resolvendo seu Primeiro Problemão - Não boota!</li>
<li>29:24 - CAP 6 - Tentando Instalar GNOME - Mais um Problemão</li>
<li>35:49 - CAP 7 - GDM, WebKit, Reflexões - Final da Instalação</li>
<li>37:35 - CAP 8 - Mais um Problema de SystemD - OpenRC</li>
<li>39:33 - CAP 9 - Por que e Quando usar Gentoo? É pra mim?</li>
<li>42:52 - CAP 10 - Qual a Melhor Distro? Eu sei &ldquo;Linux&rdquo;?</li>
<li>45:57 - Bloopers</li>
</ul>
<p>== Links</p>
<ul>
<li>Gentoo AMD64 Handbook (<a href="https://wiki.gentoo.org/wiki/Handbook:AMD64/pt-br"target="_blank" rel="noopener">https://wiki.gentoo.org/wiki/Handbook:AMD64/pt-br</a>)</li>
<li>Quick Installation Checklist (<a href="https://wiki.gentoo.org/wiki/Quick_Installation_Checklist#UEFI.2FGPT"target="_blank" rel="noopener">https://wiki.gentoo.org/wiki/Quick_Installation_Checklist#UEFI.2FGPT</a>)</li>
<li>GNOME/Guide (<a href="https://wiki.gentoo.org/wiki/GNOME/Guide"target="_blank" rel="noopener">https://wiki.gentoo.org/wiki/GNOME/Guide</a>)</li>
<li>GNOME/GNOME without systemd/Gentoo (<a href="https://wiki.gentoo.org/wiki/GNOME/GNOME_without_systemd/Gentoo"target="_blank" rel="noopener">https://wiki.gentoo.org/wiki/GNOME/GNOME_without_systemd/Gentoo</a>)</li>
<li>GCC optimization (<a href="https://wiki.gentoo.org/wiki/GCC_optimization"target="_blank" rel="noopener">https://wiki.gentoo.org/wiki/GCC_optimization</a>)</li>
<li>Gentoo Cheat Sheet (<a href="https://wiki.gentoo.org/wiki/Gentoo_Cheat_Sheet"target="_blank" rel="noopener">https://wiki.gentoo.org/wiki/Gentoo_Cheat_Sheet</a>)</li>
<li>Upgrading Gentoo (<a href="https://wiki.gentoo.org/wiki/Upgrading_Gentoo#Updating_packages"target="_blank" rel="noopener">https://wiki.gentoo.org/wiki/Upgrading_Gentoo#Updating_packages</a>)</li>
</ul>
<h2>SCRIPT<span class="hx:absolute hx:-mt-20" id="script"></span>
    <a href="#script" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Olá pessoal, Fabio Akita</p>
<p>Vamos continuar a saga de Linux por baixo do capô e como prometido, desta vez o video vai ser mostrando o lendário Gentoo. Mesmo quem nunca tentou instalar acho que já ouviu falar dele. A distro onde todo o sistema é compilado na sua máquina em vez de baixar pacotes binários pré-compilados.</p>
<p>Não é a distro mais difícil, mas certamente é chatinha, talvez ainda mais chatinha que o Slackware, e muito demorada, vocês vão ver. Só pra ter uma idéia, num ambiente controlado que é uma máquina virtual, mesmo assim eu recomecei a instalação do zero múltiplas vezes e ainda tive que fazer muita tentativa e erro até conseguir bootar.</p>
<p>(&hellip;)</p>
<p>O projeto original do Gentoo se chamava Enoch Linux, lá no começo deste século, e o objetivo era criar uma distro customizável que não instalava nenhum binário e sempre compila tudo direto na sua máquina. Consigo imaginar as vantagens disso. Mesmo assim, ainda não recomendo pra todo mundo. Esperem até o final que vou explicar porquê.</p>
<p>Sem mais delongas, mesma coisa que Ubuntu ou Slackware, vamos no site, baixar a ISO pra gravar no pendrive e bootar o instalador. No caso do Gentoo tem uma peculiaridade. Não esquece de baixar esse arquivo chamado stage3 aqui embaixo. Se quiser uma instalação pra servidor, ou seja, sem interface gráfica, baixe um dos dois primeiros arquivos. Se quiser instalar em desktop com gerenciador gráfico de janelas, escolha o profile de desktop. Em ambos os casos, você pode escolher se prefere usar systemd ou openrc.</p>
<p>Já expliquei um pouco sobre init systems e o systemd no episódio anterior de Slackware, mas de novo, se já está acostumado a usar uma distro mais popular como Ubuntu ou Fedora, eles usam systemd e talvez você prefira instalar systemd aqui também, pra não ter que reaprender muita coisa. Por outro lado, justamente porque estamos já tendo o trampo de instalar e configurar Gentoo, por que não usar OpenRC? Já que é uma das poucas distros que tem a opção de não usar systemd. Experimentar coisas novas e diferentes sempre vai agregar, no mínimo você vai ter outra perspectiva.</p>
<p>Eu resolvi escolher o stage3 de profile desktop com openrc por padrão. De resto, mesma coisa, colocamos a ISO no CD-ROM virtual da máquina virtual, bootamos e deixamos carregar. E diferente do Slackware, que cai no login em modo texto, aqui caímos em modo gráfico abrindo KDE. A tela está pequena porque não carregou serviço das ferramentas de guest da vmware pra ajustar resolução. Depois resolvemos isso.</p>
<p>Mas meio que tanto faz pra agora, porque vamos abrir o terminal e fazer tudo dele de qualquer jeito, já que Gentoo também não usa o instalador gráfico Calamares e nos obriga a configurar tudo na mão, bem old school mesmo, e por isso escolhi falar dele pra mostrar algumas coisas que não expliquei na instalação de Slackware.</p>
<p>Uma das grandes vantagens do Gentoo é que o site deles é muito bem documentado. Tem um wiki bem completo que, embora não seja do tamanho do wiki do Arch Linux, mesmo assim consegui encontrar quase tudo que queria. Vale a pena experimentar Gentoo só como desculpa pra estudar a wiki e aprender mais sobre Linux em geral. Em particular, como estou instalando dentro do VMWare, vou precisar usar a página de Wiki específica sobre VMWare, que também é meio válido pra VirtualBox. Então lembrem de ler caso queiram experimentar no VirtualBox de vocês.</p>
<p>Eu vou seguir primariamente esta página que é o &ldquo;Quick Installation Checklist&rdquo;. Como disse no episódio passado, este video não é um tutorial pra seguir passo a passo. Vou usar a instalação como desculpa pra explicar conceitos de Linux e também uma parte do processo de tentativa e erro normal. Assistam tudo primeiro, depois leiam as páginas da wiki, e depois se aventure a instalar direto na sua máquina ou num VirtualBox.</p>
<p>E não se preocupe, você não vai acertar na primeira vez. Eu mesmo tiver que reinstalar umas três ou quatro vezes na minha máquina virtual até conseguir terminar, foi um dia inteiro de tentativas e erro. Errar e recomeçar faz parte do aprendizado. Se quiser uma instalação fácil que acerta tudo de primeira, e não aprender nada, baixa Ubuntu.</p>
<p>Enfim, a wiki já começa sendo legal com você. Se sua máquina for muito antiga, de mais de 10 anos pra trás, pode ser que tenha BIOS em vez de UEFI e só suporte boot com MBR. Se for um pouco menos velha talvez seja BIOS com GPT, e se for mais moderna vai ser UEFI e GPT. Já falei disso no video passado e na minissérie sobre armazenamento. Assistam depois. Se tiver assistido, já sabe a diferença de BIOS e UEFI e MBR e GPT. No meu caso vou escolher UEFI e GPT, só garantir que na minha máquina virtual selecionei UEFI também, por padrão ele simula uma BIOS antiga, cuidado com isso.</p>
<p>O resto é a mesma coisa que já mostrei no video de Slackware. Uso <code>cfdisk</code> pra particionar o HD e depois comandos como <code>mkfs.ext4</code> e <code>mkswap</code> pra formatar as partições. A única diferença é que no video de Slackware fui preguiçoso e só criei 3 partições, 1 de boot efi, 1 de swap e a principal. Esse wiki manda criar 4, que é mais correto, 1 partição separada pro mount point de &ldquo;/boot&rdquo;, outra pra &ldquo;/boot/efi&rdquo; dentro, daí as mesmas de swap e outra pra principal.</p>
<p>Não vou explicar linha a linha tudo de novo. Veja o episódio anterior pra detalhes disto. Mas é esta sequência de comandos aqui do lado. Primeiro estas, depois do cfdisk, pra formatar as partições e depois esta outra sequência pra montar as partições dentro de &ldquo;/mnt/gentoo&rdquo;, que vai ser a raíz da instalação.</p>
<p>Agora vem a hora daquele Stage3 que falei no começo, o zipão de 500 megas. O wiki manda entrar no diretório &ldquo;/mnt/gentoo&rdquo; e usar wget pra baixar o zipão. É o jeito mais fácil mesmo se o LiveCD detectou seu wifi ou sua rede cabeada e tá conectado na internet. Se não estiver, baixa em outro computador, coloca num pendrive, e copia do pendrive pra dentro desse diretório.</p>
<p>No meu caso, abro o firefox, e na página de download seleciono o stage3 pra desktop com openrc. Agora é descompactar com o comando <code>tar xpf stage3*</code>. Vai parecer que travou, mas é porque o arquivo é grandão e leva alguns minutos pra descompactar tudo, paciência.</p>
<p>Pronto. Se der um <code>ls</code>, olha só, tem os diretórios que você já deve ter visto em qualquer instalação de Linux, o &ldquo;/usr&rdquo;, &ldquo;/etc&rdquo;, &ldquo;/bin&rdquo;, &ldquo;/var&rdquo; e tudo mais. Tecnicamente o Gentoo já tá instalado, agora vem a parte mais complicada, que é configurar tudo antes de bootar. E a próxima seção do Wiki se chama &ldquo;Chroot&rdquo;. Então chegou a hora de fazer uma tangente pra explicar o que é isso.</p>
<p>Deixa eu bootar meu Ubuntu em outra máquina virtual e abrir um terminal. Agora vou criar um diretório qualquer e chamar de &ldquo;jail&rdquo; ou &ldquo;prisão&rdquo; mesmo. Tenha paciência que vou executar vários comandos que podem não fazer sentido, mas vai fazer. Lembra que executáveis de Linux costumam ter dependência de outros objetos binários ou bibliotecas compartilhadas? Que nem em Windows que você tem DLLs?</p>
<p>Lembra também quando falei sobre PATH? Quando executamos <code>ls</code>, onde que realmente tá esse executável? Podemos saber usando o comando <code>which ls</code> e descobrimos que o caminho completo é &ldquo;/usr/bin/ls&rdquo;. Fazemos a mesma coisa pro shell Bash, que é a linha de comando onde estamos. <code>which bash</code> e tá em &ldquo;/usr/bin/bash&rdquo;. Beleza, vou precisar desses binários.</p>
<p>Uma ferramenta que nunca tinha mostrado é o <code>ldd</code>. Ela analisa um binário e lista as bibliotecas compartilhadas que depende. Fazemos <code>ldd /usr/bin/bash</code> e <code>ldd /usr/bin/ls</code>. Estes são os objetos binários que eles precisam. Agora vem a parte estranha. Recriamos esses diretórios dentro do &ldquo;jail&rdquo; com <code>mkdir -p jail/bin</code> depois <code>mkdir -p jail/lib/x86_64-linux-gnu</code>, <code>mkdir -p jail/lib64</code>. Copiamos os binários do bash e ls pra &ldquo;jail/bin&rdquo; e depois, um a um, copiamos as bibliotecas pra dentro de &ldquo;jail/lib&rdquo; e &ldquo;jail/lib64&rdquo;. Trabalhinho. Já entenderam o que vou fazer?</p>
<p>Pronto, listando com <code>ls jail</code>, temos todos os bits necessários pra rodar bash e ls. Mas qual o objetivo de duplicar essas coisas? Agora vem o truque: rodamos <code>sudo chroot jail /bin/bash</code>. E olha só, abriu um shell de bash. Duh, grande bosta. Mas presta atenção, estamos rodando o bash que copiamos dentro do diretório &ldquo;jail&rdquo;.</p>
<p>Fazendo <code>ls /</code> pra listar a raíz, cadê meu Ubuntu, cadê todos os outros diretórios? Estou preso dentro do jail, enxergando como se esta prisão fosse a raíz do sistema. Parece uma máquina virtual né? Só que não é. <code>chroot</code> literalmente quer dizer &ldquo;change root&rdquo; ou &ldquo;mude a raíz&rdquo;. Ele faz o sistema operacional mentir pro meu usuário achar que a raíz do drive agora é só isso. A grosso modo, é como se eu tivesse bootado pra dentro de outra máquina, sem realmente ter feito um boot de verdade.</p>
<p>Eu chamei o diretório de &ldquo;jail&rdquo; porque neste momento meu usuário está preso dentro dessa cadeia. Ele acredita que meu HD de verdade é o que está dentro da cadeia. Por isso copiei as bibliotecas do bash e ls pra dentro, senão eles nem iam conseguir executar. Se der exit, pronto, voltamos ao normal. <code>ls /</code> agora lista minha partição de verdade.</p>
<p>Sei que é um pouco confuso isso, mas vocês tem que perder a noção de associar a raíz do sistema com seu HD físico. A raíz do sistema é um ponto de montagem, por acaso eu associo &ldquo;/&rdquo; com a partição usando o sistema de arquivos ext4, é o que tá configurado no arquivo &ldquo;/etc/fstab&rdquo;. Mas posso mudar isso dinamicamente mesmo depois do boot. Linux é um sistema dinâmico, não pense nele como algo congelado e fixo.</p>
<p>Chroot é bem útil pra várias aplicações, mas um uso errado é segurança. Se procurar no Google vai achar tutoriais, por exemplo, pra fazer um usuário se conectando via SSH cair dentro de um chroot. Alguns pensam que é uma boa forma de evitar que o usuário consiga enxergar o sistema de arquivos de verdade da máquina por baixo. Uma forma de segurança. Mas chroot nunca foi projetado pra ser usado pra segurança.</p>
<p>Antigamente, coisa de mais de 20 anos atrás, a gente usava chroot em processos como servidor web Apache, na esperança que se o apache fosse invadido, o invasor ia cair dentro de um chroot e não ter acesso à partição toda do servidor. De novo, chroot não é mecanismo de segurança. Deixa eu provar com o tiro pode sair pela culatra. Chroot é executado como root e permanece com o setuid de root dentro. Vamos tentar estourar essa prisão. Nada nessa manga, nada nessa outra. Minto na verdade eu tenho um programinha feito em C que achei no Google. Esse aqui.</p>
<p>`#include &lt;sys/stat.h&gt;</p>
<h1>include &lt;stdlib.h&gt;</h1><h1>include &lt;unistd.h&gt;</h1><p>//gcc break_chroot.c -o break_chroot</p>
<p>int main(void)
{
mkdir(&ldquo;chroot-dir&rdquo;, 0755);
chroot(&ldquo;chroot-dir&rdquo;);
for(int i = 0; i &lt; 1000; i++) {
chdir(&quot;..&quot;);
}
chroot(&quot;.&quot;);
system(&quot;/bin/bash&quot;);
}`</p>
<p>Vou compilar, copiar esse binário pra dentro do diretório jail/bin, entro no chroot de novo, estou preso, tá vendo? Não enxergo nada fora. Agora é só executar e .. boom, olha só, não só estourei pra fora do jail como invadi o usuário de root dessa máquina. Isso que se chama escalação de privilégios.</p>
<p>O que ele faz é simples. Esse programinha poderia ter sido feito em python, shell script ou o que quiser. Ele só cria um novo diretório com mkdir, dentro dele faz um loop com equivalente a <code>cd ..</code> mil vezes, e sabemos que &ldquo;..&rdquo; é pra voltar pro diretório anterior. Mas ele explora algum bug do chroot que ao fazer isso um tanto de vezes e depois criar outro chroot dentro desse chroot, ele estoura pra fora e mantém os privilégios do usuário que criou o primeiro chroot, que foi o root.</p>
<p>Enfim, essa tangente foi só apresentar chroot e pra ilustrar o ponto que apesar de parecer um mecanismo de segurança ao isolar o usuário num diretório mais limitado, na realidade não é, é uma conveniência que serve justamente pra coisas como instalar de Linux, que é justamente o que o tutorial do wiki do Gentoo vai nos mandar fazer no próximo passo.</p>
<p>Veja que na página de Wiki a próxima seção se chama justamente &ldquo;Chroot&rdquo;. Entramos no diretório <code>cd /mnt/gentoo</code> que foi onde descompactamos aquele arquivão stage3 e instalamos todos os arquivos do sistema. Criamos pontos de montagem pra diretórios virtuais especiais de Linux usando parâmetros especiais do comando <code>mount</code>. Pra proc, sys, dev e run, tudo dentro do /mnt/gentoo.</p>
<p>Com tudo montado, no final copio o &ldquo;/etc/resolv.conf&rdquo; que tem configuração de DNS e faço um chroot pro diretório corrente, executando o <code>/bin/bash</code> que tá dentro desse chroot. A partir de agora, pro meu usuário, o novo &ldquo;/&rdquo; é o que tem no diretório &ldquo;/mnt/gentoo&rdquo;, sacaram? Estou dentro do meu gentoo recém instalado, sem precisar bootar. Saí da partição do LiveCD e entrei na partição do novo Linux instalado no meu HD. Assim posso mexer lá dentro sem ter que bootar ainda. E nem daria pra bootar, porque essa instalação ainda não tem kernel e nem bootloader configurado, que é o que fazemos agora.</p>
<p>De novo, a partir deste ponto é como se eu já estivesse no novo Gentoo instalado no meu HD de verdade, sem ter precisado bootar. Isso é um jeito super rudimentar e incompleto de container, como um Docker. Você já está num Linux funcionando, a gente só muda a raíz do usuário pra outra raíz em outra partição e de lá de dentro é um Linux com ferramentas diferentes, embora usando a mesma kernel que já tava carregada. Ainda não é hoje que vou falar de containers, mas pra chegar lá achei útil explicar que chroot existe, e apesar de ter um efeito parecido, não é usado em containers de verdade.</p>
<p>Agora que estamos dentro do nosso novo Linux, o que todo mundo sempre fala pra fazer logo que instala um Linux novo? Atualizar os pacotes com o repositório online pra ver se tem pacotes novos pra instalar. Num Ubuntu da vida, no terminal, é só executar <code>apt update &amp;&amp; apt upgrade</code>. Mas Gentoo não usa Apt e sim Portage e o comando é <code>emerge</code>. Gentoo não instala software, ele &ldquo;emerge&rdquo; software .. Enfim, o equivalente ao <code>apt update</code> é <code>emerge-webrsync</code>. Pra aprender outros comandos de emerge, a wiki tem outra página com um cheat sheet, explicando as principais opções. Vou deixar o link na descrição abaixo.</p>
<p>Feito isso, até agora só temos o usuário de root funcionando, mas sem senha. Então precisamos criar uma senha forte pro root com o comando <code>passwd</code>. Por acaso a política de senhas do Gentoo é mais restrita que de um Ubuntu, ele exige senhas um pouco mais fortes, então cuidado aqui. Depois disso, só criar um usuário normal não-administrador com o comando <code>useradd</code> e mudar a senha dele também.</p>
<p>Precisamos editar alguns arquivos de configuração, então próximo passo é instalar um editor de textos de linha de comando decente. Por isso <code>emerge -vq vim</code>. Se ainda não sabe usar vim, tudo bem, usa um nano da vida, qualquer editor serve, mas você precisa aprender a usar um editor de linha de comando. VSCode não vai te ajudar quando precisar dar SSH num servidor. Depois disso precisamos editar o arquivo &ldquo;/etc/fstab&rdquo;, que já expliquei no video passado, é onde declaramos os pontos de montagem principais, ligando partições como &ldquo;/dev/sda1&rdquo; com pontos de montagem como &ldquo;/boot&rdquo;.</p>
<p>Como expliquei no começo, o conceito todo do Gentoo é baixar pacotes de código-fonte dos softwares e compilar na hora de instalar. Significa que temos que configurar o compilador com parâmetros de compilação e a configuração global do Portage fica no arquivo &ldquo;/etc/portage/make.conf&rdquo;. Lendo as páginas de instalação do Wiki, mantenho tudo igual e só no final adiciono as seguintes variáveis de ambiente:</p>
<p><code>ACCEPT_LICENSE=&quot;*&quot; GRUB_PLATFORMS=&quot;efi-64&quot; USE &quot;-qt5 -kde X gtk gnome&quot; VIDEO_CARDS=&quot;vmware&quot; INPUT_DEVICES=&quot;libinput synaptics&quot;</code></p>
<p>De novo, isto não é pra ser um tutorial completo de instalação, certamente tem mais configurações importantes que eu não vi, então faça sua pesquisa. Pra mim, nesse cenário de máquina virtual, isso foi o suficiente. E no meu caso vou instalar GNOME como gerenciador de janela, por isso tem &ldquo;-qt5 -kde&rdquo;, pra priorizar opções em gtk e gnome.</p>
<p>Vale a pena explicar é esse Accept License pra asterisco. Acho que o emerge restringe instalar pacotes de softwares com licenças não livres, daí ele mascara esses pacotes e eu tive problema de não conseguir instalar por causa disso. Mas dizendo pro Portage aceitar as licenças, daí consigo instalar. E veja também em Video Cards que isso é necessário no meu caso porque estou num Vmware. Se você tiver placa de video NVIDIA teria colocado &ldquo;nvidia&rdquo; ou se fosse AMD seria &ldquo;amdgpu&rdquo; e assim por diante.</p>
<p>Além disso, o grande lance do Gentoo é baixar pacotes de código fonte e compilar, por isso nesse arquivo tem CFLAGS e CXXFLAGS, que são opções pro compilador GCC. Tem outra página no Wiki explicando essas e outras flags que eu recomendo que vocês leiam e não saiam só copiando e colando coisa aqui sem saber porque. Por exemplo, o flag &ldquo;-O2&rdquo; é o nível de otimização que o compilador vai usar. &ldquo;-O1&rdquo; é o mais básico e &ldquo;-O3&rdquo; é o máximo. Tem gente escrevendo em fórum que conseguiu um executável mais rápido usando um &ldquo;-O9&rdquo; da vida. É mentira, não existe esse nível, o máximo é 3.</p>
<p>Tem gente recomendando usar flags como &ldquo;-funroll-loops&rdquo; pra otimizar mais, e de novo, como o Wiki explica, o próprio manual do GCC fala pra não usar isso, porque você vai acabar com um binário maior e mais lento. Flags agressivas devem ser usadas só pro programadores que realmente sabe o que elas fazem, em software que foi escrito pra tirar vantagem disso. Não devem ser usadas em pacotes aleatórios e muito menos pro sistema inteiro. Se ficar usando flags aleatórias, vai acabar com binários mais pesados, mais lentos e mais instáveis e seu sistema vai ficar uma bosta. E a culpa não é o Gentoo, é você que sai copiando e colando coisa sem saber.</p>
<p>Seguindo nosso guia do Wiki, tem configurações opcionais que vou passar acelerado. É só seguir o que diz no Wiki. Mas seria configuração de locale, hostname, keymap, timezone. Nenhum detalhe importante pra agora&hellip;. E finalmente chegamos na parte importante que diferencia o Gentoo dos demais, na minha opinião, a seção de customização da Kernel agora na instalação. Na real, você pode customizar kernel em qualquer distro, mas no Gentoo isso faz parte do processo de instalação.</p>
<p>Pra isso precisamos do código-fonte. Executamos <code>emerge -av sys-kernel/gentoo-sources sys-kernel/linux-firmware</code>. Note que pacotes em Gentoo são organizados em namespaces como &ldquo;sys-kernel&rdquo;. Enfim, quando terminar, entramos no diretório de código-fonte que é o &ldquo;/usr/src/linux&rdquo; e a versão.</p>
<p>Se nunca teve a oportunidade de fuçar o código fonte da kernel do Linux, eis sua chance. Depois abra um editor de textos qualquer e perca algumas horas vasculhando o código, talvez aprenda algo. Não tenha medo de código só porque parece complicado. Justamente porque parece complicado é que deveria ser fascinante. Na prática, uma boa parte do código vai ser de drivers de dispositivos.</p>
<p>Apesar do código fonte do Linux ser um enorme monolito, tudo organizado num mesmo repositório, o binário em si é mais ou menos modular. Existem vários drivers que são compilados estaticamente no mesmo binário da kernel. Acho que o driver do sistema de arquivos ext4, por exemplo, fica dentro do binário da kernel. Porém existem drivers que não são carregados imediatamente no boot. São compilados separadamente, como objetos ou bibliotecas, e podem ser carregados depois, com comandos como modprobe.</p>
<p>Sem mais delongas, do diretório de código fonte, vai ter um Makefile, como mostrei no episódio passado, lembram? Todo programador de C sabe lidar com Makefiles e aqui não é diferente. Vai ter uma tarefa chamada <code>menuconfig</code>, que carrega com <code>make menuconfig</code>. Abre esse programa interativo em modo texto, acho que usando ncurses. É uma lista de categorias de módulos de kernel.</p>
<p>Tudo que tá desmarcado, é porque não vai ser compilado. O que estiver com &ldquo;*&rdquo; vai ser compilado e linkado estaticamente, ou seja, vai estar dentro do binariozão da kernel. E o que estiver com &ldquo;M&rdquo; vai ser compilado e mantido desativado num arquivo separado até ser carregado por comandos como <code>modprobe</code>. Você quer manter o máximo de pacotes desmarcados, se possível.</p>
<p>Por exemplo, sei lá porque, por padrão vem marcado suporte pra PCCards, padrão PCMCIA ou Cardbus. Eu nunca mais vi esse tipo de dispositivo nos últimos 20 anos. Pra quem não sabe, antes de ter conectores como Thunderbolt ou USB, uma das formas de adicionar um hardware externo num notebook dos anos 90, era com cartão PCMCIA. Eram coisas como essas. Até imagino que deva ter hardware especializado em alguma indústria que ainda precise disso, mas pra pessoas normais como eu ou vocês aí, nunca vamos precisar disso. Não faz sentido a kernel sempre carregar esse driver e ficar ocupando espaço na RAM. Posso desmarcar.</p>
<p>Na real, vamos sair e fazer outra coisa antes. Note que estamos ainda no ambiente de LiveCD do pendrive. E tá tudo funcionando bonitinho, ou seja, a detecção automática de hardware funcionou até que bem. Seja lá quais drivers foram carregados, tá fazendo nossa máquina funcionar. Então, por que não selecionar os mesmos drivers que já estão carregados? Pra isso podemos rodar o comando <code>make localyesconfig</code> pra atualizar o arquivo <code>.config</code> com esses drivers. E aí sim, voltamos pro <code>make menuconfig</code> e tiramos suporte a PCMCIA e outras coisas que sabemos que não vamos precisar.</p>
<p>Podemos sair tirando mais coisas, como suporte a hardware de Chromebooks, ou suporte a notebooks Surface da Microsoft. Normalmente o que você mais vai mexer é a categoria de Device Drivers. Nas outras opções, a menos que tenha certeza absoluta, não mexa, especialmente em categorias como Criptografia, Gerenciamento de Memória. Isso é bom pra você fuçar se estiver pesquisando sobre sistemas operacionais mais a fundo. Mas pra usuários iniciantes, o ideal é mexer bem pouco.</p>
<p>No meu caso, agora entra aquela outra página de Wiki que falei no começo, que lista alguns módulos específicos pro caso onde estou numa máquina virtual VMWare. Então eu gostaria de carregar drivers de Vmware. Por exemplo, em Device Drivers, Network device support, preciso selecionar o driver VMware VMXNET3 ethernet. Nessa página tem essa listinha sugerindo módulos pra checar e ativar. Depois que terminar, só selecionar lá embaixo a opção de &ldquo;Save&rdquo; e sair.</p>
<p>De volta à linha de comando, agora é hora de compilar a kernel. Vamos compilar com o comando <code>make -j4</code>. No tutorial ele sugere &ldquo;-j2&rdquo;. Essa opção &ldquo;j&rdquo; significa &ldquo;jobs&rdquo; ou trabalhos em paralelo, que é quantos arquivos vai compilar ao mesmo tempo. &ldquo;j2&rdquo; é o mínimo, vai usar só duas threads da sua CPU. No meu caso, eu dei 2 cores da minha CPU de verdade com 2 threads cada, então posso rodar com &ldquo;-j4&rdquo;.</p>
<p>Se estivesse nativo no meu AMD Ryzen 9 de 32 threads, eu poderia rodar com &ldquo;-j32&rdquo;. Quanto mais cores tiver pra gastar, mais rápido vai ser a compilação, porque vai tudo em paralelo. Porém, quanto mais rodar em paralelo, mais RAM precisa ter. Se for agressivo demais em jobs paralelos e tiver 4 giga ou menos de RAM, provavelmente vai crashear, então cuidado.</p>
<p>Esse arquivo vmlinuz que gera no final é o binário da kernel. Se nunca viu um Linux de verdade na sua frente, muito prazer, este é &ldquo;O&rdquo; Linux que todo mundo tanto fala mas ninguém nunca viu. E não só isso, esse é um kernel feito sob medida especialmente pra você, sem carregar muita coisa desnecessária. Numa distro normal como Ubuntu ou Manjaro, vem com uma kernel mais genérica que precisa suportar os mais diferentes tipos de hardware, então eles tentam manter mais drivers ativos do que realmente é necessário, consumindo mais RAM.</p>
<p>Esse é o custo da comodidade. Um usuário normal não quer ter que configurar sua própria kernel do zero, então se contenta em desperdiçar um pouco de RAM e um pouco até de processamento, carregando uma kernel mais gorda do que precisa, só pro caso de um dia precisar de um hardware mais exótico. Mas a filosofia do Gentoo é justamente compilar tudo do zero pra termos a oportunidade de escolher tirar tudo que sabemos que não vamos precisar.</p>
<p>Agora que temos a kernel, precisamos colocar na partição de boot junto com um bootloader. Lembram de dois episódios atrás que expliquei sobre boot? Vamos instalar o bootloader com <code>emerge --ask sys-boot/grub</code>. Uma vez instalado, como estamos num ambiente EFI, rodamos <code>grub-install --target=x86_64-efi --efi-directory=/boot/efi</code> pra instalar o bootloader na partição de boot. E instalamos a kernel com <code>grub-mkconfig -o /boot/grub/grub.cfg</code>.</p>
<p>E pronto. Pra terminar, só instalar o suporte a rede pra no próximo boot conseguir carregar wifi, rodar dhcp e tudo mais. O wiki sugere essa linha de comando grandão aqui, mas como estou numa máquina virtual, sei que não vai ter wifi, porque estou simulando uma rede cabeada na máquina virtual, por isso só rodo <code>emerge --ask sys-apps/iproute2 net-misc/dhcpcd</code>. E acabou a parte do LiveCD. Saímos com <code>exit</code> e damos um reboot de uma vez.</p>
<p>E que estranho. Cadê a opção da kernel que acabamos de bootar? O menu do Grub tá vazio. Ele entra no menu UEFI da máquina. Bom, obviamente fiz alguma coisa errada, mas por aqui podemos bootar de novo pelo LiveCD no CD-ROM virtual. Vamos voltar pro ambiente que estávamos antes. Lembra que eu falei que o LiveCD serve pra diagnosticar e resolver problemas caso o boot falhe? Vamos ver isso na prática.</p>
<p>De volta àquele KDE do LiveCD, abrimos o terminal e vamos criar os pontos de montagem das nossas partições de novo. Pra não ficar repetitivo é essa sequência igual tá no começo da página de wiki. Ir criando os diretórios, daí <code>mount</code> de coisas como proc, run, sys e finalmente o chroot de novo. E enquanto fazia isso que me toquei. Eu terminei de compilar a kernel e logo depois fui instalar o Grub, mas esqueci de instalar a kernel. Vamos voltar pro diretório &ldquo;/usr/src/linux&rdquo;. Faltou rodar <code>make modules_install</code> e <code>make install</code>. Burro.</p>
<p>Sempre que compila e instala uma nova kernel, tem que lembrar de atualizar o Grub. Só rodar <code>grub-mkconfig -o /boot/grub/grub.cfg</code>. Pronto, podemos dar exit pra sair e reboot. Esperamos alguns segundos e agora sim, temos a opção do nosso Gentoo novinho. Escolhemos ele, começa a sequência de boot do sistema init. E &hellip; caraca, que porra é essa?</p>
<p>A mensagem diz que a CPU foi desabilitada e a máquina parou de bootar. Literalmente ou a kernel deu crash ou deu uma instrução HLT de halt and catch fire. Nunca tinha visto isso em nenhuma outra instalação de Linux. Certamente fizemos alguma coisa errada na hora de compilar a kernel que agora ela não boota. Isso vai acontecer bastante nas primeiras vezes que você tentar compilar sua própria kernel e acabar desabilitando coisa que não devia.</p>
<p>E eu estou deixando esses erros aparecer no video de propósito pra vocês saberem que sim, esses erros acontecem o tempo todo. E sim, em videos como esse todo youtuber corta fora as partes de erro. Por isso parece que no video tudo é perfeito e só você que deve ser ruim porque no seu dá erro. Mas pra todo mundo dá erro, a gente corta senão o video ia ficar muito cansativo.</p>
<p>Temos que resetar à força de novo, escolher o menu da UEFI no Grub pra poder escolher bootar pelo LiveCD. E lá vamos nós outra fez, cair no KDE do LiveCD, abrir o terminal, refazer os pontos de montagem e dar chroot &hellip;  Alguma coisa eu fiz errado quando desmarquei coisas do kernel. Vamos abrir o menuconfig outra vez &hellip; (5 min later &hellip;)</p>
<p>Se olharmos a página de Wiki sobre Vmware, fala que preciso checar se estes módulos aqui estão selecionados, e eu vi que estão. Muito estranho. Selecionei de volta tudo que lembro que tinha tirado. Vamos compilar de novo com <code>make -j4</code> &hellip;. (5 min later), pronto, agora é fazer outra vez <code>make modules_install</code> e <code>make install</code> e <code>grub-mkconfig</code>.</p>
<p>Pra garantir, acho que não faz diferença pra agora, mas vamos aproveitar pra instalar o pacote <code>open-vm-tools</code>, que é a versão open source do antigo pacote proprietário <code>vmware-tools</code>, as ferramentas da Vmware pra Guests. Ele configura coisas como resolução da tela, rede, clipboard compartilhado com o host, sincronia da hora com o host. Talvez tenha algum driver que falta. Pra instalar é só fazer <code>emerge --ask app-emulation/open-vm-tools</code>.</p>
<p>Se fosse systemd como num Ubuntu, precisaria fazer <code>systemctl start vmware-tools</code> mas como escolhi o stage3 com OpenRC precisamos fazer <code>rc-service vmware-tools start</code> e olha só, dinamicamente carregou o driver de video da Vmware e ajustou a resolução da máquina. Bom sinal. Pra garantir que vai carregar no próximo boot, só fazer <code>rc-service add vmware-tools</code>. Mas tá vendo, systemd ou openrc, pro usuário final, é mais diferença de sintaxe entre os comandos systemctl e o rc-service.</p>
<p>Podemos sair, rebootar e &hellip; Caraca, mesma coisa. Crash. Vamos bootar outra vez pelo LiveCD .. (5 min later) .. pronto. Tudo que a gente modifica naquela tela interativa do menuconfig no final é gravado no arquivo <code>.config</code>. Deixa eu abrir direto ele. Comparando com a Wiki, ele fala NET_VENDOR_AMD, vamos procurar e sim, tá yes. AMD8111_ETH, tá yes também. Vamos checar um a um (5 min later), FUSION &hellip; ué, tá comentado. Mas eu juro que no menuconfig o Fusion MPT que é driver de Scsi Host, tava habilitado. Estranho, vamos descomentar e dar yes.</p>
<p>Gravamos e damos <code>make -j4</code> de novo. E olha só, ele vai me dando opção de configurar outras opções novas, como Fusion SPI, que também precisa estar habilitado. Vamos lá então. Vai continuar a compilação como antes. No final, repetimos a mesma sequência, <code>module_install</code>, <code>install</code>, <code>grub-mkconfig</code> &hellip; saímos com exit, e reboot com dedos cruzados.</p>
<p>Máquina rebootando &hellip; e caraca, agora passou!! Como eu mexi mais coisas além do Fusion SPI, não sei se foi isso que resolveu ou não, mas pqp. Fiquem espertos, talvez vocês rodem num Vmware também e não tenham problema nenhum, talvez tenham problemas diferentes, mas enfim, vai ter problemas desse tipo e vai ter que ficar indo e voltando como eu fiz. Agora sim, termina o boot e chega até a o prompt de login em modo texto, ou seja, runlevel 3 de multi-user. Vamos instalar uma interface gráfica pra gente.</p>
<p>Entramos com <code>sudo su</code> pra continuar como root. Gentoo tem conceito de profiles, sets e coisas assim que ainda não sei muito bem os detalhes. Mas segundo o Wiki, preciso me certificar que estou no profile de desktop gnome com openrc. Pra isso posso ver os profiles disponíveis com <code>eselect profile list</code>. Seleciono o certo com <code>eselect  profile set default/linux/amd64/17.1/desktop/gnome/systemd</code>. Pronto.</p>
<p>Antes de continuar, vamos mexer na configuração do Portage em &ldquo;/etc/portage/make.conf&rdquo;. Tinha faltado INPUT_DEVICES. Colocamos libinput e synaptics que é pra touch pads. E no final configuramos o parâmetro USE pra ignorar qt5 e kde e prioriza X, gtk e gnome. E é isso. Pra instalar o gnome é só fazer <code>emerge --ask gnome-base/gnome</code>.</p>
<p>Mas, já temos um erro. No caso um erro de dependência circular. Vira e mexe vai esbarrar nisso em Gentoo e não tem uma resposta automática. Nesse caso tem dois sistemas de áudio concorrentes e ele não sabe qual instalar. Mas como falei antes, leia a porra do erro. Já diz que é ou pra escolher &ldquo;minimal&rdquo; ou &ldquo;pulseaudio&rdquo;. Pra corrigir basta mudar o comando pra <code>USE=&quot;minimal&quot; emerge --ask gnome-base/gnome</code>.</p>
<p>Só que deu erro de novo. Leia com atenção, é um erro diferente. Agora fala que não consegue instalar o pacote <code>x11-base/xorg-server</code>. Gnome, Kde, Xfce e qualquer gerenciador de janelas roda em cima do servidor gráfico X11, ou em distros mais novas, em cima do Wayland. Então precisa instalar o X11, só que o erro diz que ele não consegue instalar com essa flag &ldquo;minimal&rdquo; que acabamos de colocar. Uma das formas de resolver é instalar o xorg-server sozinho com <code>emerge --ask x11-base/xorg-server</code>. Não sei se é a melhor forma mas, é isso, tá instalando. Temos que esperar alguns minutos porque o X11 é bem grandinho e compilar leva tempo &hellip; (5 min later)</p>
<p>Com o xorg instalado, podemos tentar instalar o gnome de novo com o mesmo comando de antes e agora passa! Baixa o código fonte, começa a compilar e pode ir almoçar, vai na academia, vai ler um livro. Sério. Um gerenciador de janelas, Gnome, Kde ou qualquer um é composto por dezenas de pacotes, milhões de linhas de código, e o Gentoo vai compilar tudo do zero.</p>
<p>Eu configurei esta máquina virtual com 2 cores e 2 threads e 8 giga de RAM, uma configuração bem fraquinha. Se estivesse nativamente no meu Ryzen 9 de 32 threads com 64 giga de RAM, ia acabar em poucos minutos, mas numa máquina fraca dessas, vai levar mais de 2 horas fácil. Nem tô brincando &hellip; Até logo, a gente se vê mais tarde</p>
<p>(1 year later &hellip;)</p>
<p>Ufa, parece que agora terminou. Caraca, sério, é muito tempo. Nem tô brincando. Vamos no wiki ver o que falta fazer. Ele manda atualizar as variáveis de ambiente com <code>env-update &amp;&amp; source /etc/profile</code>. Daí manda colocar nosso usuário no grupo plugdev com <code>getent group plugdev</code> primeiro pra checar, e sim, tá lá. Então <code>gpasswd -a akitaonrails plugdev</code>.</p>
<p>Finalmente, precisamos habilitar o DM, no caso o GDM. E o GDM precisa do elogind no boot. Opa, falei grego, eu sei. Que diabos é DM? É acrônimo pra Display Manager ou, mais corretamente, Login Manager ou gerenciador de Login. É aquela primeira tela gráfica que pede seu login e senha depois do boot. É ele que se encarrega de carregar o GNOME propriamente dito. Por padrão o X carrega o XDM, então precisamos trocar pro GDM porque o XDM não consegue carregar Gnome.</p>
<p>Pra isso primeiro precisamos configurar o serviço elogind pra carregar antes no boot com <code>rc-update add elogind boot</code>. Agora precisamos instalar o serviço que inicia o display manager com <code>emerge --ask --noreplace gui-libs/display-manager-init</code> e editamos o arquivo <code>/etc/conf.d/display-manager</code> com vim. Tá vendo? Lá embaixo o padrão é &ldquo;xdm&rdquo; então trocamos pra &ldquo;gdm&rdquo; e salvamos.</p>
<p>Por fim, configuramos o serviço pra iniciar automático, colocando no runlevel padrão com <code>rc-update add display-manager default</code>. Teoricamente é só isso, só rebootar agora &hellip; e &hellip; falhou, por alguma razão ainda tá tentando carregar o XDM, que não existe, e sai fora. E lá vamos de novo investigar. (5 min later) Fiquei fuçando aqui e checando se aquele arquivo de configuração tá com &ldquo;gdm&rdquo; mesmo, o serviço elogind também carregou normalmente, tá difícil.</p>
<p>Mas achei estranho que também não encontrei o gdm. Uma hipótese é que inicializador tenta carregar o GDM, não acha, e como alternativa tenta carregar o XDM, que também não tá instalado. Imaginei que o pacote &ldquo;gnome-base/gnome&rdquo; já automaticamente instalava, mas pelo jeito não, ou deu algum erro que eu passei batido e não vi, então vamos instalar com <code>emerge --ask gnome-base/gdm</code>. De novo, hora de mais um café, porque esse também demora pra compilar &hellip; (1 year later)</p>
<p>(levanta .. CONTINUA &hellip; volta &hellip;)</p>
<p>Dessa vez estou cortando fora as várias horas que eu levei apanhando do GDM. Na real, da dependência do GDM e do GNOME que é o webkit-gtk. Puta pacote bosta. Ele ficava dando erro, eu tentava de novo e nada. Rechequei configuração, flags de compilação e gastei um tempo lendo fóruns que achei no Google, até num deles tive um insight. Lembra que falei que se tentar compilar muito agressivo, numa máquina fraca, pode faltar RAM? Acho que foi isso, o compilador crasheava por falta de memória, dava erro e parava. Só que o compilador não diz que faltou memória, ele fala que deu erro numa linha de um script que voltou false.</p>
<p>Mas sim, voltou false porque deu crash. Aumentei pra 16 giga e vamos compilar de novo. Nos vemos em duas horas &hellip; (2 hours later) …</p>
<p>Será que agora vai? Opa, sem erro na deteção do GDM e &hellip; e &hellip; ha! Carregou o GDM!! Vamos logar &hellip; opa, senha errada &hellip; de novo. Pronto! Caraca, um dia inteiro pra no fim descobrir que era falta de memória. Vai se fuder. E olha só, isso é um GNOME zerado, sem nenhuma opção extra, sem nenhum aplicativo pré-instalado. Agora eu posso instalar exatamente só os programas gráficos que eu quiser, e não ter que ficar com aquele monte de lixo que toda distro já pré-instala pra mim. Eu não preciso de cliente de email, não preciso de gerenciador de foto. Nesse sentido, eu gosto disso de poder instalar minhas próprias coisas.</p>
<p>A moral da história é: não tente instalar um gerenciador de janela pesado como GNOME numa máquina fraca com menos de 8 giga de RAM. Provavelmente tinha flags de GCC que eu podia ficar mexendo, mas na prática só ia deixar a compilação ainda mais lenta. E sério, puta componente lento de compilar. Toda vez que tentava de novo era fácil mais de 1 hora até terminar em crash. Configurar um Gentoo não é pros fracos. E se você tem máquina fraca, escolha um gerenciador de janela mais leve, como XFCE. Apesar que a culpa nem foi do GNOME, foi do webkit. De curiosidade, vocês sabem o que é Webkit?</p>
<p>Webkit é o framework de navegadores, a engine de HTML, CSS que roda por trás do Safari de Mac e que inicialmente estava nos Chrome. Acho que o Chrome é meio que um fork ou rewrite de Webkit e evolui separado. Mas o Webkit não é o navegador, ele é usado dentro de navegadores como o Konqueror, e todo aplicativo desktop que exibe HTML, como cliente de email. Justamente por isso é provavelmente o componente mais pesado que você vai instalar na sua máquina. Sério, olha o tanto de hora que leva pra compilar essa porra. Uma engine de web não é um troço pequeno, porque a web hoje é desnecessariamente complicada. Valeu Apple e Google, por tornar a web pior.</p>
<p>Aliás, falei que não veio nenhum aplicativo instalado aqui. Inclusive não tem nem loja de aplicativos e nem terminal. Como que eu instalado um terminal sem ter o terminal? Lembrem dos meus videos anteriores, vocês tem 5 segundos pra adivinhar. 4, 3, 2, 1 &hellip; vamos mudar pro runlevel 3. Ctrl + Alt + F3. Pronto, de volta pro console em modo texto. Agora daqui eu posso instalar qualquer aplicativo de terminal que eu quiser, como o Alacritty, que é meu preferido. E quando terminar, volto pro modo gráfico com Ctrl + Alt + F5.</p>
<p>Enfim, finalmente, temos GNOME bootando bonitinho neste Gentoo quentinho saído do forno, configurado com OpenRC em vez de systemd pra gente ter um ambiente pra estudar melhor OpenRC e se é melhor mesmo do que o Systemd. Falando nisso, tem essa outra página no Wiki que fala de GNOME sem Systemd. Lá explica que antes dava pra carregar GNOME sem problemas tanto com systemd quanto openrc. Mas isso mudou.</p>
<p>Como expliquei no episódio anterior, o systemd faz mais do que só gerenciar resolução de dependências e start de serviços. Agora gerencia também coisas como economia de energia e outras atividades do sistema, inclusive gerenciar o diretório /dev de dispositivos, lembra dele? Por causa disso surgiram dois projetos que extraem essas coisas do systemd, projetos como elogind que instalamos antes e eudev. Assim é possível usar só essas partes do systemd e substituir por OpenRC e conseguir subir o Gnome.</p>
<p>Essa é outra das críticas do systemd: que ele faz muito mais do que deveria. Um sistema de init deveria só gerenciar inicialização. Software pra controlar &ldquo;/dev&rdquo; deveria ser separado, em outro pacote, de tal forma que desse pra instalar um, sem instalar o outro. Mas o systemd é um código-fonte monolito, ou compila tudo junto, ou nada funciona.</p>
<p>Pra extrair projetos como elogind e eudev, dá um puta trampo, porque toda vez que o systemd atualiza e muda as coisas, esses outros projetos precisam extrair de novo o que mudou pra nada quebrar. É realmente uma grande perda de tempo e consigo entender porque muitos desenvolvedores de Linux estão putos com isso.</p>
<p>De qualquer forma, pra gente que contribui no desenvolvimento de distros, é bom saber que essa discussão existe e se tiver interesse depois procura fóruns de desenvolvimento pra ver como as coisas estão evoluindo. Eu pessoalmente não tenho muito interesse porque não contribuo com software livre, mas quem contribui precisa entender essa novela. No mínimo é um bom estudo pra saber como a comunidade lida com conflitos assim.</p>
<p>Sobre o Gentoo em si. É um excelente exercício se desafiar em controlar essa besta selvagem. É o extremo oposto de instalar um Ubuntu da vida. Você realmente vai perder muitas horas, muitos dias, em tentativas e erros, lendo muita documentação no Wiki deles, e no mínimo serão horas de muito estudo e aprendizado que uma hora vai ser útil em outras distros de Linux. Todo mundo que tem alguma vontade de brincar no mundo de devops, esse é o hello world do hello world. Se não consegue nem se virar com a instalação de um Gentoo, que tem documentação bem organizada, imagina clusters de servidores mais avançados ou sistemas embarcados mais restritos.</p>
<p>Porém, sobre a filosofia de sempre compilar tudo do zero, acho que é uma faca de dois gumes. Pensando exclusivamente no meu caso. Eu tenho uma máquina parruda, um Ryzen 9 com 64 giga de RAM e todo o espaço em disco que eu precisar no meu NAS de 10 gigabits, com velocidade superior a SSDs. Pra fazer os últimos episódios instalei dúzias de máquinas virtuais de teste. No final, o Gentoo é o que realmente dá sensação de mais responsivo, um pouco mais rápido, e isso provavelmente se deve a ter compilado tudo exclusivamente pra minha máquina, eliminando muita gordura no processo.</p>
<p>Mas como falei antes, instalar X11, Gnome, GDM, na verdade o pacote webkit, custou literalmente umas 3 horas, a CADA tentativa, e até eu descobrir o problema, foram VÁRIAS tentativas. Foi quase um dia inteiro repetindo esse processo até resolver o erro. Enquanto ficava esperando, escrevi quase o script inteiro desse episódio, com tempo sobrando pra revisão. Não tô brincando, é muito tempo. Tudo bem que foi numa máquina virtual. Se fosse no meu hardware nativo, num dual boot, teria sido ordens de grandeza mais rápido. Mas é justamente esse o ponto.</p>
<p>Quem tem hardware parrudo como o meu, não se importa tanto se tá ganhando 1 milissegundo a mais de performance por ter compilado tudo nativo. Os milissegundos que vou ganhar, não compensam a espera em compilar tudo do zero toda hora. Minha máquina já é rápida o suficiente. Mesmo se o binário for mau feito e pesado, vai rodar de boas. Quem realmente precisa da otimização é quem tem máquinas mais lentas ou antigas. Só que agora a compilação também vai ser ordens de grandeza mais lento, nessa faixa de levar mais de 3 horas pra conseguir instalar um simples GNOME.</p>
<p>Ou seja, quem mais precisa da performance extra, vai toda hora perder muita produtividade quando precisar instalar pacotes, porque todo novo software, precisa baixar o código fonte e esperar compilar tudo. Nem sempre é demorado assim, a maioria dos softwares são pequenos. Mas imagina agora quero instalar Firefox, lá se vai mais uma ou duas horas. Agora preciso instalar Ruby, ou Python, mais 1 hora. Você tem que ser disciplinado de não tentar instalar nada grande no meio do expediente, senão acabou o dia pra você. Sério. É meio duvidoso até onde tem vantagem.</p>
<p>O benefício de um Gentoo vem quando você tem uma máquina fraca que não vai ficar usando no dia a dia. Por exemplo, um PC fraco que quer usar como servidor multimídia, ou um roteador de rede, ou um NAS. Uma máquina com um único propósito, idealmente sem nem precisar de interface gráfica, que é a compilação mais pesada. Por isso falei em aplicações de sistemas embarcados, ou IoT. Aí sim, você precisa economizar o máximo de recursos, e quando terminar de instalar, não vai ficar adicionando mais nada. Um Gentoo é perfeito pra isso.</p>
<p>Outro objetivo dos exercícios dos últimos videos é mostrar o seguinte: qual é a melhor distro? Não existe essa resposta. Todas são boas, e em todas roda praticamente todos os mesmos software, é tudo software livre. Em alguns dá mais trabalho ou menos trabalho instalar esse ou aquele software, mas na prática dá no mesmo. Se tiver um dispositivo periférico muito exótico, no final vai ter que compilar kernel na mão de qualquer jeito, e em qualquer distro pode fazer isso. Não é só em Gentoo que pode customizar kernel. No Ubuntu também dá. Só baixar o código fonte, subir o menuconfig, compilar e mandar o grub configurar no boot.</p>
<p>Pra quem é iniciante, povo recomenda instalar Ubuntu ou PopOS da vida porque são triviais, por causa do Calamares, e por serem populares, tem documentação de tudo na internet. Tem fóruns de discussão ativos. Tem salas de chat com gente discutindo a respeito. Vai ser mais fácil de achar solução pra qualquer problema neles. Por outro lado, se usar um distro dessas, não vai aprender nada sobre Linux. Clicar com mouse e arrastar janela não te ensina absolutamente nada. Esquece colocar no currículo &ldquo;Sei Linux&rdquo; só porque instalou um Ubuntu. Sabe bosta nenhuma. Só sabe abrir o Chrome e navegar. Isso você faz em Windows ou Mac igual.</p>
<p>Saber Linux é no mínimo estar confortável com tudo que eu fiz nos últimos videos. Saber o que é chroot, o que são pontos de montagem, o que é escalonamento de privilégios, como se customiza a kernel, como configura um bootloader, como diagnostica dependências de binários, como monta um pacote. Olha só tudo que a gente viu até agora. Isso minimamente &ldquo;saber Linux&rdquo;, e o que mostrei até agora, foi só o hello world, os conceitos básicos. Começa a ler a Wiki do Gentoo ou Arch. Aí você vai ver o quanto ainda falta pra realmente &ldquo;saber Linux&rdquo;.</p>
<p>Por isso, sim, tente instalar Slackware, tente instalar Gentoo, tente instalar Arch. Esse é o exercício que todo aprendiz de Linux precisa passar. O fim de semana inteiro varando noite de sábado pra domingo, saindo de uma mensagem de erro pra outra mensagem de erro, até ter a satisfação de ver tudo bootando e funcionando no final. Aí sim você sabe que aprendeu alguma coisa de verdade.</p>
<p>Aliás, eu até entendo porque no final tem um grupo de pessoas que defente um Gentoo com unhas e dentes, porque depois de tantas horas e dias dedicado em fazer tudo funcionar na sua máquina, horas e horas esperando tudo compilar e tendo que repetir tudo de novo quando dá erro. Dá muita dó jogar fora e mudar de distro. É meio que síndrome de Estocolmo, já sofreu tanto, agora fica com ele. Mas eu sou um psicopata altamente funcional. Gastei dias configurando tudo, no final jogo tudo fora e pulo pra outra coisa. Quem consegue desapegar de coisas que investiu horas em cima, sempre vai ter mais vantagem, pense nisso.</p>
<p>E o assunto ainda não chegou ao fim, o próximo video vai ser mais conceitos de Linux que você não sabe. Então, se ficaram com dúvidas mandem nos comentários abaixo, se curtiram o video deixem um joinha, assinem o canal e compartilhem o video com seus amigos. A gente se vê, até mais!</p>
]]></content:encoded><category>linux</category><category>reviews</category><category>akitando</category></item><item><title>[Akitando #79] Teclados Mecânicos Exóticos | Minha coleção - Parte 2</title><link>https://akitaonrails.github.io/2020/05/12/akitando-79-teclados-mecanicos-exoticos-minha-colecao-parte-2/</link><guid isPermaLink="true">https://akitaonrails.github.io/2020/05/12/akitando-79-teclados-mecanicos-exoticos-minha-colecao-parte-2/</guid><pubDate>Tue, 12 May 2020 17:55:00 -0300</pubDate><description>&lt;div class="embed-container"&gt;
&lt;iframe
src="https://www.youtube.com/embed/57axLgXkS_M"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h2&gt;DESCRICÃO&lt;span class="hx:absolute hx:-mt-20" id="descricão"&gt;&lt;/span&gt;
&lt;a href="#descric%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Continuando sobre minha coleção de teclados mecânicos, agora quero mostrar alguns dos meus ítens mais exóticos. Mais do que isso vou falar sobre ergonomia e ainda quero aproveitar o gancho pra contar uma história sobre UNIX e Linux que muitos nem sabem ainda!&lt;/p&gt;
&lt;p&gt;Mas pra quem estava esperando por isso também vou mostrar o que eu elegi como melhor custo-benefício. Assistam até o final!&lt;/p&gt;</description><content:encoded><![CDATA[

<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/57axLgXkS_M"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<h2>DESCRICÃO<span class="hx:absolute hx:-mt-20" id="descricão"></span>
    <a href="#descric%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Continuando sobre minha coleção de teclados mecânicos, agora quero mostrar alguns dos meus ítens mais exóticos. Mais do que isso vou falar sobre ergonomia e ainda quero aproveitar o gancho pra contar uma história sobre UNIX e Linux que muitos nem sabem ainda!</p>
<p>Mas pra quem estava esperando por isso também vou mostrar o que eu elegi como melhor custo-benefício. Assistam até o final!</p>
<p>De novo, como o video tem muitos itens diferentes, vou deixar um bookmark das seções pra ficar fácil voltar depois:</p>
<ul>
<li>01:34 - Keychron K2</li>
<li>04:52 - Drop Ctrl</li>
<li>08:18 - Um pouco sobre Ergonomia</li>
<li>15:31 - Ultimate Hacking Keyboard</li>
<li>20:33 - QwerkyWriter S</li>
<li>23:42 - SURPRESA 1 (sem spoilers aqui)</li>
<li>26:46 - Um pouco de história</li>
<li>33:53 - Um pouco de UNIX</li>
<li>39:34 - SURPRESA 2</li>
</ul>
<p>Links:</p>
<ul>
<li>QWERKYWRITER® S (<a href="https://www.qwerkywriter.com/collections/frontpage/products/qwerkywriter-s-typewriter-inspired-mechanical-keyboard"target="_blank" rel="noopener">https://www.qwerkywriter.com/collections/frontpage/products/qwerkywriter-s-typewriter-inspired-mechanical-keyboard</a>)</li>
<li>Keychron K2 Wireless Mechanical Keyboard (<a href="https://www.keychron.com/products/keychron-k2-wireless-mechanical-keyboard?variant=31063869620313"target="_blank" rel="noopener">https://www.keychron.com/products/keychron-k2-wireless-mechanical-keyboard?variant=31063869620313</a>)</li>
<li>MASSDROP CTRL MECHANICAL KEYBOARD (<a href="https://drop.com/buy/68551"target="_blank" rel="noopener">https://drop.com/buy/68551</a>)</li>
<li>Dave Lee - I found the perfect keyboard (<a href="https://www.youtube.com/watch?v=ADEh9F0Lidc"target="_blank" rel="noopener">https://www.youtube.com/watch?v=ADEh9F0Lidc</a>)</li>
<li>Best ergonomic keyboard 2020 (<a href="https://www.t3.com/features/best-ergonomic-keyboard"target="_blank" rel="noopener">https://www.t3.com/features/best-ergonomic-keyboard</a>)</li>
<li>Ultimate Hacking Keyboard (<a href="https://ultimatehackingkeyboard.com/"target="_blank" rel="noopener">https://ultimatehackingkeyboard.com/</a>)</li>
<li>Unicomp Model M (<a href="https://www.amazon.com/Unicomp-Classic-Buckling-Spring-Keyboard/dp/B01MSNM6YG?ref_=fsclp_pl_dp_1"target="_blank" rel="noopener">https://www.amazon.com/Unicomp-Classic-Buckling-Spring-Keyboard/dp/B01MSNM6YG?ref_=fsclp_pl_dp_1</a>)</li>
</ul>
<p>Pra Aprender a digitar certo:</p>
<ul>
<li>Type Club (<a href="https://www.typingclub.com/"target="_blank" rel="noopener">https://www.typingclub.com/</a>)</li>
<li>KeyBR (<a href="https://www.keybr.com/"target="_blank" rel="noopener">https://www.keybr.com/</a>)</li>
<li>Game: ZType (<a href="https://zty.pe/"target="_blank" rel="noopener">https://zty.pe/</a>)</li>
</ul>
<h2>SCRIPT<span class="hx:absolute hx:-mt-20" id="script"></span>
    <a href="#script" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Olá pessoal, Fabio Akita</p>
<p>No episódio anterior eu comecei explicando o que é essa história de teclados mecânicos e mostrei metade da minha coleção pessoal. Não precisa ter assistido a parte 1 pra entender o video de hoje mas seria bacana se visse depois pelo menos. Hoje eu vou terminar o assunto com os exemplos mais interessantes de teclados e na segunda metade vou usar de gancho pra ensinar algumas coisas básicas de programação que eu sei que até mesmo alguns programadores que se dizem com experiência desconhecem.</p>
<p>(&hellip;)</p>
<p>No episódio anterior eu falei mais de teclados de notebooks, modelos de marcas comerciais reconhecidas como Corsair, Cooler Master, Razer e Logitech. Daí mostrei dois exemplos de marcas mais de nicho como Matias e RealForce. Essa categoria tem marcas mais de nicho, normalmente voltada pra entusiastas mesmo. E de novo repito a recomendação que fiz no video anterior de visitar canais que falam sobre esse tipo de teclado em mais detalhes como o canal do Random FrankP ou Tae Keyboards.</p>
<p>Duas marcas que eu ainda não tenho são a Anne e Ducky, tanto o Anne Pro 2 ou o Ducky One 2 Mini tem recebido excelentes reviews mas eles não são baratos, na faixa dos 100 dólares que é parecido com a faixa da Corsair ou Cooler Master. Porém você necessariamente vai precisar importar, diferente de uma Corsair que você acha um pouco mais fácil no Brasil.</p>
<p>Na categoria abaixo de 100 dólares eu acho bem mais difícil achar teclados bem construídos, mas existem, e um excelente exemplo é a Keychron. Eu mencionei o modelo K1 low profile que compete com o Cooler Master SK630. Mas eu atual favorito em termos de custo-benefício é o modelo K2.</p>
<p>O K2 da Keychron que eu tenho é um 75%, mas o layout dele é muito melhor que o do Matias que eu mostrei no video anterior porque ele tem teclas individuais pra page up, page down, home e end numa linha vertical, além das teclas de setas que estão bem posicionadas. Além disso os keycaps são PBT doubleshot de excelente qualidade. O chassi também é todo de metal e tem zero problema de torção ou afundar no meio. A construção inteira é uma das mais sólidas e rígidas. A única pequena reclamação é que ele é um pouco mais alto que todos os outros que mostrei até agora, incluindo o Matias e o RealForce que já são um pouco mais altos que o normal.</p>
<p>Por isso se você comprar eu recomendo que adicione um palm rest pra apoiar os pulsos. Eu comprei o de madeira da própria Keychron mas qualquer outro serve. Os da Razer são bem confortáveis por exemplo. Vale lembrar que o jeito certo de digitar é sempre com as mãos flutuando um pouco acima do teclado. De preferência evitar que o pulso fique apoiado na mesa pra evitar dores.</p>
<p>De qualquer forma, o custo benefício desse teclado é excepcional. A versão mais básica e que tem até backlight branco custa 70 dólares e lógico, isso sem contar frete. Além disso é importado e todo eletrônico que vem de fora sempre vai estar sujeito a cair em tributação, e todos sabemos que a porcaria das taxas aqui vão de 60% até 100% de imposto, o que é uma estupidez.</p>
<p>A versão que eu tenho custou 90 dólares porque tem backlight RGB com o frame de aluminío, então não sei dizer se a versão que não é de alumínio é tão sólida quando esta, mas vamos ouvir um pouco pra vocês terem uma noção, e comparar com o Corsair de 100 dólares que é o mais próximo em preço.</p>
<p>(keychron comparado corsair)</p>
<p>Não sei se conseguem notar a diferença da qualidade de som de um e de outro. É subjetivo, mas eu realmente prefiro bem mais o som mais sólido e assertivo do Keychron do que o som mais barato do Corsair. Os switches são Gateron Red. A Gateron é uma que faz clones de Cherry. Em termos de especificação é praticamente um Cherry MX Red então é um switch linear. Diferente de switches proprietários como da Razer e Logitech significa que você pode encaixar keycaps compatíveis com Cherry nesse teclado, como aqueles da Corsair que eu mostrei mais no começo.</p>
<p>Outra coisa é que este Keychron é um dos únicos teclados wireless que eu tenho. Dizem que ele tem uma das maiores baterias de todos, de 4000 miliamperes, o que justifica ele ser tão mais alto que os outros. Eu mesmo não uso em modo wireless porque ele fica na minha mesa em casa e eu ligo num desktop então pra mim realmente tanto faz ser wireless. Mas pra quem carrega entre casa e escritório ou viaja bastante, esse é sem dúvida um dos mais portáteis sem comprometer usabilidade.</p>
<p>Falando em switches compatíveis com Cherry, outro exemplo é a empresa Kaihua que faz os switches Kailh e eu queria testar o Kailh Silver linear deles que é parecido com o Cherry Speed Silver, por isso algum tempo atrás eu comprei o Massdrop Ctrl depois que vi no canal do Dave Lee, vale conferir o video dele.</p>
<p>Em termos de estética este é sem dúvida o teclado que eu acho mais bonito. Vocês vão notar que o frame inteiro dele é de alumínio, com uma camada no meio de leds RGB. E como os switches ficam expostos o led reflete no alumínio. Aliás, a Massdrop é uma das poucas marcas que produzem teclados de alta qualidade e onde você consegue trocar os switches sem precisar desmontar nem soldar nada. Como eu disse, eu escolhi o meu com switches Kail Silver e, de fato, em termos de velocidade ele se compara com o Razer Yellow ou o Romer G linear que mostrei antes. Vale a pena ouvir um pouco ele comparado com o Blackwidow por exemplo.</p>
<p>(comparação ctrl - blackwidow yellow)</p>
<p>Como eu já expliquei o barulho total não vem só do switch, depende muito da qualidade do keycap, da construção do chassi, se o switch fica exposto ou não. É muito difícil determinar como vai ser o barulho final sem testar um do lado do outro mas esse é um dos menos barulhentos que eu tenho, menos ainda que o Keychron, mais próximo do Blackwidow.</p>
<p>Mas diferente do Blackwidow, apesar de teoricamente a força de acionamento ser os mesmos 45 gramas, não sei se os keycaps são mais densos, mas me dá impressão desse Drop Ctrl ser um pouquinho mais pesado pra acionar. Ou seja, apesar dos switches terem praticamente as mesmas especificações de força de acionamento e key travel, a diferença na construção muda bastante a sensação quando digita. Minha tese é a textura dos keycaps da Massdrop serem um pouco mais ásperas, o que dá sensação que &ldquo;segura&rdquo; mais o dedo na hora de digitar se comparado com os da Razer que são um pouco mais lisas.</p>
<p>Por outro lado, assim como os switches da Gateron, os da Kaihua também são clones de Cherry e por isso eu poderia trocar os keycaps por qualquer outro kit que seja compatível com Cherry, o que pode ser interessante se eu quiser mudar a aparência no futuro. Porém, é difícil recomendar este teclado porque o preço de saída dele é 200 dólares, sem contar frete nem imposto. É um dos teclados mais caros que eu tenho e muito disso é a escolha de materiais e engenharia que de fato são excelentes. É basicamente um bloco gigante de alumínio, tipo um macbook.</p>
<p>Se tem uma coisa que me incomodou é que ele não tem pernas atrás como os outros pra controlar a altura. Em vez disso ele veio com duas peças magnéticas que grudam atrás. Só que como é magnético não é difícil perder essas peças e adivinhem, eu perdi transportando e nunca mais achei. Na prática, você paga um premium por ser bonitão, mas por preço realmente não compensa porque por 50 dólares a menos que isso você compra um Blackwidow Chroma V2 que tem basicamente a mesma performance e solidez. 200 dólares é um valor compatível com os materiais desse teclado, o custo benefício não compensa a menos que você seja um entusiasta como eu.</p>
<p>Antes de continuar, vale e pena uma tangente pra falar sobre teclados ergonômicos e talvez um mínimo de ergonomia. Pra variar, valem os famosos disclaimers: eu não sou especialista em ergonomia mas falando de anos e anos digitando nos mais variados ambientes, o maior problema que eu sempre encontrei não foram tanto teclados e sim uma combinação de cadeira e mesa que permita que eu sente ereto, com os pés encostados no chão e que eu consiga ficar com os braços verticais pra baixo e os antebraços em 90 graus, sem forçar os ombros pra cima que é o que normalmente resulta em parte das dores no pescoço.</p>
<p>Eu tenho 1 e 72 de altura, meu peso médio é 76 a 77kg. Pra mim uma mesa comum de escritório que costuma ter 75 centimetros é alto demais. Pra ficar na posição correta eu sou obrigado a usar uma cadeira que levanta, mas aí meus pés não alcançam direito o chão, e depois de meses usando um apoio vou dizer que isso incomoda. Monitor eu coloco alguma coisa embaixo pra que eu consiga olhar reto pra frente sem inclinar a cabeça nem pra baixo demais nem pra cima demais.</p>
<p>Por isso aqui pra minha casa eu comprei esta mesa Genius Desk, que fabrica e entrega no Brasil aliás. Uma das funcionalidades é que eu posso trabalhar de pé também pra não ficar sentado o dia inteiro. Daí eu subo a mesa pra ficar com 1 metro de 4 centímetros e fica perfeito pra eu trabalhar de pé na postura certa das costas e dos braços. Só que ela é hiper cara e se o objetivo for só trabalhar de pé eu recomendo procurar por suportes articulados pra notebook que você facilmente encontra no mercado livre na faixa dos 200 reais.</p>
<p>Mas mais importante que isso é que essa mesa também ajusta até o mínimo de 66 centímetros que é a altura ideal pra eu sentar numa cadeira com os pés alcançando firmes no chão e manter minha postura correta como eu expliquei antes. A recomendação pra quem está sentindo problemas como tendinite, dor nas costas, nos ombros ou qualquer coisa assim não é trocar teclado, primeiro é ajustar altura da cadeira e mesa pra ficar na postura correta, depois procurar teclados especiais.</p>
<p>Com tudo isso ajustado o outro problema que causa dor é digitar errado. Se você for do tipo que a gente falava antigamente que cata milho pra digitar, ou seja, que não consegue digitar com todos os dedos das mãos, significa que seu braço precisa se movimentar muito mais por todo o teclado pra alcançar as teclas só com o dedo indicador e dedo médio. Antes de botar a culpa no teclado eu recomendo pegar aulas online e se exercitar digitando dúzias e dúzias de textos usando os dedos nas posições corretas. Eu mesmo não vou dizer que digito perfeitamente, o meu dedo mindinho e anelar da direita até hoje eu uso mal.</p>
<p>Outra coisa é que digitar em português é sempre mais devagar que digitar em inglês porque temos que ficar buscando acentos o tempo todo. Eu me acostumei a usar o formato americano US international. Eu detesto o formato ABNT2 não só por que tem a tecla de cedilha onde eu normalmente encontro o ponto e virgula mas porque diversas outras teclas mudam de lugar, em particular isso incomoda pra programar porque colchetes, sinais de maior e menor, backtick, barra invertida, tudo muda de lugar. Aqui meio que independente qual você vai escolher contanto que fique só com um layout.</p>
<p>Ficar mudando derruba a produtividade. Tudo que é importado vai ser formado americano, e se comprar fabricados no Brasil vai acabar sendo ABNT2. E falando em layout eu já disse no video anterior que tentar aprender Dvorak ou Colemak com objetivo de ser mais veloz eu acho que não compensa. E se o outro motivo for pra evitar dores, eu também acho que faz pouca ou nenhuma diferença. O que faz diferença é digitar errado e postura errada, independente do layout.</p>
<p>Se você já consertou tudo, mas digita muito rápido corretamente e tem tendinite, temos os teclados ergonômicos que talvez ajudem. Até onde eu sei não existe um consenso de qual é o melhor estilo mas em princípio você quer evitar mexer seu pulso o máximo possível. O problema é que todo teclado é totalmente horizontal, só que suas mãos não ficam naturalmente na horizontal. Você precisa girar os pulsos. Além disso você precisa trazer as duas mãos mais pra perto uma da outra, mas teoricamente o natural seria elas estarem mais separadas. Quanto maior você for mais isso é verdade.</p>
<p>Por isso a maioria dos teclados considerados ergonômicos primeiro não vão ser horizontais e sim inclinados de tal forma que você não precise girar os pulsos, mantendo o centro do teclado mais pro alto e as extremidades laterais pra baixo. Além disso eles vão dividir o teclado em duas partes e separar de tal forma que você não precisa aproximar tanto suas mãos. Tudo pra forçar menos tanto o pulso quanto todas as articulações do seu braço até os ombros. Muita gente ignora, mas sempre note se você está fazendo força com os ombros, isso causa dor.</p>
<p>Nessa categoria você encontra teclados como o Microsoft Sculpt ou similares da própria Microsoft como o Natural Ergonomic ou Surface Ergonomic, alguns mais genéricos como os da Logitech e algumas mais famosos hoje em dia como os da Kinesis, onde você tem tanto o monstruoso Advantage2 ou o Freestyle.</p>
<p>O principal problema que a maioria das pessoas vai ter com teclados desses eu diria que é até um ponto positivo, na real, porque você vai ser obrigado a aprender a digitar corretamente. Porque não tem como você digitar teclas que seria da mão esquerda com a a mão direita ou vice versa porque agora tem um espaço bem maior entre as duas metades.</p>
<p>Mas pra mim o problema era outro. Primeiro porque eu sempre achei teclados ergonômicos feios e com materiais de baixa qualidade. Isso felizmente mudou porque um Microsoft Sculpt é bem construído e até fico com vontade de experimentar. Segundo porque a maioria era full-size, ou seja, tinha teclado numérico e aí meu problema era dor no braço por usar o mouse tão afastado pra direita. De novo, o Sculpt é 75% então seria perfeito e apesar de ainda não ter experimentado eu recomendaria porque até o preço é razoável a 60 euros. Ele provavelmente não é mecânico, mas entre ter dor e usar um teclado rubber dome de boa qualidade, eu escolheria não ter dor.</p>
<p>Obviamente existem opções mecânicas como os da Kinesis. O Advantage2 usa switches Cherry Brown ou Red mas eu acho monstruoso demais, mas uma coisa que eu gosto dele é que tem boas opções de teclas extras perto dos dedões. Em vez de um espaço fixo no meio das duas metades do teclado, tem o Freestyle que você pode ajustar quanto espaço quer. O Freestyle normal é de membrana e rubber dome mas o Freestyle Pro tem opção também com switches Cherry Brown ou Red, mas eu nunca parei pra pedir. Mas pra variar, esses modelos são super caros com os Freestyle Pro na faixa dos 180 dólares e os Advantage2 na faixa dos 350 dólares. Os mais baratos de 100 dólares não são nem mecânicos.</p>
<p>Talvez um dia eu tente os modelos da Kinesis mas recentemente eu esbarrei em alguns vídeos mostrando um novo teclado, o Ultimate Hacking Keyboard. O conceito é muito bacana e eu recomendo ver os vídeos de review mais detalhado dele. Porém, assim como a Massdrop este daqui também é caro, mais caro ainda aliás, começando em nada menos que 275 dólares, sem contar frete e sem contar que no meu caso quando chegou aqui, a porcaria da receita federal me taxou em 100% do valor do produto. Bando de filho da p &hellip;</p>
<p>Aham, enfim. Agora que está aqui o que eu posso dizer é que assim como o Kinesis Freestyle, você tem o teclado fisicamente dividido em duas metades, o que facilita ajustar a distância no meio o quanto quiser, diferente dos da Microsoft por exemplo. Você também pode unir as duas metades se preferir e usar como se fosse um teclado normal. Quando faz isso o mecanismo de junção é um híbrido de encaixes físicos e ímãs que mantém as duas metades bem firmes no lugar, realmente é muito bem construído.</p>
<p>O chassi é de metal mas o frame ao redor é de plástico, mas é um plástico rígido de boa durabilidades, e não um molenga barato então não tem torção aparente e não afunda em nenhum lugar. Você pode parafusar os pés dele pra ficar em posição de tenda, levantando mais o meio, que é como todo ergonômico faz. Ou você pode escolher usar do jeito tradicional levantando mais a frente ou até fazer inclinação negativa colocando pra trás que eu não gosto muito.</p>
<p>Os keycaps foram minha maior decepção porque eles não chegam a parecer que são de ABS mas não parecem PBT também. Talvez um ABS melhor produzido. Não é doubleshot então as letras são todas impressas, o que significa que daqui algum tempo vai começar a sumir também. Por outro lado é um teclado com switches Kaihua, que são compatíveis com Cherry, o que significa que eu sempre posso trocar os keycaps por um kit de PBT doubleshot no futuro. Mas como o teclado já custa 275 dólares, eu esperaria keycaps melhorzinhos.</p>
<p>Mas o preço é caro assim por causa do circuito integrado e do software customizado. Esse teclado foi feito pra aceitar módulos que colocam controles extras ao alcance do seu dedão. Eu pedi os módulos de touchpad pro dedão direito e um grupo de teclas customizáveis extras pra ficar no dedão esquerdo. Se o touchpad funcionar resolve um dos meus problemas de ritmo que é ter que tirar a mão direita do teclado pra pegar no mouse. Com touchpad no dedão, não preciso tirar a mão do lugar, que é uma das coisas que sinto falta dos macbooks.</p>
<p>E o grupo de teclas pro dedão esquerdo vai ser importante porque esse teclado só tem layout de 60% que eu disse lá atrás que eu não gosto. Significa que qualquer tecla de navegação como page up, home e tudo é uma combinação de duas teclas. Imagina pra fazer coisas como shift + control + end pra marcar o texto até o fim da linha. Isso vira um malabarismo de apertar shift com o dedo anelar, control com o mindinho, mod com o dedão e &ldquo;O&rdquo; do outro lado. Eu até acho que com algumas semanas me forçando eu vou criar memória muscular, mas isso é bem inconveniente.</p>
<p>Pior ainda é que como não tem a linha de teclas de função em cima da linha de números, não existe a tecla Esc. Ela precisa ser uma combinação de duas teclas. Felizmente deu pra mapear a tecla que seria caps lock e que nesse teclado é um modificador pra controlar o mouse via teclado, mas mesmo assim minha memória muscular joga meu anelar esquerdo lá pra cima toda vez que quero Esc. Mas com o tal módulo pro dedão esquerdo eu conseguiria mapear coisas como esc, ou delete pra não ser uma combinação de teclas.</p>
<p>O problema é que esses módulos ainda não foram lançados. Eu comprei na pré-venda a 60 dólares cada módulo e eles só vão lançar em junho deste ano ainda. Me acompanhem no Instagram porque eu só vou mostrar esses módulos lá depois. De qualquer forma, o nome realmente resume bem o que é esse teclado, o Ultimate Hacking Keyboard. Falando nisso notem que a maioria dos teclados que eu falei até agora podem ser customizados e remapeados via software, mas tá fora do escopo deste video eu ficar falando disso, mesmo porque eu nunca remapeio teclas ou fico fazendo macros.</p>
<p>De novo, eu não sou gamer então não tenho tanta necessidade de customizar. E mesmo pra ambiente de programação eu prefiro não ficar criando macros porque eu uso teclados diferentes em cada lugar, então não vale a pena eu me acostumar com macros se vou usar 3 ou 4 teclados diferentes toda vez. Mas, sendo realista, este teclado é completamente fora de mão em termos de custo. Seriam 275 dólares só o teclado, mais 120 dólares por dois módulos, mais 75 dólares o palm rest de madeira que parafusa nas duas metades. Então o conjunto completo são nada mais, nada menos que 470 dólares sem contar frete nem imposto.</p>
<p>E falando em teclado caro, chegou a hora de eu mostrar o esteticamente mais diferente da minha coleção. Este é o QwerkyWriter S, e é querky com “K”, não confunda com o layout “qwerty”, obviamente que foi um trocadilho de propósito. Esse é outro que me custou nada menos que 300 dólares quando eu comprei em 2018. Não lembro se comprei em pré-venda ou algo assim porque fui ver na Amazon esses dias e esse mesmo modelo estava uns 500 dólares. Se for isso mesmo, esse é de longe meu teclado mecânico mais caro de todos e justamente por causa disso eu não recomendo pra ninguém que não seja entusiasta mesmo.</p>
<p>Esse foi o único que eu comprei exclusivamente pela aparência mesmo. Como podem ver o objetivo dele foi tentar se aproximar da aparência de uma máquina de escrever antiga. E sim, todos os apetrechos que você está vendo funcionam. A alavanca na esquerda realmente age como um return. Os botões de girar na esquerda e na direita que tentam parecer como se fosse pra puxar uma folha de papel se fosse uma máquina de escrever agem como botão de volume na direita e seta pra cima e seta pra baixo na esquerda, o que é bem legal porque é quase mesmo como puxar papel.</p>
<p>Ele é caro assim porque a construção e escolha de materiais é bem superior. Ele é um dos mais pesados, mais sólidos e mais rígidos, o que é absolutamente necessário pra passar mesmo a sensação de uma máquina de escrever. Ironicamente ele também é wireless com suporte a conectar até 3 dispositivos por bluetooth. E vem com um apoio atrás onde você pode colocar um tablet ou mesmo seu smartphone de pé. A intenção é que assim fica parecendo mesmo que você tá teclando num pedaço de papel, só que digital.</p>
<p>Aliás, uma dica se você conectar um teclado bluetooth num smartphone como iPad ou qualquer Android. Você vai ter dificuldade pra acentuar as coisas. Mas não precisa mudar o layout ou configurar nada. Por alguma razão o teclado em Android aceita combinações semelhantes ao do layout de teclados Mac. Por exemplo, pra acento agudo use alt e &ldquo;e&rdquo; e daí a sílaba. Pra acento com crase faça alt e &ldquo;i&rdquo; e daí a sílaba. Pra til é a mesma coisa só que com “n”, pra crase com backtick e pra cedilha é só alt e &ldquo;c&rdquo;. Alt em Mac é a tecla Option.</p>
<p>Esteticamente o que faz esse teclado evocar a aparência correta é porque assim como no Massdrop Ctrl ou Cooler Master SK630 que eu mostrei, os switches ficam expostos e, claro, os keycaps são mais altos. O que sai caro nesse teclado são justamente os keycaps que não são só plástico injetado. Cada um deles tem esse detalhe prateado ao redor. Em termos de acabamento e estética realmente se destaca de todos os outros na atenção a detalhes. Pra ficar mais próximo possivel de uma máquina de escrever, ele precisa ser barulhento, por isso vem com switches Cherry MX Blue. A própria batida da tecla no chassi complementa um som mais alto que o normal. Mesmo assim não é exatamente a mesma coisa.</p>
<p>Pra provar isso, temos que ver o verdadeiro teclado 100% mecânico. A boa e velha máquina de escrever. Pra mostrar aqui no canal eu resolvi comprar esta Olivetti Lettera 82, primeiro porque ela é bem menor do que a Olivetti que meu pai tinha ou as gigantonas britânicas Remington. Pense que isso aqui poderia ser como um jornalista iria em campo pra escrever matérias. Pensa como seria abrir um troço desses num Starbucks. Uma máquina dessas tem mecanismos que mapeiam cada tecla com um martelo num tambor na parte do meio. E a nitidez das letras vai ser proporcional à força que você marreta a tecla. Lembram que eu tava reclamando da diferença entre os 45 gramas de força de um Cherry Speed Silver contra os 78 gramas de um Thinkpad? Ha, essa aqui deve precisar pra lá de 100 gramas de força, fácil.</p>
<p>Mesmo se você nunca viu ou usou uma máquina dessas provavelmente entende o princípio de que tem um tambor com martelos de metal com letras em relevo no inverso, e quando você bate uma tecla ele movimenta um desses martelos batendo numa fita de tinta contra o papel. Daí por puro movimento mecânico a máquina mexe um espaço pra esquerda e assim você vai batendo uma letra atrás da outra.</p>
<p>Essas máquinas são a melhor coisa pra treinar digitar corretamente. Primeiro porque você literalmente vai fazer musculação nos mindinhos tentando marretar uma tecla pesada dessas, especialmente nas máquinas maiores. Segundo porque você realmente precisa fazer cada dedo bater no meio de cada tecla com precisão. Se escorregar e seu dedo bater duas teclas de uma só vez, os martelos podem enroscar e aí você tem que manualmente desenroscar, o que vai diminuir muito sua velocidade. Pior ainda se escorregar e seu dedo cair no meio das teclas. Embaixo são barrinhas de metal que vou te falar que dependendo de como você bater, pode machucar os dedos. Essa máquina é pra quem cresceu na época que mertiolate ardia.</p>
<p>Comparado com uma máquina de mesa essa pode ser considerada até leve, mas é no mínimo o peso de uns dois notebooks normais um em cima do outro. Eu não pesei mas me parece mais pesado que um saco de arroz de 5kg. As de mesa acho que era quase o dobro do peso. Ela é pesada demais pra carregar numa mochila mas leve demais a ponto de quando você tá datilografando e marretando teclas, ela fica escorregando na mesa se for muito lisa. Pra poder gravar eu tive que prender na mesa com fitas pra não ficar balançando pra tudo que é lado.</p>
<p>Eu não comprei junto mas antigamente a gente podia fazer múltiplas cópias ao mesmo tempo, bastava colocar papel carbono entre duas folhas e bater mais forte. Lembram o episódio do Diário de Henry Jones? Era assim que eu passava muitos dos meus dias:</p>
<p>(demonstração - lettera)</p>
<p>Achei interessante que tem vários modelos que você vai achar até que fácil em sites de usados como mercado livre, custando na faixa de uns 200 ou 300 reais. E tem até fitas novas sendo vendidas a meros 10 reais. Então, pra quem tiver curiosidade, tá super acessível. Obviamente os modelos mais raros vão ser mais caros, mas essa Lettera 82 hoje em dia tá fácil de achar.</p>
<p>Falando em carbono, quero aproveitar pra fazer uma tangente. Tem muita coisa do nosso dia a dia que os jovens, na faixa aí dos 20 anos ou menos não tem muita idéia e também nunca pararam pra questionar. Vou dar alguns exemplos: o mais óbvio é o famoso ícone em muitos programas pra opção de Salvar que ainda hoje é representado por um disquete. Eu usei muito disquete mas a nova geração nunca viu um ao vivo, e só sabe porque todo mundo já repetiu sobre isso em algum canal de YouTube. Outro exemplo que eu testei alguns meses atras foi sobre cartões de crédito. Alguma vez vocês já se questionaram porque cartões tem dados como o número, nome, data em relevo?</p>
<p>A maioria dos jovens primeiro nunca notou isso. Os que notaram acham que é puramente por estética. Porém a resposta é bem mais simples. Cartões de crédito são usados desde o meio do século XX. As maquinetas de cartão tipo as Cielo ou Stone que tem em toda loja hoje são invenções recentes que só começaram a se difundir no século XXI. E mesmo quando elas foram inventadas a internet móvel era super instável e em muitas regiões podia nem existir, então como fazia em lugares sem internet ou quando a internet caía? A gente tinha outra opção e eram máquinas manuais.</p>
<p>Nessas máquinas você colocava o cartão num espaço especial, daí colocava tipo um boleto com múltiplas folhas e carbono entre elas, daí puxava esse troço grandão que aplicava pressão contra o cartão. Daí o número, nome e data eram impressos no papel por causa da pressão da máquina contra o carbono e o cartão e voilá, tinha uma cópia pro lojista, outra pra administradora e um recibo pra você. Daí de tempos em tempos uma cópia era recolhida pela administradora que daí emitia fatura pra você e pagava o lojista. Basicamente processo parecido com o de hoje só que analógico. E quando começaram a surgir as maquinetas eletrônicas, elas podiam falhar ou ficar sem sinal ou mesmo a luz cair, e nesses casos os caixas tinham a contingência de usar essas máquinas manuais.</p>
<p>Voltando pra máquina de escrever. Elas são invenções bem antigas, acho que do fim do século XIX. No começo do século XX elas foram evoluindo. Resumindo bastante a história nós passamos por Graham Bell, por Thomas Edison, e criou-se a malha de comunicação e de eletricidade. Primeiro a gente tinha telégrafos, depois pulou pra telex. De forma simplificada podemos trafegar dados digitais encodados em ondas analógicas que podem viajar tanto pelo ar via rádio ou via cabo. Numa ponta ele precisa encodar a mensagem como um binário de zeros e uns, transformar isso em onda, transmitir e na outra ponta reverter da onda pra binário.</p>
<p>Muitos iniciantes tem dificuldade de entender isso. Mas pense na máquina de escrever. Cada tecla mapeia pra um martelo de metal no tambor. E se em vez disso ele mapear pra um código? Por exemplo, a letra “A” poderia ser 0 0 0 1 1, a letra “B” poderia ser 1 1 0 0 1 e assim por diante. E de fato era assim que as primeiras máquinas de telex funcionavam. Essa tabela de conversão era o baudot code inventado em 1870 e implementado em 1901. Telex significa Teleprinter Exchange e era usado uma máquina parecida com a de escrever mas em vez de ser só mecânica passou a ser eletromecânica pra fazer a conversão e modulação do sinal analógico.</p>
<p>Essa tabela de conversão Baudot era de 5 bits. E se você fez a conta de cabeça significa que é possível ter 2 elevado a 5 combinações diferentes, o que dá 32 combinações únicas. Como o alfabeto tem 26 letras e 10 números isso sem contar símbolos como de mais ou igual, significa que em 5 bits não cabe tudo. Pra isso você tinha dois códigos especiais pra mudar pra uma tabela de letras e outro código pra mudar pra uma tabela de números. Então o mesmo código pra letra “A” que eu falei também era do símbolo de “menos” se usasse antes o código de figuras. O da letra “B” era a figura de interrogação. No começo do século XX cada bit a mais era caro de processar porque eram processos mecânicos. O transistor só viria a ser inventado quase 50 anos depois.</p>
<p>Hoje em dia encodamos letras, números e símbolos usando convenções como UTF-8 onde a maiorias das letras e números em binário coincidem com a antiga tabela ASCII que era limitada em 127 combinações, porque é um esquema de 7-bits. Lembrando que você precisa se acostumar a pensar em binário e hexadecimal. Isso é matemática de primário, onde cada bit a mais que você adiciona duplica a quantidade possível de combinações. É uma exponencial de base 2. O ASCII antigo definia as primeiras 127 combinações. As próximas 128 combinações num esquema de 8-bits variavam bastante como no charset 1252 do Windows ou Mac Roman. De qualquer forma, strings e principalmente Unicode é um assunto bem cabeludo que fica pra outro dia. O importante era só lembrar que foi assim que tudo começou e que em computadores tudo é binário e como isso mapeia pra letras é uma convenção.</p>
<p>Falando em encoding de texto de Windows, vocês que são de Mac ou Linux devem ficar irritados toda vez que baixa um texto vindo de editores Windows antigos, porque o equivalente a uma nova linha que a gente em programação costuma simbolizar com “\n”, se vier de Windows, vai ter um caracter estranho aparecendo que é o símbolo “\r”. Mesmo em Git de Windows tem até a opção pra filtrar fora esse caracter inútil. Editores modernos como VS Code fazem certinho e não usam mais o \r.</p>
<p>Deixa eu mostrar pra vocês de onde vem o \n que significa New Line e o \r que significa Carriage Return. Vamos lá:</p>
<p>Isto é um New Line ou nova linha
E isso é um Carriage Return ou retorno do carro, e carro é esse cilindro onde passa a folha de papel.</p>
<p>(carriage return maquina de escrever)</p>
<p>Lembram que eu falei que as máquinas de Telex eram basicamente máquinas de escrever mais sofisticadas? Elas recebiam comandos e automaticamente batiam os martelos numa folha e precisavam receber os dois comandos pra fazer a coisa certa. Se recebesse um TXT moderno que só tem \n, não haveria o retorno do carro pro começo da nova linha. Esse era o motivo.</p>
<p>Aliás, outra coisa antiga que você talvez tenham se dado conta agora é que talvez já tenham ouvido falar de bauds quando lidam com modens. Muita gente confunde bauds com bits e de fato antigamente 1 baud era um 1 bit. Então um modem de 1200 bauds transmitia 1200 bits por segundo. Porém baud é um termo de telecomunicações e eletrônica que significa um símbolo ou mais corretamente um pulso por segundo. Num pulso você pode empacotar muitos bits, então um model de 1200 bauds com pacotes mais compactos de 8 bits por pulso na verdade transmitiam 9600 bits por segundo. E de onde vem Baud? Vem de Émile Baudot que criou a tabela de 5-bits usado nos telex que eu falei agora pouco.</p>
<p>Pra terminar a tangente, tem outra coisa que você provavelmente também já viu e não tem idéia do que é. Mas pense assim, depois da era do Telex começou a era da computação, principalmente depois dos anos 50 quando o transistor começou a popularizar. No fim dos anos 60 apareceram os primeiros UNIX. Mas os computadores de antigamente eram gigantes que nem um armário. Não era que nem um desktop que você coloca embaixo da mesa. Mais do que isso, eles eram recursos compartilhados porque não dava pra ter um computador gigante por pessoa. Por isso nasceu o conceito de rodar jobs assíncronos em paralelo de várias pessoas e depois timesharing pra ser possível ter múltiplas pessoas usando o computador ao mesmo tempo com o processador dividindo o tempo entre diferentes processos. Eu explico um pouco disso no meu video do ano passado que está na Playlist de Programação para Iniciantes, na de concorrência e paralelismo.</p>
<p>Então, por necessidade, precisava dar um jeito de compartilhar o mesmo computador, mesmo remotamente. Por isso existiam os terminais remotos. E os primeiros terminais sequer precisavam ter monitores, pense que eles eram máquinas de Telex conectadas no computador e as respostas eram impressas em papel. A vantagem disso era que você podia ter esse teleprinter do lado do computador ou remotamente. Então o que chamamos hoje de STDIN ou Standard Input era uma máquina tipo essa minha de escrever mas adaptada pra ser uma teleimpressora como na era do Telex. E o STDOUT ou Standard Output poderia ser um monitor de fósforo verde ou âmbar de antigamente ou mesmo a impressora em papel.</p>
<p>Quando a saída eram monitores remotos eles eram chamados de Video Terminals ou VTs. Com o tempo, além das letras e números mapeados na tabela ASCII que eu falei, começaram a criar comandos de escape especiais pra mover o cursor em posição X e Y na tela bem como mudar cores e coisas do tipo, e um conjunto ficou mais conhecido e é usado até hoje, o conjunto VT-100, que são combinações de caracteres que escapam de serem impressos, normalmente começando com o código binário pra Esc, abre colchete e algum código. Um dos grandes problemas do console de linha de comando antigo do Windows, o conhost é que ele sequer suportava esses escape codes então imprimia tudo errado. Isso foi corrigido com o novo Windows Terminal que tá quase saindo de versão Preview e você pode ver mais sobre isso no episódio que eu fiz sobre o WSL 2.</p>
<p>Mas, voltando onde quero chegar. Esses teleprinters são o que chamamos de dispositivos de entrada, input devices. E foi no UNIX que se criou o conceito de lidar com tudo, incluindo devices, como se fossem arquivos. Por isso existem os arquivos /dev/tty que vai de tty0 até tty63, ou seja, num Linux moderno daria pra ligar até 64 dispositivos. Toda vez que você abre o programa de Terminal, como o que vem nas distros ou outros como um Tylix da vida ele se registra como um dispositivo de entrada virtual, um pseudo-TTY ou PTY.</p>
<p>Vamos fazer um teste abrindo aqui meu bom e velho Manjaro de guerra. Se eu abrir um Terminal e digitar o comando <code>tty</code> ele vai devolver em qual estou conectado. Note que não é um /dev/tty1 ou algo assim e sim /dev/pts/0. PTS são Pseudo Terminal Slaves, associados a um PTY, que serve pra conectar terminais falsos ou emuladores de terminal como é o caso de um programa como xterm ou Tylix que não é um teleprinter de verdade e nem mesmo um hardware moderno como teclado ou mouse. Se eu abrir outra janela ou mesmo dividir essa janela em duas, a segunda vai se conectar em outro <code>pts</code> diferente.  Eu posso fazer um script besta na primeira janela pra esperar alguma coisa, por exemplo um programinha de uma linha de Ruby com o comando <code>gets</code>, que vai ficar esperando alguma coisa vir pelo STDIN, por exemplo pelo teclado.</p>
<p>Agora, do segundo terminal eu posso dar o comando <code>echo</code> de qualquer string direto pro /dev/pts/0 e ele vai direto pro script Ruby. Mas agora, quem se liga nos TTY de verdade do sistema além de teclado e mouse? Podemos dar um comando <code>ps aux</code> pra listar todos os processos rodando e dar um <code>grep</code> por tty e de fato vemos que o X.org e o GDM que é o gerenciador de janelas gráficas do GNOME é que estão pendurados lá. Note que eles estão no TTY2. Se eu der Ctrl + Alt + F3 eu vou pular pro TTY3, de onde eu posso dar login normalmente. E se der de novo <code>ps</code> com grep em tty pra filtrar, vemos que no tty3 está o Zshell que é onde estou neste momento. E se eu der Ctrl + Alt + F2 eu posso voltar pra sessão gráfica do X.</p>
<p>Em muitos casos, se por acaso seu X travar por alguma razão, pode ser possível destravar sem precisar bootar a máquina. Tente fazer primeiro Ctrl + Alt + backspace que é um hard restart do X. Se isso não funcionar, você pode tentar ir pra outros TTY e de lá dar um kill forçado no X por exemplo.</p>
<p>E agora vem o interessante, eu ainda não falei o que significa TTY. Máquina de escrever em inglês é typewriter. Um typewriter adaptado pra Telex é um TeleTypeWriter e daí vem TTY. Agora você sabe. Este assunto de TTY é muito importante que todo programador que usa Linux ou derivados de UNIX tem obrigação de saber. Por isso vou deixar linkado nas descrições abaixo um artigo que eu achei faz tempo e que é bem completo chamado TTY Demystified.</p>
<p>Voltando pro assunto de teclados, já que falei do avô dos teclados, podemos finalizar pulando algumas décadas e cair nos anos 80 pra falar do último da minha coleção. Diferente de máquinas de escrever que você encontra até que barato, este teclado é caro. Eu paguei uns 1400 reais no mercado livre num anúncio que estava lá pegando poeira fazia alguns anos. Aliás, quando eu abri a caixa veio pó com cheiro dos anos 90 nele, sério.</p>
<p>É este IBM Model M, uma das primeiras versões. Este em particular é da série que chegou a ser montado na Zona Franca de Manaus. E não é como os porcaria que vinha nos IBM Aptiva de 1994 em diante. Este Model M é de dez anos antes, 1985. Se quiserem entender a história dos Model M, por acaso, tem um video curto e bem feito do canal Linus Tech Tips que explica as diferentes versões, então vou deixar o link nas descrições abaixo também.</p>
<p>Os model M são tanques de guerra. Este em particular, é um que provavelmente se ligava num Terminal remoto, num VT. Isso porque ele é a versão que ainda não tem as luzes de caps lock ou num lock na direita. E fora isso o conector dele é anterior à existência do padrão PS2. O cabo é serial com conector RJ-45 que é o mesmo que se usa em cabow de rede Ethernet. Ou seja, eu preciso de um adaptador especial que não é o mesmo adaptador de redes pra USB que se encontra por aí, o circuito é totalmente diferente. Por isso eu encomendei um que achei no eBay mas ele não chegou até o dia de gravação desse video então eu não pude testar de verdade esse teclado. Mas vamos ver como ele se parece digitando.</p>
<p>(digitando model M)</p>
<p>Como deu pra ouvir, o barulho é alto, irritante e extremamente satisfatório. Esse barulho faz o click dos Cherry MX Blue parecer brincadeira de criança. Se a máquina de escrever que mostrei é o avô dos teclados mecânicos, este Model M é o paizão de todos. Porém, diferente dos mecanismos modernos, este tem switches que chamamos de Buckling Springs. Na prática, dentro tem uma mola que quando você vai pressionando ele vai se deformando até acumular força pra empurrar a peça da base e pressionar um rubber dome em cima de uma membrana, registrando a tecla. Ou seja, este é provavelmente um dos melhores teclados de membrana ou rubber dome, com a diferença que não é a resistência do domo de borracha que segura a tecla e sim a mola entre a tecla e o domo. Por isso a sensação é bem diferente e única.</p>
<p>Assim como o Cherry Blue, ele tem um click bem nítido de quando a mola quebra a tensão, soltando o barulho de click. Além disso os keycaps neste modelo são diferentes. Eles são, entre aspas, double mas não é double shot, são literalmente duas cascas de tecla uma em cima da outra mas não grudados. Parece que a tecla que se conecta no switch é tudo do mesmo tamanho, daí em cima dela tem outra que tem os formatos diferentes de cada tecla. Então são teclas mais pesadas do que você tá acostumado. Some a isso este frame e chassi que é grande, denso, robusto e bem rígido. Esse teclado é um tanque de tão pesado. Eu poderia chutar que é metade do peso da máquina de escrever. Por isso você pode bater com a força que quiser que esse monstro aqui não se mexe.</p>
<p>Não dá pra usar a medida de força de acionamento oficial porque estamos falando de um mecanismo com molas que são mais velhas que a maioria de vocês assistindo, provavelmente com 30 anos ou mais de idade. As patentes originais foram sendo passadas pra frente e hoje estão com a empresa Unicomp que faz Model M novos usando os mesmos mecanismos mas com peças novas e você pode encomendar na Amazon americana por uns 95 dólares, o que eu diria que vale a pena. Eu só não gosto porque eles só fazem tamanhos full-size, com o teclado numérico que eu não preciso.</p>
<p>Mas a sensação de digitar é bem diferente do que todos os outros teclados. Eu diria que ele precisa de pouca coisa mais de força do que os Cherry MX Blue. Mas é um pouco menos do que os switches Topre da RealForce. O Topre vocês vão lembrar que eu disse que sinto que tem uma resistência maior logo no começo da tecla, este tem uma resistência um pouco maior mais pro fim, no ponto em que a mola faz o clicky e é amortecido pelo domo de borracha da membrana. Não dá pra dizer se ele é melhor, mas certamente a sensação é bem diferente. Eu pessoalmente gosto bastante desse switch e queria ver modelos modernos. Talvez eu encomende um Unicomp. O problema é que ele é um dos mais barulhentos então eu definitivamente não recomendo usar num escritório com outras pessoas.</p>
<p>Com este Model M eu senti que tenho uma coleção com as principais variações de switches e qualidades de construção. Assim que chegar o adaptador pra esse conector RJ-45 eu falo mais sobre ele no Instagram, então não deixem de me seguir lá, que aliás é onde vou mostrar qualquer outro novo teclado que comprar. Mas depois de tudo isso, qual o teclado que eu gosto mais? Isso varia muito, depende do dia e do meu humor mesmo. Tirando o baratinho que mostrei no começo do video anterior de propósito, todos os outros são bons e eu gosto e não pretendo me desfazer de nenhum. Na prática, não precisa comprar nenhum de 200 dólares ou mais porque não vão ser tão diferentes dos de 100 dólares. Vai variar mais em funcionalidades, tamanho, portabilidade, extensões e outras coisas, mas pra digitação em si muda muito pouco.</p>
<p>Por isso eu falei no começo deste video que o melhor custo-benefício são os da Keychron. Começando abaixo de 100 dólares, é difícil competir. No Brasil talvez seja mais fácil achar os Corsair ou Razer, então ficaria de olho neles também. Ambos até tinham quiosques de demonstração em alguns shopping centers. Se você for entusiasta e tiver dinheiro pra gastar existe um ecossistema enorme onde você pode comprar todas as peças separadamente e você mesmo programar seu firmware, soldar sua própria placa com os switches que quiser e muito mais. Só de keycaps você vai encontrar dezenas de qualidades, cores e estilos bem diferentes. E sim, vai ter que importar, basicamente inexiste um mercado de peças de boa qualidade fabricadas no Brasil pra entusiastas.</p>
<p>No final, não, você não precisa e nem deve procurar teclados caros achando que isso vai afetar sua produtividade de alguma forma, porque não vai. Da mesma forma que não adianta sair comprando Nikes de corrida se você não consegue correr nem um quilômetro sem morrer. O equipamento só ajuda quem já é treinado. Sim, teclados baratinhos daquela faixa dos 100 reais pode atrapalhar, porque seus dedos vão escorregar em teclas de baixa qualidade, o amortecimento de domos de borracha porcaria vai dar falsos registros de tecla ou nem registrar, as membranas podem ter mal contato e te levar a erros mais frequentes e tudo mais. Mas na faixa dos 70 dólares pra cima é mais difícil de errar. Acho que com os teclados que mostrei deu pra dar uma noção de porque alguns cobram mais caro que outros. E é muito mais pelo luxo do que pela produtividade.</p>
<p>Inclusive, outra pergunta que muita gente deve ter na cabeça é por quê eu tenho esta coleção. E a resposta é muito simples, pelo mesmo motivo que qualquer pessoa faz uma coleção: porque eu quero. Tem gente que coleciona quadros, tem gente que coleciona miniaturas, tem gente que coleciona tampinhas de garrafa ou sei lá, eu gosto teclados e ponto. É mais barato que colecionar carros e tem a diferença que teclado é de longe o equipamento que eu mais uso todos os dias. Eu passei os anos 90 e os anos 2000, quase 20 anos usando teclados de membrana com plástico barato porque era o que dava pra comprar. Hoje eu posso comprar um bom mecânico. Dependendo do seu estilo de vida, um bom teclado desses sai mais barato que muito show ou balada por aí.</p>
<p>Cada seção onde eu falo de cada teclado deste episódio e do anterior eu escrevi usando o teclado certo, então estes episódios foram escritos com todos os 16 teclados, com exceção da Olivetti Lettera e do IBM Model M que ainda não dá pra ligar. Mas o que eu mais usei no geral foi mesmo meu Keychron K2. E com isso encerro o assunto de teclados mecânicos, aproveitem pra ajudar o povo com dúvidas nos comentários, se curtiram o video mandem um joinha, assinem o canal e cliquem no sininho pra não perder os próximos episódios. E não deixem de compartilhar o video pra ajudar o canal. A gente se vê, até mais.</p>
]]></content:encoded><category>teclados</category><category>hardware</category><category>reviews</category><category>akitando</category></item><item><title>[Akitando #78] - Entendendo Teclados Mecânicos | Minha coleção - Parte 1</title><link>https://akitaonrails.github.io/2020/05/05/akitando-78-entendendo-teclados-mecanicos-minha-colecao-parte-1/</link><guid isPermaLink="true">https://akitaonrails.github.io/2020/05/05/akitando-78-entendendo-teclados-mecanicos-minha-colecao-parte-1/</guid><pubDate>Tue, 05 May 2020 18:00:00 -0300</pubDate><description>&lt;div class="embed-container"&gt;
&lt;iframe
src="https://www.youtube.com/embed/tEXX1jdpZN8"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h2&gt;DESCRICÃO&lt;span class="hx:absolute hx:-mt-20" id="descricão"&gt;&lt;/span&gt;
&lt;a href="#descric%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Finalmente consegui compilar a primeira metade do vídeo sobre minha coleção de teclados mecânicos. Neste episódio você vai entender as principais características de teclados mecânicos, algumas das principais marcas e modelos e, claro, as combinações que mais me agradam.&lt;/p&gt;
&lt;p&gt;Também vamos comparar com alguns notebooks e o que diferencia os mecânicos dos &amp;ldquo;normais&amp;rdquo; e pra isso também vou contar sobre a controvérsia dos switches butterfly da Apple.&lt;/p&gt;</description><content:encoded><![CDATA[

<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/tEXX1jdpZN8"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<h2>DESCRICÃO<span class="hx:absolute hx:-mt-20" id="descricão"></span>
    <a href="#descric%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Finalmente consegui compilar a primeira metade do vídeo sobre minha coleção de teclados mecânicos. Neste episódio você vai entender as principais características de teclados mecânicos, algumas das principais marcas e modelos e, claro, as combinações que mais me agradam.</p>
<p>Também vamos comparar com alguns notebooks e o que diferencia os mecânicos dos &ldquo;normais&rdquo; e pra isso também vou contar sobre a controvérsia dos switches butterfly da Apple.</p>
<p>Como o video é longo, segue um bookmark das principais seções do video pra ficar mais fácil voltar depois:</p>
<p>02:06 - velocidade de digitação e um resumo inicial
05:54 - switches butterfly da Apple
08:33 - Surface Book 2 e Thinkpad Extreme
12:27 - o mau exemplo: Bright
16:26 - Das Keyboard 1
20:07 - Corsair K65 Vengeance
24:34 - Cooler Master SK630
29:38 - Razer Blackwidow Chroma V2
33:12 - Logitech G PRO
36:04 - Matias Mini Quiet Pro
37:53 - Tamanhos de Teclados
42:09 - RealForce 87U</p>
<p>Links:</p>
<ul>
<li>Click, Clack (<a href="https://tedium.co/2018/07/19/cherry-mx-keyboard-history/"target="_blank" rel="noopener">https://tedium.co/2018/07/19/cherry-mx-keyboard-history/</a>)</li>
<li>Cherry MX Switch Comparison - KeyMouse (<a href="https://www.youtube.com/watch?v=zlSPH3HvxhQ"target="_blank" rel="noopener">https://www.youtube.com/watch?v=zlSPH3HvxhQ</a>)</li>
<li>An introduction to Kailh switches, including Speed &amp; Box (<a href="https://www.keyboardco.com/blog/index.php/2017/11/an-introduction-to-kailh-switches-including-speed-box/"target="_blank" rel="noopener">https://www.keyboardco.com/blog/index.php/2017/11/an-introduction-to-kailh-switches-including-speed-box/</a>)</li>
<li>MK&rsquo;s official mechanical keyswitch guide (<a href="https://mechanicalkeyboards.com/switches/"target="_blank" rel="noopener">https://mechanicalkeyboards.com/switches/</a>)</li>
<li>THE BEST MECHANICAL KEYBOARD KEYCAPS (<a href="https://blog.wooting.nl/what-are-the-best-mechanical-keyboard-keycaps/"target="_blank" rel="noopener">https://blog.wooting.nl/what-are-the-best-mechanical-keyboard-keycaps/</a>)</li>
<li>ABS vs. PBT Keycaps (<a href="https://gearbroz.com/abs-vs-pbt/"target="_blank" rel="noopener">https://gearbroz.com/abs-vs-pbt/</a>)</li>
<li>Full-size, TKL, 60% and more: a guide to mechanical keyboard sizes (<a href="https://www.keyboardco.com/blog/index.php/2017/08/full-size-tkl-60-and-more-a-guide-to-mechanical-keyboard-sizes/"target="_blank" rel="noopener">https://www.keyboardco.com/blog/index.php/2017/08/full-size-tkl-60-and-more-a-guide-to-mechanical-keyboard-sizes/</a>)</li>
<li>Why Are Apple’s Butterfly Keyboards So Bad? (<a href="https://www.maketecheasier.com/why-apples-butterfly-keyboards-so-bad/"target="_blank" rel="noopener">https://www.maketecheasier.com/why-apples-butterfly-keyboards-so-bad/</a>)</li>
<li>Razer Blackwidow Chroma V2 (<a href="https://www.razer.com/gb-en/gaming-keyboards-keypads/razer-blackwidow-chroma-v2"target="_blank" rel="noopener">https://www.razer.com/gb-en/gaming-keyboards-keypads/razer-blackwidow-chroma-v2</a>)</li>
<li>Matias Mini Quiet Pro (<a href="https://matias.ca/miniquietpro/pc/"target="_blank" rel="noopener">https://matias.ca/miniquietpro/pc/</a>)</li>
<li>REALFORCE TKL SA / R2TLSA-US4-IV (<a href="https://www.realforce.co.jp/products/R2TLSA-US4-IV/index.html"target="_blank" rel="noopener">https://www.realforce.co.jp/products/R2TLSA-US4-IV/index.html</a>)</li>
<li>Realforce 87U Tenkeyless 55g (Black) (<a href="https://www.amazon.com/gp/product/B00MV84Y2Y/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&amp;psc=1"target="_blank" rel="noopener">https://www.amazon.com/gp/product/B00MV84Y2Y/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1</a>)</li>
</ul>
<h2>SCRIPT<span class="hx:absolute hx:-mt-20" id="script"></span>
    <a href="#script" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Olá pessoal, Fabio Akita</p>
<p>Finalmente resolvi falar um pouco sobre minha coleção de teclados mecânicos. Depois de mais de um mês em quarentena sem ver uma pessoa já já vou estar conversando com meus teclados isso sim. No total são uns 16 teclados mas vou cobrir metade hoje e dividir alguns itens especiais pra falar só no próximo episódio. E pra ficar fácil encontrar qual, também vou deixar um bookmark com o tempo de cada um nas descrições abaixo. Parece que o interesse por teclados mecânicos cresceu bastante recentemente. Eu venho colecionando bons teclados faz uns 5 anos já. Então vamos lá que tem bastante coisa só pra hoje.</p>
<p>(&hellip;)</p>
<p>Antes de mais nada, eu não pretendo explicar tudo que existe sobre cada teclado. Vou focar só no que é importante pra mim. Existem canais inteiros dedicados só pra falar de teclados, incluindo DIY pra quem quer construir um teclado customizado. Três exemplos de canais que eu assisto são o Random FrankP, o Hardware Canucks e o Tae Keyboards. Em cada video eles vão em muitos detalhes sobre cada teclado, os keycaps, switches, testes de som, desmontagem pra ver o chassi, chipset e muito mais. Se você tem curiosidade sobre um teclado em particular, veja se eles já não falaram a respeito.</p>
<p>Vamos tirar algumas coisas do caminho primeiro. Muita gente ainda pensa que teclados mecânicos é só coisa pra gamers. E isso não está totalmente errado. Muitas das melhores tecnologias de teclado de fato estão nos modelos pra gamers profissionais, em marcas como Razer. Mas não se engane, só porque tem RGB não quer dizer que é pra gamer. Aliás, tem muito xing ling por aí que enfia LED em teclado porcaria achando que vai atrair gamers. Só se forem os amadores mesmo. De qualquer forma, muitas das tecnologias de verdade pra gamers como switches confiáveis e rápidos, anti-ghosting, baixo input lag e tudo mais já existem em teclados sóbrios que não são só pra gamers e sim pra touch typists, ou seja, povo que sabe digitar rápido com todos os dedos.</p>
<p>Falando em velocidade, existem diversos sites e ferramentas disponíveis pra quem quiser treinar digitar corretamente. Muita gente acaba usando o 10fastfingers, e como passatempo é divertido. Mas a configuração padrão dele é extremamente fácil, com palavras simples de 3 ou 4 letras. Então não é difícil eu ficar entre 95 a 105 palavras por minuto, algo em torno de 400 toques por minuto. Mas isso é velocidade de competição, onde eu preciso estar focado em copiar muito rápido sem pensar se o que estou digitando faz qualquer sentido. Ninguém consegue manter esse ritmo num trabalho de programação ou dissertação durante horas sem parar. Isso é velocidade de pico e não média. A média de trabalho seria muito abaixo, mais pra 40 palavras por minuto ou menos, porque o certo é você parar pra pensar no que tá escrevendo. Tirando trabalho de digitador mesmo, ninguém fica apostando corrida.</p>
<p>Mas claro, se num site como 10fastfingers você está abaixo das 70 palavras por minuto eu realmente recomendo que treine muito mais. Apesar de gostar de me considerar um touch typist mesmo eu estou ciente que tenho defeitos em alguns dedos, em particular meu dedo anelar da mão direita eu uso muito mal. Os verdadeiros touch typists vão acima de 150 palavras por minuto. Já em código só dá pra ir rápido assim se você estiver digitando algo que já repetiu dezenas de vezes antes, e nesse caso eu tomaria cuidado: porque você tá repetindo tantas vezes o mesmo código em tantos lugares e ainda não extraiu em uma biblioteca ou algo assim?</p>
<p>Na prática, se eu realmente me concentrar, em silêncio, com palavras simples, fico na faixa das 90 e poucas palavras. A maioria dos teclados que eu vou mostrar consegue me manter na faixa entre 80 e 90 sem atrapalhar. E aqui já vou resumir: o teclado faz um pouco de diferença se e somente se, você já for um digitador rápido. Se você tiver estatura média e mãos pequenas como as minhas, prefira switches lineares, especialmente os semelhantes aos Cherry MX Speed Silver que eu vou explicar mais na frente. Eles exigem na faixa de 45 gramas de força. Agora, se você for maior, com mãos grandes tipo jogador de basquete, aí talvez faça mais sentido switches com mais resistência como os Cherry MX Blue ou Black que exigem uns 60 gramas de força. Teclados de notebook são mais rasos mas também são mais pesados, exigindo uns 70 gramas de força. Em notebooks eu tendo a ir mais devagar e fico abaixo das 80 palavras por minuto, por exemplo.</p>
<p>Uma pergunta que muita gente vai fazer é se deveria treinar layouts diferentes do tradicional qwerty como Dvorak ou Colemak. Eu não vou entrar nesse assunto nestes videos mas meus dois centavos é que vale a pena experimentar se você tem tempo ou interesse nessas coisas. Mas pra maioria da população não, é perda de tempo. Não vai drasticamente aumentar sua velocidade e nem diminuir dores magicamente. Melhorar sua postura vai fazer muito mais diferença. Não quer dizer que sejam ruins, só que não tem nenhum milagre neles. E isso vai limitar suas opções também porque só vai poder usar alguns tipos de teclados e toda vez que for usar maquina de outra pessoa vai ter que incomodar instalando layouts diferentes. É muito pouco prático por isso não me interessa.</p>
<p>Outra pergunta que já sei que todo mundo vai fazer é sobre custos, eu realmente não tenho muitos teclados baratos. E cuidado com os baratos demais, que como eu vou mostrar já já, é comprar gato por lebre. Os parâmetros que eu diria é procurar marcas que ofereçam switches Cherry, Gateron ou Kaihua que são mais fáceis de encontrar, de preferência o tipo linear como Cherry Red ou Speed Silver. Também prefira os que ofereçam keycaps PBT doubleshot. E fique com tamanhos que vão do TKL até no máximo 65% se não quiser sofrer muito. Vou explicar tudo isso em mais detalhes neste video, mas esses são os parâmetros. O meu recomendado de custo benefício mesmo vai ficar pra Parte 2, então aguardem pra ver.</p>
<p>Como eu estava dizendo, teclados mecânicos viraram moda ultimamente, o assunto virou notícia nos últimos anos não só por causa do aumento da comunidade de gamers profissionais, mas também por causa do fracasso homérico da Apple com os famigerados switches butterfly que sempre quebram e foram alvo de muita crítica até finalmente eles resolverem voltar pros antigos switches scissor que era o padrão até 2015.</p>
<p>Pra quem não acompanhou, por muitos anos os notebooks e magic keyboards da Apple usavam o design de switches que ficou conhecido como scissors porque as peças são conectadas no meio e sobem e descem parecendo uma pequena tesoura, conseguindo manter uma tecla fina e estável por cima. Era um design simples, feito com peças comoditizadas, testadas ao longo de anos e muito confiáveis. Raramente você ouvia falar de alguém reclamando disso.</p>
<p>Mas por volta do fim de 2015 a 2016 a Apple resolveu mudar esse design pro que ficou conhecido com switches butterfly ou borboleta porque as peças se movem parecendo as asas de uma borboleta. O objetivo era diminuir o que chamamos de key travel que é a distância entre a tecla em seu estado de repouso até ele encostar no final. O que chamamos de actuation ou acionamento do circuito da tecla em si costuma acontecer no meio do caminho antes de bater no final. Em notebooks é um espaço bem pequeno, na casa de 1 milímetro.</p>
<p>Teoricamente, com key travel menor você consegue trabalhar o frame, ou o casco do notebook pra ficar mais fino, coisa que sempre foi uma prioridade no design industrial da Apple. Porém, esse design tem pelo menos dois grandes problemas: diferente dos switches scissors, os butterfly usam peças mais frágeis e por causa do key travel super curto, o espaço embaixo da tecla quando sobe funciona como uma pequena sucção, atraindo sujeira pra baixo dela. Qualquer grão de poeira no lugar errado é suficiente pra travar a tecla. E isso foi tão comum que todo novo modelo de macbook lançado já vinha com reportagens das teclas estarem travando.</p>
<p>Umas 2 ou 3 revisões diferentes foram feitas, inclusive adicionando uma membrana fina de silicone ou algo assim ao redor do switch, mas mesmo assim as teclas continuavam com alto grau de defeitos. Depois de uns 4 anos tentando e toda vez fracassando, finalmente no fim do ano passado eles decidiram reverter pros switches scissor originais e até agora não vimos mais relatos desastrosos como os de antes. Mas apesar das más notícias no mundo Apple nesses últimos anos, também precisamos reconhecer que foi por causa dela que desde o ano 2000 as demais marcas tiveram que evoluir e oferecer teclados melhores.</p>
<p>Hoje em dia, dentre as principais marcas de notebooks, meus dois preferidos são os da linha Surface da Microsoft, em particular o teclado do Surface Book 2 que eu uso faz uns 3 anos e o lendário teclado dos Thinkpad, como desse Thinkpad Extreme que eu tenho faz quase um ano. O que mais varia em notebooks é o layout das teclas, em particular as da direita que tem as setas e navegação como page up ou home. Em termos das teclas em si, nenhum é excepcionalmente bom porque o próprio tamanho dos notebooks não permite teclas muito maiores. Em notebooks baratos demais o teclado é o menor dos problemas, mas dentre aqueles que começam na faixa dos mil dólares é mais questão de gosto mesmo.</p>
<p>Vamos ver como é o teclado do Surface Book 2 por alguns segundos pra vocês verem. São os que mais se assemelham aos da Apple na minha opinião.</p>
<p>(teclado Surface Book 2 - demonstração)</p>
<p>Agora vamos ver como é o do Thinkpad. Ele tem o lendário mamilo vermelho mas eu realmente nunca precisei dele em nenhum modelo que já testei. Considero bem inútil porque os touchpads hoje são bons o suficiente. Aliás, em termos de touchpad nada supera os da Apple, mas os notebooks premium tem touchpads competentes já. Mas vamos voltar pro Thinkpad.</p>
<p>(teclado Thinkpad - demonstração)</p>
<p>O que eu gosto dos dois primeiro é o chassi. Um dos grandes problemas de notebooks baratos é que eles usam chassis de plástico pouco resistentes e quando você aplica só um pouco de pressão no meio eles flexionam. Eles não são rígidos. Eu vou mostrar isso já já com outro teclado. No caso do Surface Book, ele tem mais key travel que os macbooks com switches butterfly e mesmo assim já estão no que eu considero o limite, de 1.2 milímetro de key travel e são um pouco mais resistentes que a maioria, requerendo uns 70 gramas de actuation force. Ou seja, você precisa aplicar 70 gramas de força pra tecla descer 1.2 milímetros e fechar o contato do circuito pra registrar a tecla.</p>
<p>No caso do Thinkpad Extreme, ele tem um key travel maior de generosos 1.7 milímetro. Meio milímetro pode não parecer muito mas faz bastante diferença pra um notebook de menos de 2 centímetros de espessura. Porém eu acho as teclas um pouco mais cansativas pra digitações longas porque precisa de 78 gramas de actuation force. Por isso eu disse antes que minha velocidade de pico fica na casa das 80 palavras por minuto e é bem mais difícil pra mim alcançar os 100.</p>
<p>No caso dos famigerados switches butterfly da Apple, eles eram tão rasos que estamos falando de um key travel de 0.7 milímetro, ou seja, menos de um milímetro. E pelas specs oficiais ele precisa de 70 centiNewtons de força ou aproximadamente 71 gramas de força. Portanto em termos de força é parecido com o Surface mas como o key travel é 1 milímetro menor, eu sempre senti como se estivesse batendo meus dedos na mesa. É muito cansativo pra longas sessões de digitação.</p>
<p>Vale lembrar que praticamente todos os principais notebooks usam switches scissor, não só a Apple como os modelos que eu mostrei acima. As patentes são dos anos 80 e eu não sei se os fabricantes precisam pagar royalties hoje em dia, e se sim isso também explica porque a Apple tentou um design diferente pra fugir de ter que pagar licença. Mas pelo visto switches scissor estão na ativa dos anos 80 até hoje porque passaram pelo teste de confiabilidade do tempo. Outra coisa que muitos não sabem é que esse switch usa um rubber dome ou domo de borracha no meio, que é o que dá a resistência do switch e que levanta a tecla pra posição original depois, ou seja, não é um mecanismo mecânico com molas. É a própria resistência do domo de borracha que levanta a tecla de volta.</p>
<p>Eu cito isso porque muita gente acredita que as diferenças em switches de teclado são basicamente os que tem rubber dome e os que não tem. Mas é um pouco mais complicado que isso como eu vou mostrar mais pra frente. Vamos pular de notebooks pra desktops e começar com um tecladinho bem vagabundo, hiper barato da faixa de 50 reais que eu comprei anos atrás só pra ligar temporariamente num raspberry pi que eu tava testando na época que eu só usava Macs e não usava teclados externos. Essa belezinha aqui de marca genérica chamada Bright.</p>
<p>(intro Bright)</p>
<p>É muito mais fácil falar de teclados bons começando por um bem fuleira que mostra tudo que tem de errado nos teclados baratos demais. Pra começar, o chassi inteiro e o frame são totalmente de plástico e dos mais vagabundos, olha como eu consigo torcer ele inteiro e como se eu aplicar só um pouco de força no meio ele afunda inteiro. Agora olhem também como ele tem zero estabilização nas teclas maiores como a barra de espaço. Quando se digita, você tem a sensação de estar afundando o dedo num pedaço de borracha escolar, e é praticamente isso que tem embaixo das teclas. É tudo meio molenga e ele faz você errar bastante enquanto digita. Mesmo assim eu resolvi fazer o teste de velocidade nele, mas foi super irritante.</p>
<p>(digitacao bright)</p>
<p>As teclas em si são provavelmente de ABS ou pior, PVC. Parece aqueles kits de brinquedo de plástico que tem tudo grudado numa grade e você vai recortando as peças e fica aquelas pontas de plástico. Tudo é meio folgado, todas as teclas balançam um pouco. Além disso veja meio inclinado que as letras e símbolos parecem algum tipo de adesivo, e teclas baratas assim normalmente tem as letras impressas por cima mesmo, que com o tempo apagam.</p>
<p>Lembram que eu falei que no caso do switch butterfly da Apple tinha key travel de menos de um milímetro e parecia que eu tava batendo os dedos numa mesa dura? Isso porque o chassi da Apple é de alta qualidade, rígido e de alumínio. No caso dos baratos de plástico que nem esse aqui, parece que eu tô escorregando os dedos por cima de plástico liso em cima algo molenga. Não tem firmeza nenhuma. Às vezes parece que você teclou e a tecla não registrou, ou você escorrega pro lado. A grande maioria dos teclados da faixa abaixo de 100 reais vai ser alguma coisa lastimável assim. Pra achar um razoável nessa faixa tem que pesquisar bastante, eu mesmo não conheço nenhum.</p>
<p>No mundo desktop, o normal nas últimas décadas são os teclados de membrana porque são os mais baratos de fabricar. Basicamente imagine uma placa grande embaixo, com uma matriz onde os cruzamentos seriam as teclas. Nesses cruzamentos tem traços, que estão abertos, ou seja, não fecham o circuito. Em cima dessa placa coloca-se uma manta de silicone ou borracha, que é a tal membrana. Essa membrana é impressa com o layout de onde fica cada tecla e nessas posições tem os rubber dome, ou domo de borracha, com um material condutor que quando você pressiona o domo pra baixo, ele encosta na placa e fecha o circuito daquela tecla. Finalmente, você fecha o teclado com uma frame ou corpo de plástico e encaixa as teclas nos buracos. Pronto, esse é o tipo de teclado mais barato e mais difundido.</p>
<p>Esse tipo de teclado é super porcaria. O que mantém as teclas pra cima é a resistência desse material borrachudo. Claro, a qualidade dos materiais vai variar de fabricante pra fabricante. No caso dos notebooks, a maioria não usa mais membranas, daí os domos de borracha são individuais em cada tecla, mas o conceito é parecido. Mas você vê que a maioria dos notebooks de 1000 dólares pra cima tem chassis mais rígidos, teclas mais estáveis, estabilização adequadas em teclas maiores como barra ou return e, principalmente, a qualidade do domo de borracha que não faz parecer que você tá apertando uma borracha escolar porcaria.</p>
<p>Na faixa acima dos 50 dólares eu acredito que a maioria das marcas mais conhecidas como a Logitech fazem teclados suficientemente bons. Não vão ser mecânicos como os que vou mostrar, nada excepcional, mas melhores que a porcaria que eu acabei de mostrar. A tal porcaria aliás é mais pro segmento de quem quer ligar um teclado numa smart TV pra achar um filme no Netflix mais fácil ou coisas bem curtas assim, não pra digitações longas. Dai qualquer coisa vai ser melhor que ficar usando as setinhas do controle remoto pra digitar num teclado virtual na TV.</p>
<p>Agora que falamos do mais porcaria, vamos pros modelos mecânicos que vocês querem ver. Este aqui foi um dos meus primeiros teclados mecânicos da última década. Importei faz uns 5 anos e este teclado é da faixa de uns 150 dólares. E como podem ver, este eu usei até que bastante. A marca na lateral já quase desapareceu e a impressão de várias teclas quase apagou. Esta versão 1.0 nem vende mais, o mais próximo seria o modelo 4C mas ele vem com teclas PBT e o meu provavelmente são teclas ABS ainda. Já já vou falar sobre PBT mas normalmente você sabe que as teclas são o mais barato ABS porque com o tempo ele vai ficando com essa aparência glossy brilhante de gordura ou sei lá.</p>
<p>Este Das Keyboard é alemão e parece uma construção alemã mesmo. Ele é sóbrio, super sólido, o chassi é de metal e tem zero flexionamento. Dá aquela impressão que se você bater com um martelo periga de trincar o martelo. Se você ver um teclado acima dos 100 dólares com chassi de plástico, fique longe. Aliás, eu não recomendo nenhum teclado dessa faixa de preço que tenha keycaps ABS. Mas como esse teclado é de uns 5 anos atrás, quando essa moda de mecânicos nem tinha começado, vou dar um crédito. Agora vamos ouvir um pouco essa belezinha.</p>
<p>(demonstração - daskeyboard - digitando)</p>
<p>Falando em alemão, claro, você ouviu bem: estes são os famosos switches Cherry MX Blue. Os mais barulhentos de todos, sendo tactile e clicky. A empresa Cherry existe desde os anos 50 mas foi na última década que ela se tornou internacionalmente famosa por causa dos seus switches. Vamos ver o raio X de um switch Cherry Blue. Ele requer 60 centinewtons que é quase 61 gramas de força pra descer os primeiros 2.2 milímetros pra fechar o circuito de um total de 4 milímetros de key travel. Ou seja, na teoria você não precisa descer os 4 milímetros. Eu não sou, mas sei que existem digitadores velozes que digitam super leve, só relando de leve nas teclas o suficiente pra descer os 2.2 milímetros sem marretar até o fim.</p>
<p>Na prática, eu diria que em switches Blue é bem difícil digitar leve assim porque 60 gramas é uma força considerável, pelo menos pros meus dedos, e o bump que dá esse clicky dificulta só relar na tecla de leve. Olhem com calma de novo, eu bem devagar, indo os primeiros 2 milímetros até o clicky e depois os 2 milímetros finais até o fim, notem como tem a primeira resistência até atingir os 60 gramas.</p>
<p>(das keyboard - 1 tecla devagar)</p>
<p>De qualquer forma o Blue é considerado um dos switches mais satisfatórios justamente por causa desse barulho. Eu pessoalmente já enjoei do barulho, que tem esse pitch mais agudo. Os switches Brown são tactile, com um leve bump mas sem esse click, e por isso o barulho é pouco mais grave e um pouco menos irritante. Vai de gosto, mas eu recomendo testar o Brown em vez de ir direto pra Blue se o barulho preocupa. Se você trabalha sozinho, em home office, e não tem mais ninguém do seu lado, tanto faz, mas é 100% de certeza que todo mundo vai se irritar com os Blue.</p>
<p>Dos switches que são tactile, os Blue são os que tem o som mais característico agudo. Daí você tem o Brown. Não só o som é diferente mas ele requer menos força, de 55 centinewtons em vez dos 60 do Blue pra chegar no acionamento ou actuation aos 2 milímetros em vez de 2.2 do Blue, embora ambos tenham os mesmos 4 milímetros totais de key travel pra bater as teclas até o final. Pra quem gosta de barulho mas também quer cansar menos em sessões longas de digitação, eu diria que o Brown é mais confortável. E é uma questão de gosto mas eu prefiro o som um pouco mais grave dos Brown do que o agudo dos Blue.</p>
<p>Saindo da categoria tactile você tem os lineares. E aí são vários modelos. O mais comum são os Cherry MX RED. Um exemplo razoável em custo benefício talvez seja como este meu Corsair K65 Vengeance. Esse é da faixa de 100 dólares e tem mais baratos como o K55 de 50 dólares mas também é um teclado de membrana e não mecânico. O meu K65 usa switches Cherry RED que são lineares. A diferença com o Blue é que ele não tem um ponto de acionamento com um bump, ele desce linearmente dos 2 milímetros do acionamento até o total de 4 milímetros. Vamos ouvir primeiro:</p>
<p>(digitação - Corsair K65)</p>
<p>Agora vamos ouvir bem devagar pra vocês verem que o switch em si não faz clicky. Só quando eu bato com força vocês ouvem.</p>
<p>(devagar - Corsair)</p>
<p>Este Corsair não é nada de excepcional mas é bem competente. O chassi dele é razoavelmente rígido, ou seja, você não consegue torcer ele e mesmo tentando apertar no meio, ele não afunda. Mas o que entrega pra mim que ele é da categoria um pouco mais barata são os keycaps. Notem que eles parecem de ABS, com os símbolos impressos por cima e que com o tempo vão ficar com aquela aparência de engordurado e com letras apagadas. Mas uma das vantagens de se usar switches Cherry MX é que eles meio que se tornaram um padrão, então você consegue encontrar kits de keycaps e escolher não só cores mas materiais melhores como PBT. E, por acaso, eu tenho aqui justamente um kit da própria Corsair com keycaps PBT doubleshot.</p>
<p>Agora é uma boa hora pra explicar a diferença. Pra começar eu fico falando keycaps mas tecla seria mais ou menos a mesma coisa. Enfim, keycaps ABS vocês já viram em todos os teclados que mostrei até agora. Tem mais porcaria que ABS, existem teclados super baratos que usam PVC, e eu ficaria longe desses. De qualquer forma ABS e PBT são acrônimos pro tipo químico diferente de plástico. ABS quer dizer em português Estireno de acrilonitrila-butadieno e PBT quer dizer Tereftalato de polibutileno. Na prática, são tipos diferentes de plástico, só que PBT é um de melhor qualidade, mais caro, mas tem o que engenheiros chamam de estabilidade dimensional, o que quer dizer que deforma menos sob pressão do que ABS ou PVC. E como basicamente você vai querer marretar essas teclas todos os dias, você gostaria de um material de maior qualidade.</p>
<p>Mais do que isso, muitos kits de keycaps PBT são também double shot, ou seja, eles são feitos com duas camadas de PBT e você pode ver olhando por baixo. Isso normalmente quer dizer que a camada de cima é vazada onde tem a letra e a camada branca de baixo preenche esse vazado. Ou seja, a letra nunca vai sumir porque não é uma impressão de tinta por cima e sim a segunda camada de PBT por baixo. E normalmente esse PBT debaixo é semi-transparente, daí muitos fabricantes colocam LED no switch e com isso você tem backlight que ilumina a letra.</p>
<p>Por causa desse processo você entende que maior qualidade significa usar switches melhores como os da Cherry, com keycaps doubleshot, com chassi de metal, e vão custar naturalmente mais caro. Mais do que isso, ABS e PVC tem um barulho diferente de PBT. ABS tem um som mais de “plástico barato” mesmo e PBT é um som mais cheio e mais robusto, um pouco mais grave também, parte por ser mais denso e mais pesado. Compare os dois lado a lado, o mesmo teclado da Corsair com os keycaps ABS originais &hellip;.. e agora trocando pras teclas PBT doubleshot.</p>
<p>(som - corsair trocando teclas)</p>
<p>Eu acho que teclas PBT tem som mais assertivo, a estabilidade das teclas um pouco mais pesadas é melhor, eles costumam ter uma textura diferenciada que não dá sensação dos dedos escorregarem, e no geral a sensação é bem mais satisfatória, só que agora ele deixou de ser um teclado de 100 dólares e pulou pra categoria de 150 dólares. Então de fato você recebe o que paga.</p>
<p>De qualquer forma, não quer dizer que as teclas ABS sejam totalmente ruins. Muitos notebooks caros usam teclas de ABS. Além disso você sempre pode começar com um teclado com um bom chassi e bons switches e depois pagar 50 dólares ou menos e pedir um kit de keycaps PBT doubleshot como nesse exemplo que mostrei agora. Assim você inicia investindo 100 dólares e depois consegue dar um upgrade.</p>
<p>Nessa mesma faixa dos 100 dólares da Corsair costuma estar outra marca que por alguma razão eu tendo a colocar na mesma categoria, que é a Cooler Master. E por causa da história dos switches bugados butterfly surgiram modelos de diversas marcas tentando trazer um pouco do perfil mais low profile de teclados como os antigos magic keyboards. Se você já usou um teclado da Apple da era de 2015 pra trás, vai lembrar que os de desktop eram muito parecidos com os dos macbooks. Low profile quer dizer frame menos espesso, teclas achatadas tipo chiclete, com pouco key travel, na faixa de 1 milímetro ou menos.</p>
<p>Daí eu vi a Cooler Master lançando o modelo SK630 que usa switches Cherry MX low profile que é um switch um pouco diferente dos demais porque tem o menor key travel de todos, com apenas 1.2 milímetro. E por cima disso a Cooler Master construiu keycaps flat, retos e finos com espessura da ordem de meio centímetro. Então esse SK630 parece uma versão mecânica dos antigos magic keyboard da Apple. Se você gosta desse estilo de keycaps finos e retos talvez esta seja uma boa alternativa. Esses switches parecem Red mais finos que precisam de 45 centiNewtons de força. Os keycaps em si parecem ser PBT doubleshot e acho que vale comparar o barulho dele com o Corsair com os novos keycaps PBT lado a lado também.</p>
<p>(comparação cooler master - corsair pbt)</p>
<p>Diferente do Corsair o material do frame é um pouco pior. Ele tem um pouco de torção e inclusive não é perfeitamente horizontal, dá impressão que tem uma leve curvatura. Se você procura o um teclado mecânico mais fino, com uma cara mais de Mac, esse é um candidato. E diferente do Corsair, este tem até RGB. Pelo mesmo preço eu diria que é algo a se considerar. No começo eu não gostei muito das teclas retas, mas é rápido de se acostumar e dá pra digitar rápido nela também. Mas tem um grande porém, se o objetivo for um teclado verdadeiramente low profile, esta primeira tentativa da Cooler Master talvez não seja a melhor. Eu não tenho, mas a Keychron tem o modelo K1 que é tecnicamente mais low profile do que este então vale a pena conferir no site deles.</p>
<p>Note que até aqui eu só estou comparando os materiais e qualidade de construção. Numa discussão de teclados, existem mais características como as que eu mencionei no começo do video, incluindo customização de macros, baixo input lag, anti-ghosting ou n-key rollover e mais. Isso faz mais diferença pra gamers profissionais que treinam pra serem competitivos em campeonatos. Um jogador profissional de Starcraft consegue fazer de 500 a 800 comandos por minuto; obviamente pra ele faz diferença um input lag milissegundos menor e que as teclas registrem corretamente sem ghosting, ou seja, você pode apertar várias teclas ao mesmo tempo e todas elas vão ser registradas corretamente.</p>
<p>Agora a realidade, pra mim, ou pra maioria de vocês que digitam textos normais como e-mails ou código de programação, dificilmente vão notar um teclado que não tenha todas as funcionalidades de gamers. Teclado gamer não é só RGB como eu já disse. De jeito nenhum, se o input lag for alto ou se tiver ghosting, ele não presta pra gamers. Mas pra digitação normal, você não vai notar tanto assim.</p>
<p>Mas uma funcionalidade que pra mim faz diferença apesar de não ser gamer é a qualidade do switch. Pra um gamer é importante o switch ser mais leve e com ponto de acionamento mais curto, portanto um key travel menor, pra que você possa registrar mais comandos, mais rápido e a tecla ter uma distância menor pra voltar pra posição de reset. E por isso dizem que switches lineares como os Cherry MX Red são mais voltados pra gamers. Por outro lado, pelas mesmas razões eu considero os lineares melhores pra mim que costumo digitar razoavelmente rápido. Eu disse que gamers profissionais fazem de 500 a 800 comandos por minuto? Digitadores velozes conseguem chegar em 400 toques por minuto ou mais, então estão perto da mesma faixa.</p>
<p>Recapitulando, eu disse que switches Blue tem força de acionamento de 60 centinewtons e 2.2 milímetros de pre-travel do total de 4 milímetros até bater no final. Já os Cherry MX RED requerem 25% menos força, ou seja, 45 centinewtons e tem pre-travel de 2 milímetros. Por si só, switches lineares são mais silenciosos que os Blue ou Brown. O switch em si não faz nenhum barulho, só a tecla batendo no chassi que faz. Além deles existem as variantes Silent Red e Speed Silver, ambos requerem os mesmos 45 centinewtons de um Red mas o pre-travel de um Speed Silver cai quase pela metade, pra 1.2 milímetro com key travel total de 3.4 milímetros em vez dos 4 do Blue. Na prática eu não conseguiria distinguir um Red de um Silent Red, mas um Speed Silver já dá pra sentir diferença.</p>
<p>Esse key travel curto começa a entrar no território de um notebook Thinkpad, mas precisando só de cerca de metade da força. Mas não existem só switches da Cherry. Diversos fabricantes começaram a desenvolver seus próprios switches pra se diferenciar e realmente otimizar o caso de uso de gamers. Um bom exemplo é a Razer, marca que é comumente associada com gamers. Os teclados de fato são bons. Não vou dizer o mesmo dos fones de ouvido mas eu acho que gamers não precisam de nenhuma Senheiser, B&amp;O ou Bose pra jogar Fortnite, eles só precisam de microfones pra dar uma xingada em alto e bom som. Mouses eu prefiro os da Logitech como o G502.</p>
<p>Por acaso, eu tenho dois modelos de Blackwidow da Razer. Um com switches Green que são semelhantes aos Cherry Blue e os Yellow que são lineares similares aos Cherry Red. Pois é, a Razer não quis deixar super óbvio com as cores. Vamos colocar ambos lado a lado pra vocês verem a diferença de novo de um switch tactile e outro linear do mesmo fabricante, no mesmo modelo de teclado.</p>
<p>(comparativo - razer green e yellow)</p>
<p>Vocês vão notar que ambos os teclados tem praticamente as mesmas especificações técnicas. Os chassis são de metal, os keycaps são PBT doubleshot, eles tem backlighting RGB customizáveis, e a única coisa diferente são os switches mesmo. Diferente da Corsair ou mesmo meu antigo Das Keyboard é que você imediatamente sente que tá digitando em uma construção super sólida. Nada nele balança, é tudo firme.</p>
<p>De novo, depende muito do seu gosto pelo som clicky do Razer Green ou menos barulho no caso do Razer Yellow. Quando eu uso o Green dá pra ouvir constantemente o distinto clicky agudo semelhante ao do Cherry MX Blue. Porém quando se usa o Yellow linear, você sente mais o barulho do keycap mais denso de PBT contra um chassi rígido quando a tecla chega até o fim. Em termos de switches, pode parecer heresia mas eu diria que prefiro a configuração da Razer mais que os Cherry originais.</p>
<p>O Green da Razer, comparado ao Blue da Cherry, requer menos força de acionamento, em vez dos 60 centinewtons ele precisa só de 50, então é um pouco mais leve até do que o Cherry Brown. E em vez de ter que descer 2.2 milímetros pra acionar, o Green precisa só de 1.9 milímetros. Exatamente porque a Razer foca em gamers, ele refinou o estilo tactile clicky de um Cherry Blue pra precisar de menos força. Já o Yellow da Razer é parecido com o Speed Silver da Cherry precisando dos mesmos 45 centinewtons de força de acionamento e tendo um pre-travel curto de 1.2 milímetro que é quase metade do Cherry Blue. Ou seja, são switches que de fato são mais voltados pra competição, focando em conseguir registrar mais comandos por minutos exigindo menos força e menos key-travel do que os Cherry.</p>
<p>Repetindo, eu não sou gamer competitivo, mas eu acho que os switches lineares com key travel menor que 2 milímetros são melhores pra digitadores rápidos e nesse caso o Razer Yellow é muito mais próximo do Cherry MX Speed Silver do que do Red. Digitar no Corsair com switches Cherry Red é bem rápido pra mim, mas o Blackwidow com switches Yellow da Razer são uma boa competição. Ambos são bons e rápidos mas a construção mais robusta da Razer pra mim é mais satisfatória.</p>
<p>Falando de switches diferentes, um concorrente que eu diria que é pau a pau com essa solidez do Razer Blackwidow é o Logitech G Pro. Pra começar, ele é um pouco mais barato que o Blackwidow Chroma V2 que custa hoje uns 140 euros e o G Pro custa 130 euros. E essa diferença de 10 euros é perceptível. Na ponta dos dedos me dá a impressão dos keycaps da Razer serem mais sólidos, mas isso talvez seja porque no G Pro quando você bate a tecla até o fim o som é levemente mais abafado e no Blackwidow você tem um som um pouco mais metálico no fim. Na prática o G Pro é mais silencioso do que o Blackwidow. Se colocarmos lado a lado você deve sentir a diferença:</p>
<p>(compare blackwidow vs g pro)</p>
<p>A Logitech tem alguns conjuntos de switches diferentes. A mais próxima da Cherry é a série GX que tem GX Blue, Brown e Red que mais ou menos se aproximam do Cherry Blue, Brown e Red respectivamente. Diferente da Razer a Logitech preferiu seguir as mesmas cores. Mas o que eu tenho aqui é o Romer-G Linear. Comparado aos GX ele requer menos força de acionamento de 45 gramas e um pre-travel de só 1.5 milímetros. Portanto ele também é quase comparável a um Cherry Speed Silver ou Razer Yellow.</p>
<p>Pra usar no escritório eu tenho preferido o G Pro justamente por ser um pouco mais silencioso no geral que o Corsair K65 ou o Razer Blackwidow. A construção do chassi e dos keycaps parecem mais balanceados pra abafar barulho. Ele não chega a ser totalmente silencioso, mas em comparação ele é bem mais suave e o que menos incomoda pessoas ao redor. O Cooler Master que mostrei antes também é silencioso mais ou menos no mesmo nível do G Pro.</p>
<p>Mesmo se você escolher um switch linear que, por si só praticamente não faz barulho no acionamento da tecla, ainda assim a ação de bater a tecla até o fim faz barulho. Daí depende muito do material dos keycaps e da construção do chassi. Ser de metal ajuda na rigidez mas também pode aumentar o barulho. Se você escolhe um switch tactile clicky como o Cherry Blue, isso só adiciona som extra. Em qualquer dos casos, você pode escolher diminuir o som do switch e dessa batida da tecla usando um O-Ring. São super baratos e basicamente são pequenos anéis de borracha que você coloca embaixo do keycap, então ele ao mesmo tempo serve de amortecedor pra diminuir o som da batida e também diminui o key travel, fazendo com que ele seja mais curto. Se estiver usando o Cherry Blue ainda vai ter um clicky mas ele vai ser menos irritante e o som no geral vai ser menor. Então é outra opção que talvez você queira experimentar.</p>
<p>Enfim, depois que eu migrei pra switches lineares um colega me falou de uma marca que eu nunca tinha ouvido falar, a Matias e o teclado Matias Quiet Pro que, segundo seu website clama, é o teclado mais silencioso do mundo. O design dos switches é mais inspirado nos switches Alps do que na Cherry e, de fato, é um teclado silencioso, ouçam comparado com o G Pro:</p>
<p>(matias comparado com G Pro)</p>
<p>O switch deles tem 60 gramas de força de acionamento e key travel total de 3.5 milímetros, o que coloca ele em território dos Cherry Brown. De fato, se eu for simplesmente pelo mais silencioso esse é de longe um dos mais quietos, mesmo se comparado com o G Pro que eu acabei de dizer que é bem silencioso.</p>
<p>Porém a 130 dólares não dá pra recomendar. Pra começar o corpo do teclado é de plástico e não um que me inspira muita confiança. Diferente da Cooler Master que pelo menos tenta ser mais fino, esse ainda é gordão. Não é algo que você consegue torcer fácil nem afundar, mas ao digitar você sente que tá digitando em cima de algo que parece mais oco e menos rígido. Os keycaps também são de ABS, com as letras impressas em cima, ou seja, é questão de tempo até ele ficar glossy e as letras apagarem. Fora isso, não tem backlight. Eu não faço questão de RGB mas uma luz branca faz falta especialmente porque eu gosto de digitar a noite com pouca luz. E esse teclado é um 75% o que significa que tem muitas teclas importantes com funções duplicadas, por exemplo, o Home é o Page Up com a tecla de function, o End é o Page Down com a tecla function.</p>
<p>Aliás, é uma boa hora pra falar de tamanhos de teclado. O tamanho grande ou full-size é aquele mais parecido com o layout original de um IBM antigo, com a coluna do meio com teclas de navegação como home, end, page up e down e a terceira coluna da direita com o teclado numérico, que eu imagino que nenhum contador consiga viver sem. Eu comecei como programador num teclado full-size dos anos 90 mas eu nunca fui particularmente rápido no numérico e com o passar dos anos eu nunca precisei gastar muitas horas preenchendo planilhas ou algo assim, então pra mim não faz falta.</p>
<p>Mais do que isso, quando eu uso um teclado centralizando só a parte das letras com o meio da tela, significa que meu braço vai ter que esticar muito pra direita pra usar o mouse, e isso cansa mais o braço. Eu prefiro ter o mouse mais próximo. Por isso também teclados de gamers tendem a ser pelo menos tenkey-less, sem numérico, pra ter mais espaço pra fazer movimentos longos de mouse. Em particular pra gamers de FPS, quanto mais espaço tiver na direita pro mouse melhor, por isso existem até teclados que são só a metade da esquerda que é onde normalmente você mapeia navegação, strafe e outros comandos e você raramente usa as teclas do lado direito. Assim você duplica o espaço pra movimentar o mouse.</p>
<p>Se eu quiser ir ao extremo existem os layouts 60% ou até mesmo 40% que, como os nomes dizem são 60% ou 40% do tamanho de um full-size. O 60% não tem a segunda coluna de teclas de navegação, então coisas como seta, page up e tudo mais precisa apertar uma combinação de function e alguma outra tecla. Pior, não existe a linha de teclas de função em cima das teclas de número, as teclas F1 a F12, então muitas vezes a tecla Esc que fica no começo dessa linha tem que descer e ficar do lado da tecla 1, e com isso a tecla que normalmente fica lá que é til e backtick não existe e você precisa usar uma combinação de teclas.</p>
<p>Pra digitar português onde você acaba precisando do til, isso é extremamente cansativo. Navegar usando combinação de teclas também é cansativo. Eu realmente não recomendo. Na dúvida eu ficaria num tamanho abaixo do full-size que é o chamado TKL ou tenkey-less, ou seja, é um teclado full-size sem a parte numérica da direita. Todos os teclados que mostrei até agora, incluindo o Blackwidow, G Pro, Corsair foram Tenkeyless.</p>
<p>Porém este Matias Quiet Pro que estou mostrando é um tamanho abaixo disso, de 75%, ou seja, ele retém a linha de teclas de função que tem o Esc no lugar certo, mas retém só metade das teclas de navegação, onde algumas precisam ser combinações de teclas, mas no mínimo tem as setas. Se você digita num editor de programação como Sublime, VS Code ou Vim, consegue remapear facilmente pra outras teclas como “h j k l” e não chega a ser totalmente ruim, mas se como eu precisa navegar por telas de Word ou Google Docs, ou mesmo no caso de editar vídeos, realmente é desconfortável sem ter setas ou um home e end. Por isso só recomendo layouts abaixo de 75% se você realmente passar 90% do seu tempo só em código ou games.</p>
<p>Existe até layouts absurdos como 40% que se livra da linha de teclas de número em cima do qwerty. Mas pra mim isso já é mais exibicionismo e tem zero praticidade no dia a dia. De novo, se o que você mais faz é games, talvez não faça diferença. Como uma curiosidade, um segundo teclado pra brincar ou algo assim, pode ser legal. Se o objetivo for um teclado que seja fácil de transportar na mochila, pra trabalhar de verdade, então no máximo um 65% wireless é mais que suficiente. E sim, eu sei, alguns poucos entusiastas se forçam a gostar desses layouts minúsculos, mas eu acho que pra maioria das pessoas não compensa o esforço pra ganhar alguns poucos centímetros na mochila.</p>
<p>O Matias Quiet Pro é um teclado realmente silencioso como diz a propaganda mas cujos materiais não condizem com o preço. Se ele custasse menos de 100 dólares talvez, mas a 130 eu prefiro já ir pro Blackwidow ou G Pro que tem materiais e acabamentos muito superiores por uma diferença pequena de preço.</p>
<p>O último switch diferente que eu queria mostrar hoje é uma peça que você precisa importar da Ásia, e são os switches Topre. O original é da marca RealForce e o modelo que vocês estão vendo é o RealForce 87 U  fabricado no Japão. Só por causa disso eu não posso recomendar esse modelo porque dependendo do frete o preço final pode chegar a absurdos 500 dólares, nos Estados Unidos. Você consegue achar outros fabricantes como a Leopold da Coréia do Sul ou a Ducky de Taiwan que dentre outros switches também oferece modelos com Topre. Aliás, a grande maioria dos teclados que estou mostrando hoje e no próximo video são importados, então varia frete e impostos. Marcas mais famosas como Corsair, Razer e Logitech você tem mais chance de encontrar por aqui. Vai variar caso a caso então só pesquisando mesmo. Fucem Mercado Livre e Aliexpress antes.</p>
<p>Eu comprei o meu pela Amazon e em 2018 já custou salgados 270 dólares mais o frete pra cá e por sorte não caiu em tributação quando chegou, se não me engano. E vai custar caro mesmo, porque vem do Japão. Se comparado ao Matias ele é beeem melhor construído. Mas a qualidade de construção da Razer ou Logitech ainda é superior. O layout é tenkeyless o que torna ele bem mais confortável pra usar no dia a dia. Uma coisa que me incomoda nele é que além de não ter backlight o design é letras escuras em cima de keycaps pretos, então se for comprar recomendo a versão clara.</p>
<p>O correto de fato é digitar sem olhar e normalmente eu faço isso mesmo. Comparado ao Matias que é um 75% isso me incomoda menos aqui porque eu não preciso ficar lembrando quais combinação de teclas que é home ou end, mas por esse preço eu ia gostar de ter um backlight. De qualquer forma a motivação toda pra se comprar um RealForce são os switches.</p>
<p>Tecnicamente os switches Topre não são mecânicos. Na realidade eles são rubber dome. Lembra o que eu expliquei no começo sobre domos de borracha? A diferença é que debaixo do domo existe uma mola também, o que oferece uma resistência e retorno melhor. Diferente de um rubber dome ou mesmo membrana, o Topre você não precisa bater até o fim pra registrar. Mas diferente dos Cherry o ponto de acionamento é bem mais alto, mais no começo da batida em vez de ser no meio. Então dá sensação que você faz uma força inicial maior com um acionamento no alto e depois disso a resistência do domo é mais leve do que nos mecânicos e você vai até o fim rápido. O meu requer 55 gramas de força mas como o acionamento é bem mais no começo, me dá impressão de estar digitando num switch mais pesado que o Cherry Blue ou Black.</p>
<p>Eu falei no começo sobre o teclado do Thinkpad que é um scissor switch normal mas com um key travel maior de 78 gramas de força de acionamento. Tanto o Thinkpad quando este RealForce são os que mais cansam meus dedos em sessões longas. É importante notar que eu estou mais acostumado com switches lineares de 45 gramas, por isso a diferença é muito gritante e é mais uma questão de adaptação. Também depende da sua mão. Mãos maiores que as minhas vão ter bem menos problema com switches mais pesados como esses.</p>
<p>Em termos de barulho, os switches em si são silenciosos. Ele tem o bump de um switch tactile como o Brown e assim como ele não tem o clicky de um Blue. De novo, o barulho maior é da tecla batendo até o fim no chassi e não do switch em si. O som geral é levemente mais emborrachado, mais contido e suave, lembrando mais o Matias. Mas diferente dos de membrana normais, ele é assertivo o suficiente pra ser satisfatório e não parece que você tá apertando uma borracha escolar em cima de plástico barato.</p>
<p>Falando em plástico, os keycaps são bem duros encaixado nos switches e eu não consegui tirar nem com a pinça, também preferi não forçar porque não sei se o mecanismo quebra se forçar, mas pela aparência, pela textura que não escorrega e aparente rigidez, me parece que são keycaps de PBT. Então, se você por acaso estiver pela Ásia, procure por teclados com switches Topre, no mínimo vale testar porque a sensação é muito diferente dos mecânicos normais.</p>
<p>E por hoje chegamos ao fim. Ainda tem mais teclados, vou guardar os mais interessantes pra Parte 2. Resumindo, em termos de switches você tem os Cherry MX, Blue e Brown se quiser uma tecla com um bump na hora de apertar e um clicky no caso do Blue ou os lineares como Red ou Speed Silver se quiser algo mais leve e mais rápido. Switches Gateron ou Kaihua são bons clones compatíveis e vou mostrar exemplos no próximo episódio.</p>
<p>Marcas mais mainstream como Razer Blackwidow ou Logitech G Pro são ótimas opções na faixa dos cento e pouco dólares se quiser algo com uma construção mais sólida e switches resistentes e confiáveis como os da Cherry, mas mais voltados pra velocidade e gamers, que eu pessoalmente prefiro. Modelos igual ou acima do K65 da Corsair podem ser uma opção um pouco mais barata e igualmente satisfatórios mas um pouco mais barulhentos pelos materiais usados.</p>
<p>Como sempre, não façam perguntas simples que um Google pode responder. Eu achei todos esses teclados sem ler um único fórum, foi aos poucos, pesquisando sobre cada switch, sobre cada marca, um a um ao longo de 5 anos. E lembrando que dos quase 30 anos de carreira só nesses últimos 5 eu comecei a comprar esse tipo de teclados. Quer dizer que nos primeiros 10 a 15 anos eu usei teclados de membrana mais porcaria que tinha porque era o que dava pra comprar. E nem por isso eu programei pior ou mais devagar. Assim como um carro de corrida, primeiro você precisa aprender a ser piloto pra tirar o máximo que o máquina pode entregar. Antes disso qualquer coisa serve. De qualquer forma não deixem de mandar um joinha se curtiram o video, assinem o canal e cliquem no sininho pra não perder a parte 2. Compartilhem o video pra ajudar o canal. A gente se vê na parte 2, até mais!</p>
]]></content:encoded><category>teclados</category><category>hardware</category><category>reviews</category><category>akitando</category></item><item><title>[Akitando] #14 - Consertando The Last Jedi</title><link>https://akitaonrails.github.io/2018/09/27/akitando-14-consertando-the-last-jedi/</link><guid isPermaLink="true">https://akitaonrails.github.io/2018/09/27/akitando-14-consertando-the-last-jedi/</guid><pubDate>Thu, 27 Sep 2018 17:00:00 -0300</pubDate><description>&lt;p&gt;Disclaimer: esta série de posts são transcripts diretos dos scripts usados em cada video do canal &lt;a href="https://www.youtube.com/channel/UCib793mnUOhWymCh2VJKplQ"target="_blank" rel="noopener"&gt;Akitando&lt;/a&gt;. O texto tem erros de português mas é porque estou apenas publicando exatamente como foi usado pra gravar o video, perdoem os errinhos.&lt;/p&gt;
&lt;div class="embed-container"&gt;
&lt;iframe
src="https://www.youtube.com/embed/3Y3BPty_a5E"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3&gt;Descrição no YouTube&lt;span class="hx:absolute hx:-mt-20" id="descrição-no-youtube"&gt;&lt;/span&gt;
&lt;a href="#descri%c3%a7%c3%a3o-no-youtube" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The Last Jedi é um assunto que vai ser eternamente controverso, mas hoje não vou entrar na discussão mas sim elencar o que nós fãs não gostamos e ir um passo além, mostrar como os fãs estão consertando esse e outros erros da história de Star Wars.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Disclaimer: esta série de posts são transcripts diretos dos scripts usados em cada video do canal <a href="https://www.youtube.com/channel/UCib793mnUOhWymCh2VJKplQ"target="_blank" rel="noopener">Akitando</a>. O texto tem erros de português mas é porque estou apenas publicando exatamente como foi usado pra gravar o video, perdoem os errinhos.</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/3Y3BPty_a5E"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<h3>Descrição no YouTube<span class="hx:absolute hx:-mt-20" id="descrição-no-youtube"></span>
    <a href="#descri%c3%a7%c3%a3o-no-youtube" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>The Last Jedi é um assunto que vai ser eternamente controverso, mas hoje não vou entrar na discussão mas sim elencar o que nós fãs não gostamos e ir um passo além, mostrar como os fãs estão consertando esse e outros erros da história de Star Wars.</p>
<p>Links:</p>
<ul>
<li>Harmy&rsquo;s Star Wars: Despecialized Edition - History &amp; Sources Documentary (extended version) (<a href="https://www.youtube.com/watch?v=mGrXO2RDzLg"target="_blank" rel="noopener">https://www.youtube.com/watch?v=mGrXO2RDzLg</a>)</li>
<li>Star Wars Despecialized Edition is Awesometacular! (<a href="https://www.youtube.com/watch?v=ZTRbkIBn2j0"target="_blank" rel="noopener">https://www.youtube.com/watch?v=ZTRbkIBn2j0</a>)</li>
<li>How Star Wars was saved in the edit (<a href="https://www.youtube.com/watch?v=GFMyMxMYDNk"target="_blank" rel="noopener">https://www.youtube.com/watch?v=GFMyMxMYDNk</a>)</li>
</ul>
<h2>Script<span class="hx:absolute hx:-mt-20" id="script"></span>
    <a href="#script" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Olá pessoal, Fabio Akita</p>
<p>Esta semana o tema é geek. Terça eu falei sobre como consertar Justice League e hoje o tema é o hiper controverso The Last Jedi. Vamos ver como consertar esse erro.</p>
<p>(&hellip;)</p>
<p>Star Wars é uma enorme dor de cabeça. O maior problema é que dependendo da sua idade você vai ter opiniões muito diferentes. Por exemplo, se você só começou a assistir recentemente, talvez a partir de Force Awakens, não vai entender tanto porque tantos fãs odiaram The Last Jedi.</p>
<p>Talvez você tenha começado pelos Prequels e séries de TV como Clone Wars e Rebels. Nesse caso sua base de comparação já fica diferente. Aqui você talvez fique em cima do muro com relação à nova trilogia.</p>
<p>Mas se você é da geração que começou com a trilogia original e veio assistindo a evolução desde o começo, é onde a nova trilogia realmente vai começar a irritar.
Eu sou dessa geração, eu tenho memórias de quando Return of Jedi tava nos cinemas. Eu fiquei horas sentado na fila do cinema quando Phantom Menace foi lançado, tendo esperado de 1983 até 1999, a expectativa era grande e o filme foi uma grande decepção.
Maldito Jar Jar Binks. Mas pelo menos gastei boas horas em corridas de pod racing com o game de PC Episode I: Racer.</p>
<p>Attack of the Clones melhorou bastante. Finalmente ganhamos o que queríamos ver: uma história um pouco melhor, muitas lutas de lightsabers, embora a parte do romance tenha sido bem ruim na época e continua sendo agora.
Revenge of the Sith é o melhor dos filmes dessa trilogia, de longe. Apesar de várias inconsistências pra ligar com a trilogia original, poder ver o nascimento de Darth Vader era o que queríamos ver e isso ficou até que bom, tirando o famigerado “nooooo” no final.</p>
<p>Isso foi em 2005, daí tivemos a série de TV The Clone Wars e em 2012 a Disney compra a Lucas Film. George Lucas sai de cena e entra Kathleen Kennedy na liderança. A primeira bola dentro foi trazer J.J. Abrams pra iniciar uma nova trilogia. J.J. é realmente bom, eu gosto muito do trabalho dele.
Nunca fui fã de Lost mas o soft reboot que ele fez em Mission Impossible 3 eu gostei bastante. Pra quem não lembra, MI:2 foi o pior filme da franquia e é no 3 que se cria a estrutura que vai evoluindo em Ghost Protocol, Rogue Nation e agora Fallout.
Eu também gostei muito do reboot de Star Trek nos cinemas. Eu nunca fui um trekkie nem nunca tentei aprendi Klingon, mas J.J foi extremamente bem sucedido em tornar Star Trek acessível de novo pra uma nova geração.
E quando eu vi Force Awakens eu não fiquei muito impressionado mas pelo menos não fiquei decepcionado, a última coisa que eu Não queria era ter de novo a mesma sensação de Phantom Menace.
Todo mundo sabe que ele preferiu jogar seguro, seguiu beat por beat os pontos de A New Hope e mandou até que bem em criar novos personagens que atiçaram a curiosidade sobre o que poderia vir a frente com Finn, Rey, Snoke, Kylo.</p>
<p>Mas aí a direção passou pra mão de Rian Johnson e The Last Jedi sofre por 2 razões: J.J. deixou muitas arestas soltas que provavelmente não tinha uma visão maior por trás. Ou seja, ele deixou muitas expectativas pra resolução. Rian herdou esses problemas.
E em cima disso quis colocar muitas tangentes que arrastam a narrativa do filme.
No geral, depois de 1 ano, eu meio que já engoli a maioria dos pontos que eu não gostei de imediato. Eu acho que o maior problema é justamente porque tecnicamente falando The Last Jedi é a melhor produção de um filme Star Wars que já foi feito.
A sequência do sacrifício de Holdo o ataque surpresa na velocidade da luz é de longe um dos melhores momentos no cinema, ponto. Foi perfeito.
E aí você tem pontos horrorosos como Canto Bight. Esse desbalanço que destrói o filme.
Eu também fui um dos que passou os últimos 2 anos especulando sobre Snoke e os pais de Rey. E não ter essas respostas até que não foi tão ruim assim tanto quanto Canto Bight
, Maz Kanata fazendo um call no meio de uma luta aleatória qualquer só pra soltar uma informação que não serve pra nada.
Casting de um Benicio Del Toro num personagem que na prática não serviu pra nada.
Repetir o erro de Force Awakens de não fazer nada de útil com a capitã Phasma e desperdiçar o personagem de novo. Não fazer nada de útil com o Finn e no final cortar o climax do nada sem motivo.
Eu fui um dos que mudei de opinião e até entendo melhor a idéia do Luke cínico anti-herói nesse filme. Mas o arco principal da história ser a perseguição mais lenta da galáxia com as piadas mais forçadas arrebentou esse filme.</p>
<p>Procure no YouTube e vai encontrar centenas de vídeos descrevendo item a item tudo que não funciona nesse filme, e é uma pena porque se ele passasse por uma segunda revisão de edição acho que ele ficaria bem aceitável.
E aí vem a recomendação de hoje, o canal do YouTuber Ivan Ortega. Ele é um mexicano-americano que resolveu consertar o problema.
Faz alguns meses que ele pegou o filme e vem reeditando no Adobe Premiere todos os pontos que todo mundo odiou no filme.</p>
<p>O cara tá fazendo mágica nessa edição. Ele consertou literalmente TODOS os pontos do filme que dava pra mudar com edição. E vocês vão ficar surpresos como edição é fundamental num filme.
Quem conhece a história de Star Wars sabe que o primeiro corte do A New Hope original fez o filme ficar ruim. Ninguém gostou, Spielberg não gostou, De Palma não gostou. Aliás Brian De Palma ajudou a reescrever o texto de introdução do filme, que originalmente era longo demais. Mas quem salvou o filme foi a mulher de George Lucas, Marcia Lucas que voltou pra mesa de edição e fez um novo corte do mesmo filme. A edição de Marcia transformou um filme que era objetivamente horroroso num dos maiores clássicos da história do cinema. E é uma excelente lição para lembrar que juntar um monte de partes boas num saco não faz o saco ficar bom.
Por isso saber o que cortar fora, mudar a ordem das coisas, pode fazer toda a diferença e isso vale pra filme, pra música, pra dissertações e textos em geral, e até mesmo pra código - que é um dos motivos de porque making of de filmes me atraem tanto.</p>
<p>Ivan Ortega parece entender bem isso e ele vai além. Me preocupa um pouco como vai ficar no final mas ele vai redublar algumas falas do filme com pessoas que conseguem imitar as vozes de personagens como Luke.
Ele tá treinando uma coreografia de pra ele mesmo fazer uma pequena tomada extra da luta entre Kylo Ren e Luke
e ele parece que conseguiu mesmo trocar Holdo da icônica tomada do sacrifício e trazer ninguém menos que o General Ackbar, que aos olhos de muitos incluindo eu, foi totalmente desperdiçado nesse filme.</p>
<p>Só dele conseguir diminuir e diluir a longa e cansativa cena de Canto Bight já é um enorme ganho.
Ele conseguiu reverter a piada do Luke jogando o light saber fora.
Ele conseguiu reverter um monte de coisa só na edição. O cara é bom. E ele acabou de lançar um teaser trailer pra indicar que finalizou o corte final. Assinem o canal dele pra saber quando sai o filme reeditado completo.</p>
<p>Essa não é a primeira vez que os fãs fazem algo assim. No anos 90 George Lucas resolveu reeditar os filmes da trilogia original. Ele adicionou um monte de computação gráfica muito ruim e mudou coisas importantes dos originais como a famigerada cena onde Han Solo atirou primeiro.
Esses foram os Special Edition. O problema é que hoje você só tem acesso a essas versões adulteradas.
Não existe mais a versão original da trilogia. Eu assisti a original em VHS e em DVD antes das Special Edition. Alguns anos atrás um grupo de fãs se juntou pra procurar as versões originais e fazer o processo de “remasterização” que significava limpar frame a frame do filme pra preservar como era a versão original.
Acho que o projeto era Star Wars Revisited e tem Empire Strikes Back Revisited. Eu não achei mais os links do projeto original mas coloquei na descrição os links que encontrei, se alguém tiver links melhores não esqueça de compartilhar com a gente.</p>
<p>E tudo isso são evidências de como o Head Honcho da Marvel Studios Kevin Feige tá fazendo um trabalho hercúleo. Nem a Lucas Film da própria Disney, nem a Warner Bros tão conseguindo criar e manter um universo coeso.
O que Feige conseguiu fazer, desde Iron Man em 2008 até Infinity War esse ano é um acontecimento histórico. Mas o que eu queria mostrar nesse vídeo também é um pequeno gosto da comunidade geek.</p>
<p>Diferente de áreas mais explicitamente artísticas como quadrinhos ou filmes, como programador eu também me considero de uma profissão criativa. Criatividade não é copiar e colar as coisas, é aprender o máximo possível de gente talentosa pra inspirar a melhoria nas nossas próprias técnicas.
No mínimo, todo geek de verdade tem como característica comum a dedicação em cima do que gosta. Quando eu penso em código, penso da mesma forma como Nando reimaginando a estrutura de um filme ou Ivan reeditando um blockbuster nas madrugadas. É assim que nós geeks fazemos.</p>
<p>E aí, gostaram desse vídeo? Discutam os temas de hoje nos comentários abaixo. Mande um joinha, assinem o canal e não deixem de clicar no sininho pra não perder os próximos episódios. A gente se vê na próxima, até mais.</p>
]]></content:encoded><category>cinema-e-cultura-pop</category><category>reviews</category><category>akitando</category></item><item><title>[Akitando] #13 - Consertando Justice League</title><link>https://akitaonrails.github.io/2018/09/25/akitando-13-consertando-justice-league/</link><guid isPermaLink="true">https://akitaonrails.github.io/2018/09/25/akitando-13-consertando-justice-league/</guid><pubDate>Tue, 25 Sep 2018 17:00:00 -0300</pubDate><description>&lt;p&gt;Disclaimer: esta série de posts são transcripts diretos dos scripts usados em cada video do canal &lt;a href="https://www.youtube.com/channel/UCib793mnUOhWymCh2VJKplQ"target="_blank" rel="noopener"&gt;Akitando&lt;/a&gt;. O texto tem erros de português mas é porque estou apenas publicando exatamente como foi usado pra gravar o video, perdoem os errinhos.&lt;/p&gt;
&lt;div class="embed-container"&gt;
&lt;iframe
src="https://www.youtube.com/embed/1aB1CEvnLk4"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3&gt;Descrição no YouTube&lt;span class="hx:absolute hx:-mt-20" id="descrição-no-youtube"&gt;&lt;/span&gt;
&lt;a href="#descri%c3%a7%c3%a3o-no-youtube" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Esta semana vamos pra temas geek. Hoje vamos olhar um pouco a trajetória de Justice League até ele implodir e em vez de só criticar mostrar soluções que outros geeks youtubers chegaram pra resolver esse problema.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Disclaimer: esta série de posts são transcripts diretos dos scripts usados em cada video do canal <a href="https://www.youtube.com/channel/UCib793mnUOhWymCh2VJKplQ"target="_blank" rel="noopener">Akitando</a>. O texto tem erros de português mas é porque estou apenas publicando exatamente como foi usado pra gravar o video, perdoem os errinhos.</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/1aB1CEvnLk4"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<h3>Descrição no YouTube<span class="hx:absolute hx:-mt-20" id="descrição-no-youtube"></span>
    <a href="#descri%c3%a7%c3%a3o-no-youtube" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Esta semana vamos pra temas geek. Hoje vamos olhar um pouco a trajetória de Justice League até ele implodir e em vez de só criticar mostrar soluções que outros geeks youtubers chegaram pra resolver esse problema.</p>
<p>Links:</p>
<ul>
<li>Batman v Superman: What Went Wrong? – Wisecrack Edition (<a href="https://www.youtube.com/watch?v=467ehoaGDaE"target="_blank" rel="noopener">https://www.youtube.com/watch?v=467ehoaGDaE</a>)</li>
<li>Civil War v Justice League: Dawn of Character Development (Video Essay) (<a href="https://www.youtube.com/watch?v=nVEatk78mQQ"target="_blank" rel="noopener">https://www.youtube.com/watch?v=nVEatk78mQQ</a>)</li>
<li>Justice League Reshoots: Every Change Whedon Made To Snyder&rsquo;s Film (<a href="https://screenrant.com/justice-league-movie-reshoot-changes-explained-snyder-whedon/5/"target="_blank" rel="noopener">https://screenrant.com/justice-league-movie-reshoot-changes-explained-snyder-whedon/5/</a>)</li>
</ul>
<h2>Script<span class="hx:absolute hx:-mt-20" id="script"></span>
    <a href="#script" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Olá pessoal, Fabio Akita</p>
<p>Esta semana vamos mudar um pouco os temas. Quero falar um pouco sobre filmes. Dois em particular, Justice League hoje e o espinhoso The Last Jedi na quinta. Dois dos mais controversos filmes do ano passado, duas das principais decepções em termos de blockbusters.</p>
<p>Vocês já devem ter ouvido e assistido todo tipo de crítica em torno desses filmes. Com os rumores da negociação com Henry Cavill alguns dias atrás colocando em risco a continuidade do Superman. E o cancelamento da nova trilogia Star Wars que o Rian Johnson ia iniciar - graças aos céus …</p>
<p>No episódio de hoje quero falar um pouco sobre Justice League e como consertar essa bagunça.</p>
<p>(&hellip;)</p>
<p>Esse filme estava fadado a dar errado. Todo mundo acompanhou o stress durante as filmagens. Zack Snyder fez um filme que todo mundo gosta, os 300 adaptado da obra homônima de Frank Miller. Provavelmente a adaptação de um graphic novel que entregou as melhores frases feitas na história dos blockbusters.
Pra mim ainda é o melhor papel de Gerard Butler e foi a primeira vez que prestei atenção em Lena Hedley antes dela virar Cersey em Game of Thrones.</p>
<p>Snyder foi um passo além e fez uma adaptação até que não tão ruim do lendário Watchmen de Alan Moore. É outro filme que não foi tão bem nas bilheterias mas eu particularmente gosto como filme. Em particular pontos pelo casting de Jeffrey Dean Morgan como The Comedian e em manter o tema do “Big Joke” e isso deve ser por causa do screenplay de David Hayter, que como bônus de curiosidade, pra quem gosta da série de games Metal Gear do lendário Hideo Kojima, todos sabem que David Hayter é a eterna voz de Solid Snake.</p>
<p>Com boas credenciais, Snyder ganhou as chaves do universo DC e começou com Men of Steel que não foi completamente ruim, tem idéias que eu até gosto, em particular a caracterização de um Superman menos perfeito.
O problema disso é a sequência em Batman v Superman, onde um Superman humanizado fica muito próximo do Batman e isso acaba com o propósito da história em si, ao contrário do tema da graphic novel The Dark Knight Returns de Frank Miller, que serviu de inspiração pra muitas das cenas, e onde a lendária batalha entre Batman e Superman é uma batalha filosófica entre individualismo e coletivismo, como bem analisou o canal Wisecrack, que você pode assistir clicando no link acima.</p>
<p>Então entramos em Justice League. A pressão em cima da Warner Bros tava no máximo. Muito stress interno. O script original de Snyder, com ajustes de Geoff Johns não tava bom. Foi quando trouxeram Joss Whedom pra reescrever cenas inteiras. E tudo isso com a produção em andamento. Fora acontecimentos aleatórios como o famigerado Mustache-gate por conta das refilmagens que acontecerem ao mesmo tempo que Missão Impossível 6.
Curiosidade pra quem não lembra, todo mundo tirou sarro que tiveram que tirar a barba do Henry Cavill em pós-produção via computação gráfica porque a Paramount não queria deixar ele tirar a barba pras refilmagens. Mas aí depois disso um dos stunts do Tom Cruise deu errado e ele se machucou feio e as filmagens ficaram paradas um tempão de qualquer jeito.
No final ia dar tempo do Cavill tirar a barba, refilmar o Superman pro Justice League e esperar a barba crescer de novo até o Cruise se recuperar. Coisas de Hollywood.
Aliás, se você não assistiu MI:6 assista, é o melhor filme da série e de longe um dos melhores blockbusters de ação da atualidade.</p>
<p>Enfim. No frigir dos ovos o filme Justice League virou uma bagunça. A história ficou ruim. A direção ficou ruim. Acabaram usando muito mal todos os personagens. Whedom mudou tanto o filme original que muitos clamam para o lançamento do cut original do Snyder. Eu não esperaria muito desse cut também depois de Batman v Superman.</p>
<p>A Warner teve um tiro de sorte com Wonder Woman, que apesar de ser um filme mais ou menos, com um 3o ato bem ruim e um desperdício de vilão principal, conseguiu uma boa diretora em Patty Jenkins que acertou na química entre Gal Gadot e Chris Pine, sem o qual o filme também teria sido esquecível.</p>
<p>Os próximos filmes, pelo menos pelos trailers, parece finalmente estar acertando. O filme do Aquaman de James Wan parece perfeito nos trailers, ponto positivo pra personagem Mera de Amber Heard. Wan que aliás vem fazendo filme bom atrás de filme bom, desde Saw, Insidious, Conjuring, Furious 7.
E claro o novo filme Shazam também parece muito promissor no trailer, com David Sandberg também tendo filmes de horror no currículo, como o último Annabelle: Creation e Lights out.
Eu definitivamente não sou fã de filmes de horror, pelo fato de que 99% são muito mal feitos. Mas Wan e Sandberg eu mantenho na minha lista de interesse.
Aliás, significa também que em 2019 vamos ter 2 filmes de Capitães Marvel. O original que é Shazam e a Capitã Marvel, da Marvel.</p>
<p>Isso tudo dito, o que fazer com Justice League? Aqui vem a graça do YouTube. Muita gente já tentou ajustar o filme de alguma forma, mas o que eu mais gostei até agora é a recente série do canal Nando v Movies.
Uma das melhores coisas que o Nando faz no canal é reimaginar a história de filmes. Em particular eu gosto como ele se atém à fundação da arte de escrever um screenplay.
Até o momento em que estou gravando este episódio ele lançou 3 vídeos da série “Justice League Rewrite”.
Ele está se atendo em dividir a história nos 3 atos clássicos. E dando mais atenção ao 2o ato, que ele dividiu em 2 partes, tradicionalmente chamados de 2A e 2B separado pelo que chamam de “midpoint” o meio do filme.
Por exemplo, o Nando lembra como os filmes da Marvel seguem exatamente essa estrutura e como eles tem midpoints muito bem definidos, em First Avenger, Steve Rogers salta do avião e se torna Capitão América exatamente no meio do filme, em Winter Soldier Steve Rogers e Natasha descobrem que a Hydra infiltrou a Shield e encontram Zola no meio do filme e assim por diante.</p>
<p>Esse cara é muito talentoso, a forma como ele explica as razões pra cada uma das mudanças, a forma como ele encaixa as peças no framework clássico de um bom filme, e como tudo faz sentido, faz você assistir essa nova versão na cabeça como se fosse um filme de verdade. O cara é assim bom.
Pra dar um gosto, um dos maiores problemas da história é Steppenwolf, que é um dos vilões mais fracos de todos os filmes de heróis ever. Então ele faz um twist, ele inicia com a Liga dos Vilões, trazendo Clayface, Deathstroke, Copperhead, Weather Wizard e cria um sub-arco no 1o ato que vai ligar no twist do novo midpoint.
E à medida que ele reajusta a história também reajusta o relacionamento dos personagens, criando uma das coisas que falta no filme de verdade: uma conexão entre todos os membros da Liga. Por exemplo, copiando o graphic novel de Frank Miller eles colocam vários easter eggs na batcaverna, incluindo o uniforme do 2o Robin, provavelmente, Jason Todd.
Mas eles não aproveitam o medo de Bruce em trazer pra equipe um moleque como o atual Flash, Barry Allen e não explorar o trauma de poder repetir o que aconteceu com Robin de novo. Nando corrige isso na sua versão.</p>
<p>Falando no Flash, me lembrou um video essay de outro canal, o HiTop Films que ainda tá no começo mas eles fazem análises muito boas de pontos específicos em alguns filmes, em particular um de 6 meses atrás onde eles comparam a introdução e recrutamento do Flash em Justice League comparado com uma cena muito similar em Civil War onde o Stark vai recrutar o Peter Parker, no que é a primeira aparição do homem aranha no universo marvel atual. Colocando lado a lado é gritante como as cenas são idênticas mas porque o da Marvel é eficaz e o da DC perde a oportunidade.</p>
<p>Dêem uma olhada na versão do Nando e mandem nos comentários o que acharam das mudanças que ele fez. E se vocês conhecem algum YouTuber que imaginou uma versão ainda melhor, também mandem pra eu ver.</p>
<p>Não tem coisa mais divertida pra um geek do que reimaginar as coisas. Acho que uma das coisas que separam os geeks dos não-geeks é que a maioria das pessoas assiste filmes mas não pensa muito a respeito, são aquelas 2 horas, dá uma risada e amanhã já era. A gente que é geek é estranho mesmo, anos depois ainda estamos falando em detalhes dos filmes, defeitos técnicos, cenas deletadas, histórias dos bastidores, versões alternativas. Mas essa é a parte que eu acho mais divertido.</p>
<p>E aí, gostaram desse vídeo? Discutam os temas de hoje nos comentários abaixo. Mandem um joinha, assinem o canal e não deixem de clicar no sininho pra não perder os próximos episódios. A gente se vê na próxima, até mais.</p>
]]></content:encoded><category>cinema-e-cultura-pop</category><category>reviews</category><category>akitando</category></item><item><title>Arch Linux: A Melhor Distro de Todas</title><link>https://akitaonrails.github.io/2017/01/10/arch-linux-a-melhor-distro-de-todas/</link><guid isPermaLink="true">https://akitaonrails.github.io/2017/01/10/arch-linux-a-melhor-distro-de-todas/</guid><pubDate>Tue, 10 Jan 2017 14:25:00 -0200</pubDate><description>&lt;p&gt;&lt;strong&gt;Atualização 18/01/2017:&lt;/strong&gt; Se você está num hardware antigo como o meu, talvez queira otimizar a instalação para ter muito mais responsividade. &lt;a href="http://www.akitaonrails.com/2017/01/17/otimizando-o-linux-para-computadores-lentos"target="_blank" rel="noopener"&gt;Leia tudo sobre isso aqui&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Quando decidi voltar do macOS para o Linux, não queria simplesmente retornar ao velho Ubuntu (sim, fico entediado fazendo as mesmas coisas por tempo demais). Então experimentei o Fedora 25 e fiquei impressionado com a evolução do Gnome 3.22.&lt;/p&gt;
&lt;p&gt;Comparado ao Ubuntu, os padrões do Fedora pareciam melhores. Na prática, dá para forçar qualquer distro a ser o que você quiser, mas prefiro não brigar com os padrões. O Ubuntu é fortemente customizado para o Unity e eu realmente, realmente não gosto. Parece mais um brinquedo do que um ambiente sério para trabalhar.&lt;/p&gt;</description><content:encoded><![CDATA[<p><strong>Atualização 18/01/2017:</strong> Se você está num hardware antigo como o meu, talvez queira otimizar a instalação para ter muito mais responsividade. <a href="http://www.akitaonrails.com/2017/01/17/otimizando-o-linux-para-computadores-lentos"target="_blank" rel="noopener">Leia tudo sobre isso aqui</a>.</p>
<p>Quando decidi voltar do macOS para o Linux, não queria simplesmente retornar ao velho Ubuntu (sim, fico entediado fazendo as mesmas coisas por tempo demais). Então experimentei o Fedora 25 e fiquei impressionado com a evolução do Gnome 3.22.</p>
<p>Comparado ao Ubuntu, os padrões do Fedora pareciam melhores. Na prática, dá para forçar qualquer distro a ser o que você quiser, mas prefiro não brigar com os padrões. O Ubuntu é fortemente customizado para o Unity e eu realmente, realmente não gosto. Parece mais um brinquedo do que um ambiente sério para trabalhar.</p>
<p>O Fedora 25 fica bonito com o Gnome 3, mas ainda me deu algumas dores de cabeça. Uma coisa que não funcionou de jeito nenhum foi o <a href="https://wiki.gnome.org/Projects/GnomeOnlineAccounts"target="_blank" rel="noopener">Gnome Online Accounts</a>. O GOA coleta tokens de autenticação depois que você faz login nos seus serviços sociais como o Google. Aí aplicativos compatíveis como Evolution e o Calendário integrado conseguem usá-los. Mas os tokens expiravam o tempo todo, então a integração era inútil. E configurar o Evolution manualmente para o Google não é nada agradável.</p>
<p><img src="https://akitaonrails.s3.amazonaws.com/assets/image_asset/image/584/Screenshot_from_2017-01-10_14-15-41.png" alt="Arch Linux"  loading="lazy" /></p>
<p>A surpresa: no Arch Linux, escolhi o Gnome 3.22 como desktop e instalei manualmente o pacote <a href="https://www.archlinux.org/packages/extra/i686/gnome-online-accounts/"target="_blank" rel="noopener">gnome-online-accounts</a>. Fiz login nas minhas contas Google e posso afirmar com satisfação que os tokens não expiram e tudo &ldquo;simplesmente funciona&rdquo;! É esse tipo de polimento que espero de uma distro grande, não a roubada que o Fedora rotula como &ldquo;estável&rdquo;.</p>
<h3>Por que Arch Linux?<span class="hx:absolute hx:-mt-20" id="por-que-arch-linux"></span>
    <a href="#por-que-arch-linux" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>A maioria das distros importantes se divide entre &ldquo;estável&rdquo; (mas com pacotes muito antigos) e &ldquo;instável&rdquo; (mas com o que há de mais recente). Se você instala as versões Long-Term Support (LTS), está condenado a ter só pacotes velhos de alguns anos atrás. Se instala os repositórios instáveis, está condenado a ter coisas explodindo na sua cara sem explicação e perdendo horas garimpando no Stackoverflow.</p>
<p>O Arch parece ter encontrado o nível exato de equilíbrio entre estável e cutting-edge. Ele continua empurrando as versões mais recentes dos softwares sem quebrar tudo o mais o tempo todo. No Ubuntu 16.04 e no Fedora 25, se eu quero instalar o Postgresql, fico preso no 9.4 ou 9.5, mas no Arch consigo acessar o 9.6 direto dos repositórios principais do Pacman. (A propósito, &ldquo;Pac&quot;kage &ldquo;Man&quot;ager é o nome mais óbvio possível.)</p>
<p>É só fazer <code>pacman -Sy postgresql</code> e pronto.</p>
<p>E se você está no Ubuntu 14.04 e agora quer o 16.04, boa sorte fazendo <code>dist-upgrade</code>. É mais fácil começar do zero.</p>
<p>A filosofia do Arch parece ser ter a versão mais recente de verdade de todo software sem quebrar o sistema. Não existe aquele upgrade big bang a cada 6 meses que quebra tudo. Em vez disso, você tem um sistema de upgrade <strong>rolling</strong> constante, sempre na última versão, sem precisar esperar mais um ano pelo próximo LTS grande.</p>
<p>Toda distro grande tem repositórios &ldquo;não suportados&rdquo; para binários proprietários (codecs, por exemplo) ou software de terceiros. No Arch existe o Arch User Repository (AUR): uma coleção de pequenos repositórios Git de usuários que mantêm simples arquivos de texto <code>PKGBUILD</code>.</p>
<p>O AUR é inteligente. Se você vem do macOS e conhece o Homebrew, vai entender na hora: parece Casks e Formulas. Um arquivo <code>PKGBUILD</code> pode descrever uma receita para baixar um pacote DEB ou tarball disponível, desmontá-lo e reconstruí-lo como um pacote compatível com o Pacman. Ele pode descrever as dependências necessárias e tornar o processo de instalação extremamente tranquilo.</p>
<p>Por exemplo, o Sublime Text só tem a opção de baixar um pacote DEB ou um tarball com os binários. O mesmo vale para Spotify, Franz, etc. Às vezes dá para registrar Personal Package Archives (PPAs) e instalar via <code>apt-get</code>. Mas você ainda precisa que alguém construa, mantenha e distribua esses pacotes direito. Dá muito trabalho.</p>
<p>Manter um repositório Git simples com um arquivo PKGBUILD simples é muito mais fácil. O <code>makepkg</code> faz o trabalho pesado de construir o pacote que você precisa, na sua máquina, e então o <code>pacman</code> cuida de instalá-lo como qualquer outro pacote. Chega de ficar baixando tarballs com <code>wget</code> e configurando tudo na mão!</p>
<p>Talvez eu finalmente consiga só fazer <code>pacman -Syu</code> e ter tudo &ldquo;de verdade&rdquo; atualizado sem precisar me preocupar com o próximo LTS grande que eventualmente vai me forçar a reinstalar tudo do zero.</p>
<h3>Arch Linux é perfeito para &ldquo;Iniciantes&rdquo;<span class="hx:absolute hx:-mt-20" id="arch-linux-é-perfeito-para-iniciantes"></span>
    <a href="#arch-linux-%c3%a9-perfeito-para-iniciantes" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Faz um bom tempo que ouço falar do Arch e seus usuários são muito entusiastas em tentar convencer outras pessoas a aderir. Quando você vê uma base de fãs tão leal assim, alguma coisa interessante deve estar escondida por baixo. Upgrades rolling, Pacman, AUR são razões realmente valiosas.</p>
<p>Depois de apenas um dia usando, percebi que o Arch é bom para usuários avançados, mas também para <strong>iniciantes</strong>. Não porque é fácil. Pelo contrário: porque é difícil do jeito certo.</p>
<p>A maioria dos &ldquo;usuários Linux&rdquo; hoje em dia só pega uma distro trivial de instalar, como Ubuntu ou Elementary, e não faz ideia do que acontece por baixo. Ficam clicando cegamente em &ldquo;próximo&rdquo; nos instaladores gráficos.</p>
<p>A maioria das pessoas não sabe o que são TTYs. Que você pode sondar dispositivos USB com ferramentas de linha de comando como <code>lsusb</code>, ou que precisa usar ferramentas como <code>fdisk</code> para particionar e depois <code>mkfs.ext4</code> para formatar. Que arquivos de swap de memória são partições com um formato especial. Não conhecem as opções de LVM para particionamento flexível, nem que o LVM existe. Que o &ldquo;negócio&rdquo; que você escolhe o kernel no menu de boot se chama Grub e que dá para tunear.</p>
<p>Montar uma distribuição Linux completamente funcional tem muito envolvido. Mas os instaladores gráficos escondem a maior parte. O Arch Linux te força a ir passo a passo e realmente sentir que você é dono da sua máquina, e não o contrário.</p>
<p>Se você é um &ldquo;iniciante&rdquo;, eu realmente te encorajo a instalar uma distro como o Arch algumas vezes, em diferentes configurações de máquinas, para entender de verdade como um sistema operacional funciona.</p>
<p>A <a href="https://wiki.archlinux.org/"target="_blank" rel="noopener">Arch Wiki</a> é um repositório de informações muito abrangente e detalhado sobre tudo que você precisa saber para instalar e manter cada componente de um sistema Linux adequado. Você vai aprender muito no processo.</p>
<p>Mas se você é como eu, e passou por tudo isso em meados dos anos 90 e início dos 2000 (puxa, eu tive que aprender Slackware 1.0 na marra, ainda me lembro de usar disquetes de boot e root e estragar meus HDs sem entender cilindros e setores no fdisk), pode pular essa parte. Para você, usuário avançado/experiente, eu recomendo o <a href="https://arch-anywhere.org/"target="_blank" rel="noopener">Arch Linux Anywhere</a>.</p>
<p><img src="https://akitaonrails.s3.amazonaws.com/assets/image_asset/image/586/big_20170109_150742.jpg" alt="Arch Anywhere"  loading="lazy" /></p>
<p>Ele instala o Arch de forma customizada mas com automação suficiente para não desperdiçar muito tempo em ter uma instalação Arch devidamente configurada e funcionando, sem bloatware.</p>
<h3>Pacaur - a melhor forma de lidar com o AUR<span class="hx:absolute hx:-mt-20" id="pacaur---a-melhor-forma-de-lidar-com-o-aur"></span>
    <a href="#pacaur---a-melhor-forma-de-lidar-com-o-aur" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Os usuários de Arch são rápidos em elogiar o Pacman. Na maior parte do tempo, você basicamente faz:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo pacman -S chromium</code></pre></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 é isso. Depois pode fazer <code>sudo pacman -Syu</code> para atualizar os pacotes instalados. Esse é o básico que você precisa saber.</p>
<p>Se você é desenvolvedor, recomendo instalar também os pacotes de desenvolvimento básicos:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo pacman -Sy --needed base-devel</code></pre></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>Você pode instalar pacotes do AUR manualmente. Pode ir ao site deles e <a href="https://aur.archlinux.org/packages/?O=0&amp;K=terminix"target="_blank" rel="noopener">buscar por &ldquo;terminix&rdquo;</a> (um substituto bem interessante para o Terminal, parecido com o iTerm2 do Mac), por exemplo. Vai chegar a <a href="https://aur.archlinux.org/packages/terminix/"target="_blank" rel="noopener">esta página</a> e precisará fazer manualmente o seguinte:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>git clone https://github.com/gnunn1/terminix.git
cd terminix
makepkg -si</code></pre></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 simples, mas dá para fazer melhor instalando o <a href="https://github.com/rmarquis/pacaur"target="_blank" rel="noopener">Pacaur</a>, um wrapper em cima do Pacman. Se você estiver usando um terminal gráfico como Terminal ou Terminix, NÃO ESQUEÇA de editar o perfil para &ldquo;Run command as login shell&rdquo;, caso contrário haverá um problema de PATH e o Cower vai falhar na instalação.</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo pacman -S expac yajl --noconfirm
gpg --recv-keys --keyserver hkp://pgp.mit.edu 1EB2638FF56C0C53
git clone https://aur.archlinux.org/cower.git
cd cower
makepkg -si
cd ..
git clone https://aur.archlinux.org/pacaur.git
cd pacaur
makepkg -si
cd ..</code></pre></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>Em resumo, o Pacaur pode ser usado não só como complemento para instalar pacotes do AUR, mas também se você quiser usar uma única ferramenta para gerenciar tanto o AUR quanto os pacotes oficiais do Pacman. Todos os comandos <code>-S</code> são comandos do Pacman. Então em vez de fazer <code>sudo pacman -Syu</code> para atualizar todos os pacotes, você pode substituir por <code>pacaur -Syu</code>. Todo o resto basicamente &ldquo;funciona&rdquo;.</p>
<p>Quando você tenta instalar um pacote com <code>-S</code>, ele primeiro procura nos repositórios oficiais; se não encontrar, tenta o AUR. Tem até uma GUI bem bacana se quiser:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>pacaur -S pamac-pacaur</code></pre></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 instalar o mesmo Terminix agora, basta fazer:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>pacaur -Sy terminix</code></pre></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 vai fazer perguntas simples de sim/não como &ldquo;Quer editar o arquivo de build?&rdquo; Responda &ldquo;n&rdquo; para essas e confirme &ldquo;y&rdquo; quando perguntar se quer instalar as dependências ou o pacote gerado.</p>
<p>E é isso! Você pode buscar nos repositórios do AUR com:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>pacaur -s spotify</code></pre></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>Vai te dar várias opções, por exemplo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>$ pacaur -s spotify
aur/spotify 1.0.47.13-1 (1037, 36.09) [installed]
    A proprietary music streaming service
aur/playerctl 0.5.0-1 (127, 11.33)
    mpris media player controller and lib for spotify, vlc, audacious, bmp, xmms2, and others.
aur/blockify 3.6.3-3 (106, 5.61)
    Mutes Spotify advertisements.
...</code></pre></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>Bom senso, pessoal. Leia, interprete, escolha. O Arch exige que você seja uma pessoa <strong>inteligente</strong>, e por &ldquo;inteligente&rdquo; quero dizer: que sabe ler! A maioria das pessoas pula a leitura e fica clicando em tudo como idiota.</p>
<p>Agora que você sabe o nome exato do pacote que quer, instale normalmente assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>pacaur -S spotify</code></pre></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><img src="https://akitaonrails.s3.amazonaws.com/assets/image_asset/image/604/Screenshot_from_2017-01-16_14-21-49.png" alt="Pacaur"  loading="lazy" /></p>
<p>O Pacaur é um dos muitos <a href="https://wiki.archlinux.org/index.php/AUR_helpers"target="_blank" rel="noopener">AUR Helpers</a>. Inicialmente fui atraído pelo Yaourt, mas depois de pesquisar, você percebe que deve experimentar apenas aurutils, bauerbill ou pacaur. Prefiro este último porque é mais fácil de falar.</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>pacaur -Syua</code></pre></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>Isso mantém o seu sistema atualizado, tanto os pacotes oficiais quanto os do AUR.</p>
<h3>Asdf - o último gerenciador de versões de linguagens que você vai precisar<span class="hx:absolute hx:-mt-20" id="asdf---o-último-gerenciador-de-versões-de-linguagens-que-você-vai-precisar"></span>
    <a href="#asdf---o-%c3%baltimo-gerenciador-de-vers%c3%b5es-de-linguagens-que-voc%c3%aa-vai-precisar" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Se você é Rubyist, conhece RVM, rbenv, chruby. Se vem do Node.js, conhece o NVM inspirado no RVM para gerenciar diferentes versões do Node. Cada nova linguagem hoje em dia precisa de um gerenciador de versões porque evoluem rapidamente e porque se você trabalha com projetos de clientes vai eventualmente precisar usar uma versão antiga para lidar com software legado.</p>
<p>Então, mesmo que você possa instalar o Ruby 2.3.3 estável atual só fazendo <code>pacman -S ruby</code> ou <code>pacaur -S ruby</code>, vai eventualmente precisar voltar para Ruby 2.1 ou mais antigo para algum projeto de cliente.</p>
<p>Instala RVM? Ou rbenv? E como lidar com diferentes versões de Clojure, Go, Rust, Elixir?</p>
<p>Isso soa como mais um pesadelo de manutenção para encarar. Mas alguém decidiu resolver esse problema de forma elegante. Entra o <a href="https://github.com/asdf-vm/asdf"target="_blank" rel="noopener">asdf</a> - e se você por acaso conhecer <a href="https://github.com/HashNuke"target="_blank" rel="noopener">Akash Manohar</a>, dê um abraço nele.</p>
<p>Vamos instalá-lo (do README do projeto):</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.2.1</code></pre></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>Depois edite seus arquivos de configuração de shell:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># Para Ubuntu ou outras distros Linux
echo -e &#39;\n. $HOME/.asdf/asdf.sh&#39; &gt;&gt; ~/.bashrc
echo -e &#39;\n. $HOME/.asdf/completions/asdf.bash&#39; &gt;&gt; ~/.bashrc

# OU para Mac OSX
echo -e &#39;\n. $HOME/.asdf/asdf.sh&#39; &gt;&gt; ~/.bash_profile
echo -e &#39;\n. $HOME/.asdf/completions/asdf.bash&#39; &gt;&gt; ~/.bash_profile

# Para o Fish shell
echo &#39;source ~/.asdf/asdf.fish&#39; &gt;&gt; ~/.config/fish/config.fish
mkdir -p ~/.config/fish/completions; and cp ~/.asdf/completions/asdf.fish ~/.config/fish/completions

# Se, como eu, você gosta de ZSH com YADR (precisa instalar o YADR antes disso)
touch ~/.zsh.after/asdf.zsh
echo -e &#39;\n. $HOME/.asdf/asdf.sh&#39; &gt;&gt; ~/.zsh.after/asdf.zsh
echo -e &#39;\n. $HOME/.asdf/completions/asdf.bash&#39; &gt;&gt; ~/.zsh.after/asdf.zsh</code></pre></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>Essa ferramenta é bem auto-explicativa. Vamos começar instalando um monte de plugins (tabela completa de links no arquivo README):</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>asdf plugin-add clojure https://github.com/vic/asdf-clojure.git
asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir.git
asdf plugin-add erlang https://github.com/asdf-vm/asdf-erlang.git
asdf plugin-add golang https://github.com/kennyp/asdf-golang.git
asdf plugin-add ruby https://github.com/asdf-vm/asdf-ruby.git
asdf plugin-add rust https://github.com/code-lever/asdf-rust.git
asdf plugin-add nodejs https://github.com/asdf-vm/asdf-nodejs.git</code></pre></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ê é como eu, deve estar <strong>super animado</strong> porque já sabe o que vamos fazer a seguir:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo pacman -Sy jdk8-openjdk # precisa de Java para Clojure

asdf install clojure 1.8.0
asdf global clojure 1.8.0
mkdir ~/bin
wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein -O ~/bin/lein
chmod &#43;x ~/bin/lein
export PATH=$PATH:~/bin
# echo &#34;PATH=$PATH&#34; &gt; ~/.zsh.after/binpath.zsh # se usar YADR&#43;ZSH
lein

asdf install erlang 19.0
asdf global erlang 19.0

asdf install elixir 1.4.0
asdf global elixir 1.4.0
mix local.hex
mix local.rebar

asdf install golang 1.7.4
asdf global golang 1.7.4

asdf install ruby 2.4.0
asdf global ruby 2.4.0
gem install bundler

asdf install rust 1.14.0
asdf global rust 1.14.0

asdf install nodejs 7.4.0
asdf global nodejs 7.4.0
npm -g install brunch phantomjs</code></pre></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>Pronto! Agora temos todas as linguagens que precisamos instaladas e prontas para uso! E se eu precisar do Ruby 2.3.1 para um projeto de cliente?</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>asdf install ruby 2.3.1
asdf local ruby 2.3.1</code></pre></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 agora tenho o 2.3.1 localmente (posso mudar para o padrão do sistema usando <code>global</code>).</p>
<p>A maior parte do esforço de manutenção se resume a isso:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>asdf plugin-update --all # atualiza os plugins individuais
asdf list-all [linguagem] # lista todas as versões disponíveis</code></pre></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 é basicamente isso! Você tem quase tudo que precisa para desenvolver software.</p>
<h3>Software Útil para Instalar<span class="hx:absolute hx:-mt-20" id="software-útil-para-instalar"></span>
    <a href="#software-%c3%batil-para-instalar" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Agora, como de costume, deixa eu recomendar alguns softwares:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># garanta que está atualizado
sudo pacman -Syu

# instale codecs multimídia
sudo pacman -Sy gstreamer0.10-plugins
sudo pacman -Sy exfat-utils fuse-exfat a52dec faac faad2 flac jasper lame libdca libdv gst-libav libmad libmpeg2 libtheora libvorbis libxv wavpack x264 xvidcore gstreamer0.10-plugins flashplugin libdvdcss libdvdread libdvdnav gecko-mediaplayer dvd&#43;rw-tools dvdauthor dvgrab pulseaudio-equalizer-

# se precisar de fontes japonesas como eu
sudo pacman -Sy adobe-source-han-sans-otc-fonts otf-ipafont

# alguns componentes que você vai precisar
sudo pacman -Sy fuse-exfat 

# gosto do tema Numix e ícones Breeze, mude-os com o Tweak Tool
sudo pacman -Sy numix-themes breeze-icons 

# instale mais fontes com boa aparência
sudo pacman -Sy ttf-dejavu 
pacaur -S ttf-ms-fonts ttf-vista-fonts ttf-liberation adobe-source-sans-pro-fonts ttf-ubuntu-font-family

# Firefox e plugin Java
sudo pacman -Sy icedtea-web firefox

# para devs
sudo pacman -Sy zsh the_silver_searcher gvim imagemagick htop
pacaur -Sy ttf-hack

# Wrapper nativo para apps Web como Slack, Hangout, etc
pacaur -Sy franz-bin

# Melhor cliente nativo de Twitter para Linux
pacaur -Sy corebird

# Dispensa explicação
pacaur -Sy spotify
pacaur -Sy sublime-text-dev # instale estes plugins http://www.hongkiat.com/blog/sublime-text-plugins/

# Se você gosta de ler RSS
pacaur -Sy feedreader-beta

# se precisar de suporte tipo Office
sudo pacman -Sy libreoffice-fresh

# se precisar de suporte tipo Photoshop
sudo pacman -Sy gimp
sh -c &#34;$(curl -fsSL https://raw.githubusercontent.com/doctormo/GimpPs/master/tools/install.sh)&#34;

# se quiser um editor de vídeo realmente bom
sudo pacman -Sy frei0r-plugins dvdauthor vlc
pacaur -Sy kdenlive

# isso pode fazer softwares que consomem muito CPU se comportarem melhor e garantir melhor experiência de uso
pacaur -Sy ananicy-git

# dropbox é o software mais horrível do mundo, mas pode ser que você precise:
pacaur -Sy dropbox dropbox-cli nautilus-dropbox</code></pre></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>Como sempre, gosto de substituir o Bash pelo Zsh e configurar o Vim com YADR:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sh -c &#34;`curl -fsSL https://raw.githubusercontent.com/skwp/dotfiles/master/install.sh`&#34;
touch ~/.vimrc.before
touch ~/.vimrc.after
echo &#34;let g:yadr_using_unsolarized_terminal = 1&#34; &gt;&gt; ~/.vimrc.before
echo &#34;let g:yadr_disable_solarized_enhancements = 1&#34; &gt;&gt; ~/.vimrc.after
echo &#34;colorscheme gruvbox&#34; &gt;&gt; ~/.vimrc.after</code></pre></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 instalar e configurar o Postgresql 9.6:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo pacman -Sy postgresql
sudo -u postgres -i
initdb --locale $LANG -E UTF8 -D &#39;/var/lib/postgres/data&#39;
exit

# não faça isso em máquinas de Produção
sudo sed -i.bak &#39;s/ident/trust/&#39; /var/lib/postgres/data/pg_hba.conf
sudo systemctl start postgresql
sudo systemctl enable postgresql

sudo -u postgres -i
createuser --interactive # crie com seu nome de usuário e papel de superuser
createdb youruser
exit
sudo systemctl restart postgresql</code></pre></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 quiser instalar o Docker:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo pacman -Sy docker
sudo usermod -aG docker $USER
sudo systemctl start docker
sudo systemctl enable docker
logout</code></pre></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>Sempre precisamos de Redis, Memcached, então vamos instalá-los:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo pacman -Sy redis memcached
sudo systemctl start redis
sudo systemctl enable redis
sudo systemctl start memcached
sudo systemctl enable memcached</code></pre></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>Depois de instalar e remover muito software, você pode acabar com pacotes desnecessários ocupando espaço em disco. Dá para limpar com:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo pacman -Rns $(pacman -Qtdq)</code></pre></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 como disse antes, a Arch Wiki é super útil para continuar ajustando o sistema, então leia artigos como <a href="https://wiki.archlinux.org/index.php/Improving_performance"target="_blank" rel="noopener">esta página &ldquo;Improving Performance&rdquo;</a>.</p>
<h3>Kernels para Desktop<span class="hx:absolute hx:-mt-20" id="kernels-para-desktop"></span>
    <a href="#kernels-para-desktop" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Uma coisa importante sobre a maioria das distros Linux é que o kernel geralmente é compilado para ser mais otimizado para Servidores.</p>
<p>Hardware moderno, especialmente com bastante RAM e equipado com SSD, &ldquo;deveria&rdquo; funcionar bem o suficiente. Mas nem sempre: você pode ter alguns &ldquo;engasgos&rdquo; ou até total falta de resposta.</p>
<p>Há muitas razões, mas os 2 principais culpados são a memória da aplicação sendo paginada para o swap em disco e o escalonador de I/O do kernel Linux.</p>
<p>Num cenário de servidor, você quer que os processos tenham uma fatia justa dos recursos, por isso um escalonador de processos como o CFS - Completely Fair Scheduler - e o CFQ - Complete Fairness Queueing - para I/O, são fantásticos.</p>
<p>Mas no Desktop a história é completamente diferente. Você está disposto a trocar alto throughput por baixa latência para ter responsividade. Ninguém quer ter a UI e o ponteiro do mouse congelados enquanto copia arquivos grandes para drives USB, ou enquanto espera aquele terrível <code>make -j9</code> terminar de compilar o seu igualmente terrível gcc-gcj. Pode terminar com a UI congelada por horas! Simplesmente inaceitável!</p>
<p>O que você quer para uso em Desktop, com dezenas de processos aleatórios fazendo operações aleatórias, é uma configuração quase de &ldquo;soft real time&rdquo;. Uma preempção mais agressiva onde o Kernel devolve algum controle para a UI para que você possa fazer outras coisas - embora mais devagar. Baixa latência é a chave para uma experiência de usuário fluida.</p>
<p>Para aumentar a responsividade, a primeira e mais importante coisa a fazer é configurar isto:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo tee -a /etc/sysctl.d/99-sysctl.conf &lt;&lt;-EOF
vm.swappiness=1
vm.vfs_cache_pressure=50
vm.dirty_background_bytes=16777216
vm.dirty_bytes=50331648
EOF</code></pre></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>Reinicie. Se quiser saber o que são essas configurações, <a href="https://rudd-o.com/linux-and-free-software/tales-from-responsivenessland-why-linux-feels-slow-and-how-to-fix-that"target="_blank" rel="noopener">leia isto</a>.</p>
<p>Você pode querer instalar um Kernel customizado com um Scheduler diferente. Existem 3 opções atualmente: <a href="https://aur.archlinux.org/packages/linux-zen-git/"target="_blank" rel="noopener">Zen</a>, <a href="https://liquorix.net/"target="_blank" rel="noopener">Liquorix</a> e <a href="https://aur.archlinux.org/packages/linux-ck/"target="_blank" rel="noopener">CK</a>.</p>
<p>Ainda não tenho 100% de certeza sobre qual é o melhor; todos têm algumas preocupações de manutenção.</p>
<p>Dos 3, você vai querer ficar com o Zen (que é <a href="https://github.com/zen-kernel/zen-kernel/issues/30#issuecomment-142787936"target="_blank" rel="noopener">basicamente o Liquorix</a>), pois é mantido nos repositórios oficiais em formato binário (acredite, você não quer esperar um kernel customizado compilar, leva uma eternidade).</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo pacman -Sy linux-zen
sudo grub-mkconfig -o /boot/grub/grub.cfg</code></pre></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>Reinicie.</p>
<p>A principal mudança é provavelmente o I/O Scheduler, passando do CFQ padrão para o BFQ. Se você usa HD mecânico vai querer usar o BFQ melhorado (que o Zen habilita por padrão). Se usa SSD vai querer &lsquo;deadline&rsquo; em vez disso.</p>
<p>NÃO INSTALE ESSES KERNELS EM SERVIDORES DE PRODUÇÃO! Eles são destinados apenas ao uso em desktop!</p>
<p>De modo geral, o Zen pode ter o melhor equilíbrio entre estabilidade e conjunto de ajustes. Vale usá-lo, especialmente em hardware mais antigo. Hardware moderno, como disse, pode não notar muita diferença.</p>
<h3>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Não sei se são os mantenedores do Arch que estão fazendo um trabalho excelente ou se são a RedHat e a Canonical que estão estragando tanto as distros deles em comparação.</p>
<p>Quer dizer, Ubuntu, Fedora, OpenSuse, Elementary são todas distros decentes que, na maioria das vezes, &ldquo;simplesmente funcionam&rdquo;.</p>
<p>Mas para uma distro que muitos consideram voltada a &ldquo;usuários avançados&rdquo;, o Arch é muito mais polido. Não consigo entender o porquê.</p>
<p>No mesmo hardware, a experiência com o Gnome 3 no Arch é visivelmente melhor do que o mesmo Gnome 3 no Fedora. Comparado ao Unity no Ubuntu, está milhas à frente. É rápido, fluido, com boa aparência, e os padrões todos funcionam bem.</p>
<p>E de repente percebo que não preciso mais me preocupar com grandes atualizações. Os upgrades rolling contínuos para o mais recente me trazem mais uma camada de confiança.</p>
<p>O Arch me faz sentir que estou no controle novamente sem exigir que eu perca horas ajustando coisas ao meu gosto. Os padrões são sólidos e consigo fazer pequenas melhorias quando preciso.</p>
<p>Parabéns aos mantenedores do Arch: esta é a melhor distro Linux que já tive o prazer de usar. Espero que essa sensação continue enquanto eu a usar como meu sistema principal. Mas até agora estou convencido de que esta é a escolha certa.</p>
]]></content:encoded><category>linux</category><category>reviews</category></item><item><title>Escolhendo MatterMost no lugar de Rocket.chat e Slack</title><link>https://akitaonrails.github.io/2016/08/13/escolhendo-mattermost-no-lugar-de-rocket-chat-e-slack/</link><guid isPermaLink="true">https://akitaonrails.github.io/2016/08/13/escolhendo-mattermost-no-lugar-de-rocket-chat-e-slack/</guid><pubDate>Sat, 13 Aug 2016 22:41:00 -0300</pubDate><description>&lt;p&gt;Eu sou um tecnólogo, basicamente um nerd. Então, quando fico obcecado com alguma questão técnica, por menor que seja, simplesmente não consigo dormir tranquilo até encontrar uma solução razoável.&lt;/p&gt;
&lt;p&gt;Meu time, meus clientes, todos nós usamos Slack felizes por mais de 2 anos, como acredito que muitos times pelo mundo também usaram. Apesar de ninguém nunca ter reclamado, eu sempre me incomodava com pequenos detalhes. Em primeiro lugar, como tudo que tem valor, custa. Ou pago USD 6.67/mês/usuário, ou aceito as restrições do plano gratuito. E, como a maioria dos outros times, fui levando com as restrições enquanto deu.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Eu sou um tecnólogo, basicamente um nerd. Então, quando fico obcecado com alguma questão técnica, por menor que seja, simplesmente não consigo dormir tranquilo até encontrar uma solução razoável.</p>
<p>Meu time, meus clientes, todos nós usamos Slack felizes por mais de 2 anos, como acredito que muitos times pelo mundo também usaram. Apesar de ninguém nunca ter reclamado, eu sempre me incomodava com pequenos detalhes. Em primeiro lugar, como tudo que tem valor, custa. Ou pago USD 6.67/mês/usuário, ou aceito as restrições do plano gratuito. E, como a maioria dos outros times, fui levando com as restrições enquanto deu.</p>
<p>Por exemplo, para me livrar dos avisos para fazer upgrade porque batemos no limite de uploads, criei uma pequena ferramenta chamada <a href="https://github.com/akitaonrails/slack_cleanup"target="_blank" rel="noopener">slack_cleanup</a> (primeiro em Elixir e depois em <a href="https://github.com/akitaonrails/cr_slack_cleanup"target="_blank" rel="noopener">Crystal</a>, só por exercício). Isso ajudou por um tempo.</p>
<p>Nosso time foi crescendo, de forma constante e frequente, assim como os clientes. Quanto mais usuários adicionamos, mais conversas, mais rápido batemos nas restrições. Histórico se perde com mais frequência, precisamos limpar uploads com mais frequência. Isso cansa muito rápido.</p>
<p>Uma coisa que valorizo acima de tudo é conhecimento. Como pequeno exemplo, eu mesmo mantenho múltiplos backups de todos os meus emails, todos os meus projetos, todos os assets que produzi nos últimos 20 anos. Caramba, tenho um sistema Drobo de 6 TB em Raid-5 bem na minha mesa de casa e mais 3 HDs externos de 1TB para backup. Perdi muito pouco ao longo dos anos.</p>
<p>Realmente me incomoda quando perco informação.</p>
<ul>
<li>
<p>Gmail Business, DropBox, buckets do AWS S3, por serem serviços externos, não me preocupam, pois mantenho cópias de tudo offline. Então, se essas contas forem comprometidas de uma hora para outra, tenho múltiplas cópias.</p>
</li>
<li>
<p>GitHub me incomodava um pouco porque, embora eu tenha múltiplas cópias dos repositórios, perderia todo o histórico de Pull Requests e Issues. Esse é um dos motivos pelos quais migrei para o meu próprio GitLab e ajudei a ajustar o processo de import para puxar esse histórico de Pull Requests.</p>
</li>
<li>
<p>O Slack me incomoda muito pelos motivos já mencionados, e por isso na semana passada testamos primeiro o MatterMost e depois subimos o Rocket.chat.</p>
</li>
</ul>
<p><img src="https://akitaonrails.s3.amazonaws.com/assets/image_asset/image/558/big_8_13_16__22_20.png" alt="Mattermost"  loading="lazy" /></p>
<h3>There, and Back Again<span class="hx:absolute hx:-mt-20" id="there-and-back-again"></span>
    <a href="#there-and-back-again" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Saímos do Slack para o Rocket.chat e, alguns dias depois, estamos migrando de novo, agora para o Mattermost.</p>
<p>Sim, isso foi trabalhoso. Meu time não ficou muito feliz em deixar o Slack. O Slack é realmente elegante, completo, bonito, redondinho, um produto web de verdade para esta geração. Qualquer alternativa precisa ser pelo menos quase tão bonita e ter funcionalidades sem bugs, incluindo webhooks.</p>
<p>O Mattermost atende quase perfeitamente, mas a Team Edition open source carecia de uma funcionalidade importante para mim: a possibilidade de impedir que membros comuns renomeiem e/ou apaguem grupos privados. Sim, esperamos que adultos se comportem, mas quando você tem times remotos, clientes remotos, usuários externos sem nenhum compromisso com a empresa, isso vira uma dor de cabeça.</p>
<p>Sim, eu poderia, e provavelmente deveria, usar a Enterprise Edition paga. Mas só por essa pequena funcionalidade, achei caro demais. Isso me motivou a deixar pra lá e instalar o Rocket.chat. Movi todo o meu time pra lá (quase 50 pessoas, porque ainda não migrei os clientes). Esse seria o fim da história.</p>
<p>Mas o Rocket.chat tem uma infraestrutura complexa para lidar (você precisa ter no mínimo 3 máquinas, ou pagar a mais por um SaaS de Mongodb decente). Aliás, <a href="http://www.akitaonrails.com/2016/08/09/moving-away-from-slack-into-rocket-chat-good-enough"target="_blank" rel="noopener">no meu post anterior</a> expliquei por que vocês, pessoal de MEAN, não devem ser desleixados ao lidar com Mongodb. Resumindo: Mongodb não foi pensado para rodar em uma única instância, você precisa ter um replica set. Se você tem um Mongodb em instância única, está fazendo errado.</p>
<p>E o mais problemático: o client-side é simplesmente pesado demais. Frequentemente faz a CPU disparar em máquinas não tão potentes. É notavelmente, e mensuravelmente, mais lento de navegar na UI, comparado ao Slack. A UI do MatterMost era muito mais rápida e muito mais responsiva.</p>
<p>Eu estava quase disposto a relevar a falta de uma suíte de testes decente. Estava disposto a tentar conviver com Meteor e CoffeeScript. Estava disposto a lidar com a manutenção complexa do MongoDB.</p>
<p>Mas a lentidão na resposta atingindo vários membros do meu time é um show-stopper, um problema gigante. Desligamos a feature beta de videochat (já que ela sempre dispara picos de CPU em todos os usuários), mas vários membros ainda tinham uma experiência ruim com uma UI lenta demais e devoradora de recursos.</p>
<p>O MatterMost, baseado em React, escrito em ES6, devidamente estruturado, com suítes de teste client-side suficientemente boas, era um candidato mais adequado. Então decidi pensar de verdade no problema original e cheguei a uma solução simples: <a href="http://www.akitaonrails.com/2016/08/12/hackeando-o-mattermost-team-edition"target="_blank" rel="noopener">adicionar uma função PLPGSQL simples</a> para ser disparada sempre que alguém tentasse apagar um canal. Funcionou direitinho. E isso me motivou a chamar meu time de novo e propor essa nova mudança: acredito que todo mundo embarcou, já que o MatterMost estava muito mais rápido nas máquinas deles.</p>
<p>Sei que estou soando muito duro com o Rocket.chat, e essa não é minha intenção. Se não tivéssemos outras opções, ainda iríamos para o Rocket.chat. Mas como o Mattermost provou ser a melhor escolha, foi decisão fácil.</p>
<h3>Instalação do MatterMost<span class="hx:absolute hx:-mt-20" id="instalação-do-mattermost"></span>
    <a href="#instala%c3%a7%c3%a3o-do-mattermost" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Como sempre, não vou cansar você com instruções já disponíveis online. Se quiser instalar tudo manualmente, siga <a href="https://docs.mattermost.com/install/prod-ubuntu.html"target="_blank" rel="noopener">este tutorial</a>, mas uma opção melhor seria <a href="https://docs.mattermost.com/install/prod-docker.html"target="_blank" rel="noopener">o deployment via Docker</a>. Você pode até instalar/atualizar <a href="http://docs.gitlab.com/omnibus/gitlab-mattermost/"target="_blank" rel="noopener">junto com o GitLab</a>.</p>
<p>Garanta que você tenha NGINX na frente do servidor e que tenha tanto um domínio ou subdomínio devidamente registrado, quanto SSL - use Let&rsquo;s Encrypt.</p>
<p>Como quero continuar mexendo e experimentando com o codebase em uma instalação ativa, instalei tudo manualmente e tenho esta estrutura de diretórios:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>-rw-r--r--  1 mattermost mattermost     6504 Aug 13 20:11 config.json
drwxrwxr-x  5 mattermost mattermost     4096 Aug 13 20:30 data
lrwxrwxrwx  1 mattermost mattermost       33 Aug 13 20:13 mattermost -&gt; mattermost-team-3.3.0-linux-amd64
drwxr-xr-x  9 mattermost mattermost     4096 Aug 13 20:28 mattermost-team-3.2.0-linux-amd64
-rw-rw-r--  1 mattermost mattermost 19968308 Jul 14 16:37 mattermost-team-3.2.0-linux-amd64.tar.gz
drwxr-xr-x 11 mattermost mattermost     4096 Aug 13 20:28 mattermost-team-3.3.0-linux-amd64
-rw-rw-r--  1 mattermost mattermost 20241448 Aug 12 20:41 mattermost-team-3.3.0-linux-amd64.tar.gz
drwxrwxr-x  3 mattermost mattermost     4096 Aug 13 20:23 platform-dev-3.3.0
-rw-r--r--  1 mattermost mattermost 18060203 Aug 13 20:22 platform-dev.tar.gz</code></pre></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>Tenho um usuário sudo restrito chamado <code>mattermost</code> e tenho um diretório principal <code>mattermost</code> apontando para os pacotes binários que você encontra na <a href="https://www.mattermost.org/download/"target="_blank" rel="noopener">página oficial de download</a>.</p>
<p>Note que tenho uma cópia de <code>mattermost/config/config.json</code> no diretório home. Deixo lá para que, toda vez que eu baixe uma nova versão e refaça o symlink para <code>mattermost</code>, eu possa simplesmente fazer:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>rm -Rf ~/mattermost/config/config.json
cd ~/mattermost/config
ln -s ~/mattermost/config.json</code></pre></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>Garanta também que você ajuste pelo menos o seguinte na config:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>...
&#34;FileSettings&#34;: {
    &#34;MaxFileSize&#34;: 83886080,
    &#34;DriverName&#34;: &#34;local&#34;,
    &#34;Directory&#34;: &#34;/home/mattermost/data&#34;,
...</code></pre></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 quiser, você pode mandar os uploads de arquivos para algum bucket S3 que você tenha, e só preencher os detalhes da AWS. Mas se escolher tê-los localmente, mude o diretório para algum lugar fora da pasta <code>mattermost</code>, já que a cada upgrade você vai trocar a pasta. Tanto com AWS EC2 quanto com Digital Ocean você sempre pode escolher adicionar um volume secundário que sobreviva às VMs, então mesmo se chegar a um ponto de ter centenas de usuários simultâneos e quiser escalar horizontalmente, pode ter todas as máquinas apontando para um volume compartilhado (AWS EFS, por exemplo).</p>
<p>Por falar nisso, nessa configuração, atualizar seria assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo service mattermost stop
wget https://releases.mattermost.com/x.y.z/mattermost-team-x.y.z-linux-amd64.tar.gz
tar xvfz mattermost-team-x.y.z-linux-amd64.tar.gz
mv mattermost mattermost-team-x.y.z-linux-amd64
ln -s mattermost-team-x.y.z-linux-amd64 mattermost
rm -Rf mattermost/config/config.json
rm -Rf mattermost/data
cd mattermost/config
ln -s ~/config.json
cd ..
ln -s ~/data
sudo service mattermost start</code></pre></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>A razão de eu querer dessa forma é poder ajustar o código e empurrar as alterações manualmente.</p>
<p>Para sua máquina de desenvolvimento, você deve seguir <a href="https://docs.mattermost.com/developer/developer-setup.html"target="_blank" rel="noopener">estas instruções</a>. Se você está em OS X e escolhe usar o Docker Toolbox, lembre que você não precisa mais do VirtualBox, pois ele vai usar o hypervisor nativo do OS X agora. Na minha máquina, tive que adicionar <code>dockerhost</code> manualmente no meu <code>/etc/hosts</code> porque o <code>boot2docker</code> estava falhando em obter meu IP.</p>
<p>Aí você pode simplesmente clonar o código do Github:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>mkdir mattermost
cd mattermost
git clone https://github.com/mattermost/platform
git checkout -b v3.3.0 v3.3.0</code></pre></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>Lembre-se de sempre fazer checkout da versão estável correta (v3.3.0 na época em que postei este artigo originalmente) que você tem instalada no seu servidor. De novo, não vou cansar você com o que já está documentado nos links acima, mas você precisa ter Go 1.6(.3), Docker, Docker-Composer, Docker-Machine, tudo já instalado.</p>
<p>Você pode executar <code>make run</code> e, depois que terminar (e, como sempre, o npm vai garantir que isso demore muito), pode abrir <code>http://localhost:8065</code> para brincar localmente.</p>
<p>Mais importante: você pode mexer nos componentes JSX do React em <code>platform/webapp/components</code>, por exemplo, no <code>channel_header.jsx</code>, e adicionar coisas 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-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// linha 493 da v3.3.0
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="p">(</span><span class="nx">isAdmin</span> <span class="o">||</span> <span class="nx">isSystemAdmin</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">dropdownContents</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">li</span>
</span></span><span class="line"><span class="cl">            <span class="nx">key</span><span class="o">=</span><span class="s1">&#39;rename_channel&#39;</span>
</span></span><span class="line"><span class="cl">            <span class="nx">role</span><span class="o">=</span><span class="s1">&#39;presentation&#39;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="nx">a</span>
</span></span><span class="line"><span class="cl">                <span class="nx">role</span><span class="o">=</span><span class="s1">&#39;menuitem&#39;</span>
</span></span><span class="line"><span class="cl">                <span class="nx">href</span><span class="o">=</span><span class="s1">&#39;#&#39;</span>
</span></span><span class="line"><span class="cl">                <span class="nx">onClick</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">showRenameChannelModal</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="o">&lt;</span><span class="nx">FormattedMessage</span>
</span></span><span class="line"><span class="cl">                    <span class="nx">id</span><span class="o">=</span><span class="s1">&#39;channel_header.rename&#39;</span>
</span></span><span class="line"><span class="cl">                    <span class="nx">defaultMessage</span><span class="o">=</span><span class="s1">&#39;Rename {term}...&#39;</span>
</span></span><span class="line"><span class="cl">                    <span class="nx">values</span><span class="o">=</span><span class="p">{{</span>
</span></span><span class="line"><span class="cl">                        <span class="nx">term</span><span class="o">:</span> <span class="p">(</span><span class="nx">channelTerm</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}}</span>
</span></span><span class="line"><span class="cl">                <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="err">/a&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="err">/li&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ChannelStore</span><span class="p">.</span><span class="nx">isDefault</span><span class="p">(</span><span class="nx">channel</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">dropdownContents</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">deleteOption</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><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>
<p>E sabe o que isso faz? Remove as opções &ldquo;Rename Group&rdquo; e &ldquo;Delete Group&rdquo; do menu do canal se o usuário não for um system admin. Agora, como colocar isso no seu servidor?</p>
<p>Antes de mais nada, você tem que editar o <code>Makefile</code> nesta seção:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>@# Make osx package
@# Copy binary
cp $(GOPATH)/bin/darwin_amd64/platform $(DIST_PATH)/bin
@# Package
tar -C dist -czf $(DIST_PATH)-$(BUILD_TYPE_NAME)-osx-amd64.tar.gz mattermost
@# Cleanup
rm -f $(DIST_PATH)/bin/platform

@# Make windows package
@# Copy binary
cp $(GOPATH)/bin/windows_amd64/platform.exe $(DIST_PATH)/bin
@# Package
tar -C dist -czf $(DIST_PATH)-$(BUILD_TYPE_NAME)-windows-amd64.tar.gz mattermost
@# Cleanup
rm -f $(DIST_PATH)/bin/platform.exe

@# Make linux package
@# Copy binary
cp $(GOPATH)/bin/platform $(DIST_PATH)/bin
@# Package
tar -C dist -czf $(DIST_PATH)-$(BUILD_TYPE_NAME)-linux-amd64.tar.gz mattermost
@# Don&#39;t cleanup linux package so dev machines will have an unziped linux package avalilable
@#rm -f $(DIST_PATH)/bin/platform</code></pre></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>Note que o desenvolvedor que fez esse arquivo provavelmente usa Linux. Isso porque esse arquivo gera o binário Linux-ELF como <code>bin/platform</code>, enquanto o binário OS X Mach-O fica em <code>bin/darwin_amd64/platform</code>. Agora, se como eu você está em OS X, tem que inverter isso e fazer a versão Linux apontar para <code>bin/linux_amd64/platform</code>, senão os pacotes vão ter o binário errado.</p>
<p>Aí você vai notar que existe esta seção bem no fim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>setup-mac:
    echo $$(boot2docker ip 2&gt; /dev/null) dockerhost | sudo tee -a /etc/hosts</code></pre></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ê está nas versões mais recentes do Docker-Toolbox, não precisa mais do boot2docker, ele vai usar o docker-machine. Então essa linha não funciona, e a forma mais fácil de fazer o <code>make test</code> rodar é trocar o <code>dockerhost</code> por <code>localhost</code> na configuração de PostgreSQL do <code>config/config.json</code>.</p>
<p>Se os testes estão todos passando, você pode rodar <code>make package</code> para gerar todos os pacotes, e então enviar o <code>dist/mattermost-team-edition-linux-amd64.tar.gz</code> para o seu servidor e descompactar no local correto.</p>
<p>Como nota pra noobs em Go como eu, eu tinha meu <code>GOPATH</code> apontando para <code>/Users/akitaonrails/.go</code> e meu projeto estava em <code>/Users/akitaonrails/codeminer42/mattermost/platform</code>. Me disseram que isso está incorreto e foi a fonte de muitas horas de frustração minha. O projeto PRECISA ESTAR DENTRO DO GOPATH.</p>
<p>Então mudei meu <code>GOPATH</code> para <code>/Users/akitaonrails/Sites/go</code> e o projeto para <code>/Users/akitaonrails/Sites/go/src/github.com/mattermost/platform</code> e agora funciona. Provavelmente eu também teria feito symlink do caminho do projeto para dentro do GOPATH. Mas agora tudo compila e roda direitinho.</p>
<p>É assim que vou continuar experimentando por enquanto, até me sentir confortável o suficiente para automatizar todo o processo depois. Isso deve funcionar bem para meu time por ora.</p>
<p>É claro, o snippet acima é apenas um <strong>dirty hack</strong>, não tente contribuir assim. Uma implementação adequada exigiria que eu pelo menos criasse uma nova configuração no <code>config.json</code>, por exemplo <code>TeamSettings.MembersCanManageChannel</code> como <code>false</code>, e mudasse o <code>api/context.go</code> por volta da linha 347 para algo como:</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-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="n">func</span> <span class="p">(</span><span class="n">c</span> <span class="o">*</span><span class="no">Context</span><span class="p">)</span> <span class="no">HasPermissionsToTeam</span><span class="p">(</span><span class="n">teamId</span> <span class="n">string</span><span class="p">,</span> <span class="n">where</span> <span class="n">string</span><span class="p">)</span> <span class="n">bool</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">c</span><span class="o">.</span><span class="n">IsSystemAdmin</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kp">true</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</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="n">utils</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">TeamSettings</span><span class="o">.</span><span class="n">MembersCanManageChannel</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kp">false</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="o">...</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>Depois mudar o componente <code>webapp/channel_header.jsx</code> no front-end React (junto com testes unitários decentes em <code>webapp/tests/client_channel.test.jsx</code>), garantir que o <code>make test</code> passa, e finalmente abrir um feature request para o core team.</p>
<p>Mas a ideia aqui era só mostrar que não foi tão difícil resolver o show-stopper para o meu cenário particular, tanto usando o <a href="http://www.akitaonrails.com/2016/08/12/hackeando-o-mattermost-team-edition"target="_blank" rel="noopener">trigger SQL</a> para proteger o banco quanto o hack para arrumar a Web UI.</p>
<h3>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Mas e a feature mais importante de todas? Suporte a RightGIF? Ainda não existe nada tão simples quanto um comando rightgif do Slack. Felizmente, dá pra compensar a maior parte dessas pequenas faltas instalando um <a href="https://www.npmjs.com/package/hubot-mattermost"target="_blank" rel="noopener">servidor Hubot</a>, e ligando a um usuário para que você possa conversar com o bot e fazer ele fazer coisas pra você (programar um alarme, buscar um gif, traduzir texto, etc). Como ressalva, o adaptador do hubot exige o uso do <a href="https://github.com/loafoe/mattermost-client"target="_blank" rel="noopener">mattermost-client</a>, que precisa ser sincronizado com as releases da plataforma do servidor para funcionar direito, então tome cuidado ao atualizar.</p>
<p>No geral, o Mattermost é uma ótima escolha. Também não é para amadores; o ambiente de desenvolvimento exige que você domine seu Docker. Exige que você saiba configurar Go-lang direito. Exige que você siga os <a href="https://docs.mattermost.com/developer/contribution-guide.html"target="_blank" rel="noopener">procedimentos adequados para contribuir</a>, como deveria ser. O projeto em si é um único codebase dividido em aproximadamente 2 aplicações, uma API HTTP em Go e um front-end em React para consumir as APIs. Tudo no projeto é automatizado através do uso adequado de imagens Docker (para mysql, postgresql, instâncias openldap) e Makefiles para rodar a suíte de testes, criar pacotes, etc.</p>
<p>E ele tem algumas conveniências do Slack que o Rocket.chat ainda não tem, como um atalho simples para trocar de canal (Cmd-K), a capacidade de responder mensagens e organizá-las como threads, suporte a Markdown adequado e mais completo. No geral, as funcionalidades são redondas e bem acabadas. O que está lá é sólido e funciona; é sempre ruim ter funcionalidades pela metade.</p>
<p>Com esses hacks em mente, posso recomendar fortemente que você use Mattermost. E como já disse em posts anteriores, isso vai além de uma questão de custo. Se você é um time pequeno, sem desenvolvedores internos ou alguém que possa manter sua própria instalação, definitivamente deveria pagar pelo suporte Enterprise do Mattermost; é acessível e bem mais barato que o Slack.</p>
<p>Por enquanto, é a melhor escolha, tanto em termos de acabamento geral, funcionalidades completas, UI simples e responsiva, qualidade de código e o cuidado geral com a engenharia.</p>
]]></content:encoded><category>reviews</category><category>containers</category></item><item><title>Saindo do Pivotal Tracker para o Fulcrum. Bom o Suficiente.</title><link>https://akitaonrails.github.io/2016/08/10/saindo-do-pivotal-tracker-para-o-fulcrum-bom-o-suficiente/</link><guid isPermaLink="true">https://akitaonrails.github.io/2016/08/10/saindo-do-pivotal-tracker-para-o-fulcrum-bom-o-suficiente/</guid><pubDate>Wed, 10 Aug 2016 18:30:00 -0300</pubDate><description>&lt;p&gt;Venho escrevendo aqui no blog sobre como estou montando minha própria infraestrutura interna. Já contei como saí do &lt;a href="http://www.akitaonrails.com/2016/08/03/migrando-para-o-gitlab-sim-vale-a-pena"target="_blank" rel="noopener"&gt;GitHub e Travis para o GitLab&lt;/a&gt;, depois como migramos do &lt;a href="http://www.akitaonrails.com/2016/08/09/moving-away-from-slack-into-rocket-chat-good-enough"target="_blank" rel="noopener"&gt;Slack para o Rocket.chat&lt;/a&gt;, mas a primeira migração de todas é o tema deste artigo.&lt;/p&gt;
&lt;p&gt;Uso o Pivotal Tracker desde 2010 até 2015, e isso porque eu acredito que ele é muito superior ao Trello e outras &lt;a href="http://www.akitaonrails.com/2009/12/16/off-topic-cuidado-com-o-kanban-butt"target="_blank" rel="noopener"&gt;listas de tarefas glorificadas&lt;/a&gt; por aí.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/Codeminer42/cm42-central"target="_blank" rel="noopener"&gt;&lt;img src="https://raw.githubusercontent.com/Codeminer42/cm42-central/master/doc/cm42-central-screenshot.png" alt="Cm42-Central" loading="lazy" /&gt;&lt;/a&gt;&lt;/p&gt;</description><content:encoded><![CDATA[<p>Venho escrevendo aqui no blog sobre como estou montando minha própria infraestrutura interna. Já contei como saí do <a href="http://www.akitaonrails.com/2016/08/03/migrando-para-o-gitlab-sim-vale-a-pena"target="_blank" rel="noopener">GitHub e Travis para o GitLab</a>, depois como migramos do <a href="http://www.akitaonrails.com/2016/08/09/moving-away-from-slack-into-rocket-chat-good-enough"target="_blank" rel="noopener">Slack para o Rocket.chat</a>, mas a primeira migração de todas é o tema deste artigo.</p>
<p>Uso o Pivotal Tracker desde 2010 até 2015, e isso porque eu acredito que ele é muito superior ao Trello e outras <a href="http://www.akitaonrails.com/2009/12/16/off-topic-cuidado-com-o-kanban-butt"target="_blank" rel="noopener">listas de tarefas glorificadas</a> por aí.</p>
<p><a href="https://github.com/Codeminer42/cm42-central"target="_blank" rel="noopener"><img src="https://raw.githubusercontent.com/Codeminer42/cm42-central/master/doc/cm42-central-screenshot.png" alt="Cm42-Central"  loading="lazy" /></a></p>
<h3>O Dilema do Custo<span class="hx:absolute hx:-mt-20" id="o-dilema-do-custo"></span>
    <a href="#o-dilema-do-custo" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Como em todos os outros relatos, vou começar pelo argumento do custo. O Pivotal Tracker tem <a href="http://www.pivotaltracker.com/why-tracker/pricing/"target="_blank" rel="noopener">preço</a> baseado na quantidade de usuários.</p>
<p>Se você tem um time pequeno e poucos clientes externos, um plano básico de 10 usuários já resolve, e você vai pagar apenas USD 420 por ano. Simplesmente pague e pronto.</p>
<p>Se você tem até 25 usuários, ainda continua barato, e sai por USD 1.800 por ano. Vale muito a pena.</p>
<p>Mesmo se você tiver 50 usuários, o plano máximo, você vai pagar USD 3.600 por ano. Acima disso, precisa entrar em contato direto com eles.</p>
<p>O custo está longe de ser proibitivo e, se você puder pagar, meu conselho é que pague.</p>
<p>No meu caso, a estratégia é ter controle total sobre nossos dados e conhecimento, e por isso prefiro ter a propriedade do serviço.</p>
<p>E como o Fulcrum estava &ldquo;quase&rdquo; bom o suficiente, resolvi testar e ver se conseguíamos evoluí-lo com o tempo. Acredito que, mesmo estando ainda muito longe do Tracker completo, o que temos hoje já atende à maior parte dos nossos projetos.</p>
<p>Deixa eu repetir: provavelmente você não vai ganhar nada com isso se seu time for pequeno. O Pivotal Tracker continua sendo, até hoje, a melhor ferramenta de gestão de projetos para times de desenvolvimento de software, e você deveria testá-lo primeiro, se acostumar com o fluxo dele (como vou explicar abaixo), e só depois decidir se quer assumir o controle e instalar a alternativa open source.</p>
<p>Tem o fator custo, claro, mas ele não é o incentivo principal para essa mudança.</p>
<h3>As Funcionalidades Importantes<span class="hx:absolute hx:-mt-20" id="as-funcionalidades-importantes"></span>
    <a href="#as-funcionalidades-importantes" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Pesquisando um pouco, encontrei o projeto Fulcrum. É um projeto Rails muito simples, muito bare-bone, que imita as funcionalidades mais importantes do Tracker.</p>
<p>Qualquer ferramenta competente de gestão de projetos <strong>precisa</strong> ter, no mínimo, 4 pilares:</p>
<ul>
<li>Stories (com threads de discussão, upload de arquivos, tags, organização em Epics e busca)</li>
<li>Estimativa numérica adequada (story points, tamanho proporcional para as stories)</li>
<li>Sprints com time-box (períodos curtos e fixos de tempo)</li>
<li>Velocity (a produtividade real de um determinado time em um determinado projeto)</li>
</ul>
<p>Qualquer ferramenta que tenha todos os itens acima já é útil.</p>
<p>O próprio Fulcrum tem quase tudo. Fizemos um fork interno do projeto e começamos a adicionar algumas das funcionalidades que faltavam. Já estamos usando ele há mais ou menos 1 ano e tem sido bom o suficiente para nossa rotina. Ainda há alguns bugs e funcionalidades faltando que pretendemos incluir.</p>
<p>Se você se interessar, estou disponibilizando esse fork <a href="https://github.com/Codeminer42/cm42-central"target="_blank" rel="noopener">publicamente</a> para cumprir a licença Affero GPL.</p>
<p>Qualquer contribuição é bem-vinda.</p>
<h3>Sobre Gestão Ágil Adequada<span class="hx:absolute hx:-mt-20" id="sobre-gestão-ágil-adequada"></span>
    <a href="#sobre-gest%c3%a3o-%c3%a1gil-adequada" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Desviando um pouco do assunto, quero explicar por que esse tipo de ferramenta (no estilo Tracker) é a melhor opção quando comparada ao que chamei de &ldquo;listas de tarefas glorificadas&rdquo;.</p>
<p>Os princípios são muito simples:</p>
<ul>
<li>Todo projeto precisa começar com o backlog mais completo possível (a incerteza está no seu pico no começo, e vão faltar detalhes, mas é importante ter uma visão do que significa &ldquo;minimamente completo&rdquo; e a ordem de importância de cada story, uma &ldquo;prioridade&rdquo; adequada).
<ul>
<li>O nível de detalhe em si não importa. Uma story precisa ter informação suficiente para que qualquer desenvolvedor do time consiga implementar as tarefas necessárias. Caso contrário, ela deve ser marcada como &ldquo;bloqueada&rdquo;, para que o Product Owner saiba que precisa adicionar mais detalhes, e nenhum desenvolvedor encosta nela até que a tag seja removida.</li>
</ul>
</li>
<li>Todas as stories <strong>precisam ser estimadas</strong> (falo mais sobre isso na próxima seção). A unidade realmente não importa. Você pode pensar em horas, em frações de um dia ou no que ela realmente é: uma proporção. Uma story de tamanho &ldquo;2&rdquo; deveria ter aproximadamente metade da complexidade de uma story de tamanho &ldquo;4&rdquo;. É só isso. Até stories &ldquo;bloqueadas&rdquo; devem receber tamanho.</li>
<li>Projetos precisam ser divididos em Sprints com tempo fixo e duração fixa, para que o time tenha a oportunidade de reavaliar frequentemente. É aqui que a estimativa pode ser refinada, onde mais níveis de detalhe nas stories devem ser exigidos.</li>
<li>Bugs não podem ter estimativa numérica. Eles servem justamente para puxar a velocity do time para baixo, e são um indicativo de entregas mal feitas.</li>
<li>Velocity é a quantidade real de story points entregues até o fim de uma Sprint.
<ul>
<li>O total de story points de todas as stories do backlog do projeto dividido pela velocity do time dá uma &ldquo;Data de Término&rdquo; estimada por alto. Isso é importante, porque é assim que você sabe quando determinados grupos de funcionalidades serão entregues ao longo do tempo, e é isso que o Product Owner precisa saber para priorizar stories, simplificar stories ou até cortar funcionalidades desnecessárias.</li>
<li>A única responsabilidade do Product Owner é prestar contas pelo Retorno sobre o Investimento das funcionalidades implementadas. E a única forma de medir custo-benefício é saber &ldquo;quanto&rdquo; uma funcionalidade vai &ldquo;custar&rdquo; em termos de story points divididos pela velocity.</li>
</ul>
</li>
</ul>
<p>O que a ferramenta vai expor:</p>
<ul>
<li>Se um backlog tem muitas stories &ldquo;bloqueadas&rdquo; ou muitas stories entregues sem aceitação, isso é sintoma de um Product Owner que não está fazendo o trabalho dele.</li>
<li>Se a velocity varia demais entre sprints, isso é sintoma ou de stories mal escritas (e portanto desenvolvedores com dificuldade de entender o que fazer), ou de desenvolvedores sem concentração no trabalho e entregando resultados inconsistentes.</li>
<li>Velocities inconsistentes com muitos bugs a cada sprint são sintoma de desenvolvedores que não estão fazendo código com qualidade adequada (testes automatizados para evitar regressões, por exemplo).</li>
<li>Um &ldquo;bug&rdquo; não é a mesma coisa que o Product Owner mudar de ideia sobre uma story e rejeitá-la. O time não deve implementar mudanças não documentadas. A aceitação está amarrada ao que a story diz. O Product Owner precisa mudar de ideia antes da story ser implementada ou criar uma nova story para adicionar a mudança (e, portanto, adicionar mais custo ao projeto; não existe almoço grátis).</li>
<li>Stories no &ldquo;Chilly Bin&rdquo; (no Fulcrum, ou &ldquo;Ice Box&rdquo; no Tracker) são &ldquo;lista de desejos&rdquo; e nunca serão implementadas até o Product Owner movê-las para o backlog.</li>
<li>A velocity deveria ser aproximadamente a mesma entre sprints. Picos ou vales na velocity são sintoma de um problema que precisa ser atacado na próxima sprint. É assim que um projeto evolui para melhor ao longo do tempo.</li>
</ul>
<p><img src="https://akitaonrails.s3.amazonaws.com/assets/image_asset/image/557/big_Cm-Fulcrum_-_CM42_Central.png" alt="Velocity"  loading="lazy" /></p>
<h3>Sobre Estimativa<span class="hx:absolute hx:-mt-20" id="sobre-estimativa"></span>
    <a href="#sobre-estimativa" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Muita gente se preocupa demais com &ldquo;estimativa correta&rdquo; a ponto de criar tanta tensão que os desenvolvedores começam a gritar por <a href="http://www.akitaonrails.com/en/2013/10/07/off-topic-desmontando-o-noestimates/"target="_blank" rel="noopener">&ldquo;no estimates&rdquo;</a>. Isso é loucura. Por isso &ldquo;estimativa&rdquo; é uma palavra diferente de &ldquo;previsão&rdquo;: uma é incerta, um chute de grosso calibre, a outra é exata.</p>
<blockquote>
  <p>Não existe estimativa &ldquo;correta&rdquo;.</p>

</blockquote>
<p>Eu diria que em muitos projetos, se as stories estiverem minimamente descritas (ou seja, um desenvolvedor consegue implementar o que está escrito), poderíamos estimar todas como tamanho &ldquo;1&rdquo; e esquecer disso.</p>
<p>Rodamos 2 ou 3 sprints (normalmente uma sprint deveria ser uma semana de trabalho - 5 dias de no máximo 8 horas, nem mais, nem menos) e medimos quantas stories foram entregues. E essa é a velocity.</p>
<p>Agora podemos ver quantas stories temos até o fim do projeto e dividir por essa velocity. E esse é o número de semanas que vamos levar para terminar o projeto.</p>
<blockquote>
  <p>Não há necessidade de estimativa por consenso.</p>

</blockquote>
<p>Consenso em estimativas normalmente é desperdício de tempo. Estimativa é apenas a constatação de que é difícil escrever cada story no exatamente mesmo tamanho, e por isso adicionamos proporções a elas (uma story tamanho 2 é metade do tamanho de uma story tamanho 4).</p>
<p>Mas se um projeto tem 3 meses ou mais, menos as proporções importam (a menos que você caia na anti-prática de ter stories muito desproporcionais, algumas tamanho 1 e muitas tamanho 5, 8 ou até 10, por exemplo). Mas se você ficar abaixo de tamanho 5 para toda story, então quanto maior o projeto, menos as estimativas individuais importam. A velocity vai diluir as diferenças ao longo do tempo.</p>
<p>A tarefa do Project Manager, do Product Owner, do time em geral, é ficar de olho no total de pontos dividido por essa velocity, de onde sai a data estimada de término do projeto. E todos podem negociar, com antecedência, quais stories podem ser feitas, quais não podem, mudar prioridades, remover stories ou simplificar stories.</p>
<blockquote>
  <p>Não perca tempo tentando criar fórmulas para derivar consenso de estimativa.</p>

</blockquote>
<p>Se você administra a Velocity, então você administra o projeto inteiro. Esse é o cerne de toda metodologia Ágil adequada. Todo o resto é acessório a essa finalidade.</p>
<p><img src="https://akitaonrails.s3.amazonaws.com/assets/image_asset/image/556/big_Heroleads_-_CM42_Central.png" alt="Velocity"  loading="lazy" /></p>
<p>Tentar aumentar a velocity artificialmente é um dos vários pecados. Você não consegue. É melhor investir tempo adicionando mais detalhes a uma story, ou simplificando uma story, ou decidindo que algumas stories simplesmente não são necessárias para entregar um produto decente no final.</p>
<p>Simulações de Monte Carlo, técnicas Six Sigma, conceitos de Kanban, nada disso importa. Todas as técnicas da indústria tradicional foram pensadas para linhas de produção de fábricas, onde o tempo de cada tarefa é bem definido e você administra a variância, a exceção. É um mundo Gaussiano, Normal.</p>
<p>Em projetos de software, ou qualquer trabalho artesanal e de pesquisa, você administra expectativas sobre resultados com base em marcos e cortando excessos e incertezas. É um mundo Pareto, onde não existe &ldquo;média&rdquo;, não existe meio, não existe variância.</p>
<p>Em um mundo <strong>Pareto</strong>, tudo está interconectado, e nada é estatisticamente independente (um requisito para Gaussianas). É portanto 80/20: onde 20% do projeto rende 80% dos resultados, onde 20% do escopo pode ser cortado.</p>
<p>Qualquer coisa que não seja <strong>&ldquo;estatisticamente independente&rdquo;</strong> (como jogar uma moeda) não pode ser tirada a média, não cabe em uma distribuição Normal. Provavelmente é uma Pareto, Power Law, Zipf, Exponencial, ou até uma Poisson, mas não uma Gaussiana. As partes de um software estão todas entrelaçadas em uma rede, elas não são eventos independentes, não podem ser reorganizadas aleatoriamente, elas não são facilmente intercambiáveis.</p>
<h2>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Este artigo é bem curto e eu posso expandir cada item acima em seu próprio artigo, bem longo. Me diz nos comentários se eu devo, e quais pontos levantam mais dúvidas.</p>
<p>Venho refinando essas técnicas ao longo dos <a href="http://www.akitaonrails.com/agile"target="_blank" rel="noopener">últimos 10 anos</a>, e pelo menos 5 deles dentro das restrições de uma ferramenta como o Tracker. E acredito que consegui chegar ao conjunto mínimo de princípios que levam a uma gestão adequada, longe de superstição, fantasia ou ilusão que você vê por aí hoje em dia.</p>
<p>Projetos sofrem quando as recomendações acima não são seguidas:</p>
<ul>
<li>Product Owners não cumprem suas responsabilidades: falham em adicionar detalhes às stories, negligenciam funcionalidades entregues e não as testam direito, não participam.</li>
<li>Backlogs estão incompletos, com falta de detalhe, falta de estimativa, falta de priorização.</li>
<li>Desenvolvedores não começam nem terminam suas tarefas direito, com qualidade de código adequada.</li>
<li>Tempo é desperdiçado em bikeshedding em vez de entrega.</li>
</ul>
<p>Nosso fork do Fulcrum, chamado <a href="https://github.com/Codeminer42/cm42-central"target="_blank" rel="noopener">&ldquo;Central&rdquo;</a>, está longe de ser perfeito, mas funciona bem o suficiente e nos dá controle para continuar adicionando funcionalidades que tornam nossa rotina mais confortável, e estamos apenas começando.</p>
<p>Espero que essa técnica e essa ferramenta sejam úteis para mais times, e adoraria ouvir o feedback de quem se interessar.</p>
]]></content:encoded><category>agile</category><category>rails</category><category>reviews</category></item><item><title>Moving away from Slack into Rocket.chat. Good Enough.</title><link>https://akitaonrails.github.io/2016/08/09/moving-away-from-slack-into-rocket-chat-good-enough/</link><guid isPermaLink="true">https://akitaonrails.github.io/2016/08/09/moving-away-from-slack-into-rocket-chat-good-enough/</guid><pubDate>Tue, 09 Aug 2016 16:21:00 -0300</pubDate><description>&lt;p&gt;In my quest to create my own private infrastructure I&amp;rsquo;ve already moved away from Pivotal Tracker (saving this for a future post), Bitbucket, Github, Travis and into GitLab and GitLab Runner. There are more services I will move away from in the future, so expect more posts like this.&lt;/p&gt;
&lt;p&gt;In &lt;a href="http://www.akitaonrails.com/2016/08/03/migrando-para-o-gitlab-sim-vale-a-pena"target="_blank" rel="noopener"&gt;my previous post&lt;/a&gt; I forgot to mention minimal firewall and SSL configuration, but you can check it here.&lt;/p&gt;
&lt;p&gt;One of the most difficult pieces to move away from is Slack. Don&amp;rsquo;t get me wrong, it&amp;rsquo;s a great tool and it gets the job done. The free-tier is really competent but I really want some of the payed features such as history of all conversations with search capabilities and uploads without limit.&lt;/p&gt;</description><content:encoded><![CDATA[<p>In my quest to create my own private infrastructure I&rsquo;ve already moved away from Pivotal Tracker (saving this for a future post), Bitbucket, Github, Travis and into GitLab and GitLab Runner. There are more services I will move away from in the future, so expect more posts like this.</p>
<p>In <a href="http://www.akitaonrails.com/2016/08/03/migrando-para-o-gitlab-sim-vale-a-pena"target="_blank" rel="noopener">my previous post</a> I forgot to mention minimal firewall and SSL configuration, but you can check it here.</p>
<p>One of the most difficult pieces to move away from is Slack. Don&rsquo;t get me wrong, it&rsquo;s a great tool and it gets the job done. The free-tier is really competent but I really want some of the payed features such as history of all conversations with search capabilities and uploads without limit.</p>
<p><img src="https://akitaonrails.s3.amazonaws.com/assets/image_asset/image/555/big_Franz.png" alt="Codeminer Rocket"  loading="lazy" /></p>
<h2>The Cost Conundrum<span class="hx:absolute hx:-mt-20" id="the-cost-conundrum"></span>
    <a href="#the-cost-conundrum" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>But then you have to commit to pay USD 8/month per user (USD 6.67 if you pay ahead of time). If you&rsquo;re a small team (around a dozen people) it&rsquo;s well worth it and you should definitely pay and get over with.</p>
<p>If you have more than 20 people then it starts to become a conundrum. On my GitLab cost calculations, some people argued that saving USD 15k yearly is not such a big deal, and they&rsquo;re not wrong.</p>
<p>If you&rsquo;re from outside of the US coastal cities, specially from countries in South America, Asia where currency can be more than 3 times devalued, than it quickly starts to become a big deal.</p>
<p>Apart from that, we are currently offloading a whole lot of out IPs and knowledge into the care of companies we don&rsquo;t really know and where we don&rsquo;t hold any real stakes.</p>
<p>If you&rsquo;re a medium to big company it really starts to make sense to want to have more control over your own property. Of course, it costs some work and maintenance, so it&rsquo;s not for everybody.</p>
<p>What I will argue is that if you have <strong>150 people</strong> or more, and you&rsquo;re still growing, it&rsquo;s not such a big burden to jump into your own infrastructure.</p>
<blockquote>
  <p>You avoid paying around <a href="https://codeminer42.slack.com/pricing"target="_blank" rel="noopener"><strong>USD 12,000 a year</strong></a> or more, and instead you will pay <strong>USD 960 a year</strong> in Digital Ocean boxes and MMS plus a few hours every month in basic maintenance. That&rsquo;s 12 times cheaper.</p>

</blockquote>
<p>Again, you shouldn&rsquo;t do it just for the cost savings as the maintenance burden can easily not be worth it if you or your team are not devops savvy and you don&rsquo;t have anyone to keep monitoring it. For most companies, the conversation history is not so important and even the free-tier will be more than enough.</p>
<p>Cost is less relevant depending on your context, and there are many different uses for group chats. For example, if you&rsquo;re an <a href="https://news.ycombinator.com/item?id=9754626"target="_blank" rel="noopener">open source community</a>, you would try <a href="https://gitter.im"target="_blank" rel="noopener">Gitter</a> instead.</p>
<p>There are also <a href="https://www.google.com/search?q=slack&#43;alternatives"target="_blank" rel="noopener">many other alternatives</a> that you may want to try.</p>
<p>For the sake of this article, let&rsquo;s assume you&rsquo;re a small to medium company, in need of private rooms, many external users (for example, your clients), with at least 50 people. Then this can start to make sense. Any other scenario and we have to analyze it differently.</p>
<h2>Why I chose Rocket.chat<span class="hx:absolute hx:-mt-20" id="why-i-chose-rocketchat"></span>
    <a href="#why-i-chose-rocketchat" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>With the cost reasoning out of the way, then it&rsquo;s a matter of choosing which alternative to use.</p>
<p>I tried <a href="https://www.mattermost.org/"target="_blank" rel="noopener">MatterMost</a> first and I really wanted to like it. It has a very similar feature set to Slack and most importantly, it&rsquo;s written in Go. So it&rsquo;s both lightweight, very fast, and not so difficult to contribute. It uses MySQL or PostgreSQL which I like.</p>
<p>Unfortunatelly, it has an important <strong>show-stopper</strong> for my needs. You can create both public channels or private groups, but anyone can delete a private group. If you want permission control for that you must use their <a href="https://about.mattermost.com/pricing/"target="_blank" rel="noopener">&ldquo;Enterprise&rdquo; offering</a> and pay <strong>USD 20/year per user</strong>.</p>
<blockquote>
  <p>It&rsquo;s still at least <strong>3 times cheaper</strong> than Slack, so it may be a good option for you.</p>

</blockquote>
<p>I really want to have full-control, not just make it cheaper. I could pay Slack already if I didn&rsquo;t care, so I would not just pay an alternative and not have full-control (including the ability to tweak and improve the entire code base).</p>
<p>Then, it took me back to <a href="https://rocket.chat/"target="_blank" rel="noopener">Rocket.chat</a>. It&rsquo;s feature set also rivals Slack, it&rsquo;s good looking enough. But, it&rsquo;s made in Meteor. Now, I don&rsquo;t have anything against Meteor and I really think a Slack-clone is exactly the kind of use case where you could use Meteor to its full potential.</p>
<p>Technically I really think it&rsquo;s a downside to be forced to use Mongodb (Meteor requires Mongo). For small installations I really prefer to have PostgreSQL. MongoDB is competent, but for medium to big installations, and I will show you why below.</p>
<p>I <strong>strongly dislike</strong> the <a href="https://medium.com/friendship-dot-js/i-peeked-into-my-node-modules-directory-and-you-wont-believe-what-happened-next-b89f63d21558#.8jd3z3n6u"target="_blank" rel="noopener">culture of writing software without <em>minimal care</em></a> such as having a reasonably complete test suite. You browse through the many packages that comprise Rocket.chat and several of them have no tests whatsoever. Some packages do have jasmine tests, but the majority is lacking.</p>
<p>This is <a href="https://github.com/RocketChat/Rocket.Chat/blob/a5cb22bb0017f4c39654bf1e2895ae64acb0339b/packages/rocketchat-katex/tests/jasmine/client/unit/katex.spec.coffee"target="_blank" rel="noopener">one example</a> I picked randomly, out of the few test files I found:</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-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">describe</span> <span class="s1">&#39;rocketchat:katex Client&#39;</span><span class="p">,</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">it</span> <span class="s1">&#39;should exist&#39;</span><span class="p">,</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nx">expect</span><span class="p">(</span><span class="nx">RocketChat</span><span class="p">.</span><span class="nx">katex</span><span class="p">).</span><span class="nx">toBeDefined</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>
<p>This is sad, sorry to say that, but it is. Not surprisingly I&rsquo;ve seen katex issues while using the interface. And if you think this was just a poor choice, I picked <a href="https://github.com/RocketChat/Rocket.Chat/blob/a5cb22bb0017f4c39654bf1e2895ae64acb0339b/packages/rocketchat-markdown/tests/jasmine/client/unit/markdown.spec.coffee"target="_blank" rel="noopener">another test file</a>:</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-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">describe</span> <span class="s1">&#39;rocketchat:markdown Client&#39;</span><span class="p">,</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">it</span> <span class="s1">&#39;should exist&#39;</span><span class="p">,</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nx">expect</span><span class="p">(</span><span class="nx">RocketChat</span><span class="p">.</span><span class="nx">Markdown</span><span class="p">).</span><span class="nx">toBeDefined</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>
<p>Really?</p>
<p>So, the code itself is not so pretty, you have to keep this in mind. I&rsquo;d much rather use Mattermost (which is much better structured and with enough tests), but it&rsquo;s not entirely free, so it&rsquo;s not an option to me. For my scenario, I&rsquo;d rather have sloppy code (that minimally &ldquo;works&rdquo;) that I can tweak than code I can&rsquo;t see, for this particular venture. Many inexperienced developers may argue about the necessity of having automated tests, but not having them also impacts this:</p>
<p><img src="https://akitaonrails.s3.amazonaws.com/assets/image_asset/image/552/big_Contributors_to_RocketChat_Rocket_Chat.png" alt="Rocket.chat contribution graph"  loading="lazy" /></p>
<p>If we see how the project is evolving over time, we can see that interest is diminishing. The lack of good automated tests also make it more difficult for new people to contribute without adding regressions, make contribution reviews more difficult and time consuming.</p>
<p>On the other hand the feature set is good enough as it is. There is only so much you can add to a Slack-clone. The upside is that if the code doesn&rsquo;t change too much, I can tweak it more without having many things breaking all the time. It&rsquo;s the complete opposite from the impressive contribution boost over at GitLab, for example.</p>
<p>Doing a few days of testing through the administration settings, user interface, having dozens of users doing real conversation, convinced me that even though the code quality is bad, the feature set is indeed there. I think I can live with that. Your mileage may vary though.</p>
<p>I am using <a href="http://meetfranz.com"target="_blank" rel="noopener">Franz</a> to open Slack, Rocket.chat, Hangouts, Messenger and any number of other communicators in one single app, which is great. And Rocket.chat does provide <a href="https://itunes.apple.com/us/app/rocket.chat/id1028869439?mt=8"target="_blank" rel="noopener">mobile</a> <a href="https://play.google.com/store/apps/details?id=com.konecty.rocket.chat&amp;hl=en"target="_blank" rel="noopener">apps</a> based off PhoneGap. Again, it&rsquo;s good, not great.</p>
<p>Many people have heavy bots or integrations into their Slack configuration. The alternatives such as Rocket.chat do support incoming and outgoing webhooks and most of the integrations should be possible (with some tweaking and hacking such as this <a href="https://github.com/FinndropStudios/GifRocket"target="_blank" rel="noopener">Giphy example</a>), so make a list of all important integrations and do a Google research on that before continuing.</p>
<h2>Planning the Infrastructure<span class="hx:absolute hx:-mt-20" id="planning-the-infrastructure"></span>
    <a href="#planning-the-infrastructure" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>All that having being said, I&rsquo;d recommend you try Rocket.chat&rsquo;s <a href="https://demo.rocket.chat"target="_blank" rel="noopener">demo server</a> first to see if it has the minimal features you need. And also that you install a dry-run in a small Digital Ocean box with the intention to blow it off later.</p>
<p>For a single-instance, stand-alone installation, temporary dry-run, I recommend you start by installing the <a href="https://www.digitalocean.com/community/tutorials/how-to-use-the-mongodb-one-click-application"target="_blank" rel="noopener">MongoDB One-Click Application</a> and follow <a href="https://www.digitalocean.com/community/tutorials/how-to-install-configure-and-deploy-rocket-chat-on-ubuntu-14-04"target="_blank" rel="noopener">this instruction</a> to install everything in one machine.</p>
<p>This is the worst possible production environment, which is why I am being so repetitive into saying that you should destroy this box after you do your testing.</p>
<p>As I&rsquo;ve said before, I am assuming a scenario where you have 50 or more people, with real clients, important communication going on. You don&rsquo;t want to keep a simple installation like this for production usage.</p>
<p>For a <strong>minimal production installation</strong> you will need at the very least 4 boxes with 1 GB of RAM each. Now, why 4?</p>
<p>This is an important section for most of the beginner Javascript programmers out there playing with the so called &ldquo;MEAN&rdquo; stack (MongoDB, Express, Angularjs, Node.js). I&rsquo;ve seen people deploy single-instance, stand-alone &ldquo;MEAN&rdquo; apps for production usage. And this is super bad.</p>
<blockquote>
  <p><strong>MongoDB is NOT MEANT to function with just one single instance!</strong></p>

</blockquote>
<p>More than that:</p>
<blockquote>
  <p><strong>DO NOT start an even number of MongoDB nodes, or at least install an Arbiter</strong></p>

</blockquote>
<p>So, the minimal setup for MongoDB is a <a href="https://docs.mongodb.com/manual/core/replica-set-architecture-three-members/"target="_blank" rel="noopener">Three-member Replica Set</a>, no less!</p>
<p>The article <a href="https://www.rainforestqa.com/blog/2012-11-05-mongodb-gotchas-and-how-to-avoid-them/"target="_blank" rel="noopener">&ldquo;MongoDB Gotchas &amp; How To Avoid Them&rdquo;</a> is a little bit old but you should be aware of several of the documented gotchas, including adding replica sets and avoid waiting too long to start sharding you data.</p>
<p>The most important part of making Rocket.chat reliable is to make your MongoDB minimally reliable, and this is a hidden cost you must consider.</p>
<h4>Installing a Three-Member Replica Set<span class="hx:absolute hx:-mt-20" id="installing-a-three-member-replica-set"></span>
    <a href="#installing-a-three-member-replica-set" class="subheading-anchor" aria-label="Permalink for this section"></a></h4><p>For the sake of this article I will assume that you created 3 (three) MongoDB One-Click Applications on Digital Ocean&rsquo;s at the very least 1 GB RAM boxes (2 GB RAM machines are a good choice if you&rsquo;re in doubt, but never the 512 Mb) and another bare Ubuntu 14.04 box to be the web server. Create all machines in the same sub-region, all of them with private networking and backup enabled.</p>
<p>Take note of the public IPs and private IPs, for the sake of this article let&rsquo;s say you have this:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>Public IP     Private IP    Hostname

192.160.10.1  10.0.0.1      mongo1.yourdomain.com
192.160.10.2  10.0.0.2      mongo2.yourdomain.com
192.160.10.3  10.0.0.3      mongo3.yourdomain.com
192.160.10.4  10.0.0.4      yourdomain.com</code></pre></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>In the commands and code snippets below, make sure to replace the fake IPs for your own private IPs.</p>
<p>As I said in <a href="http://www.akitaonrails.com/2016/08/03/migrando-para-o-gitlab-sim-vale-a-pena?"target="_blank" rel="noopener">my GitLab post</a>, create a swap file, configure the locale, set it up for automatic security updates, and do upgrade the Ubuntu packages.</p>
<p>The next first thing: configure the firewall in all machines (assuming <code>ufw</code> package is already installed):</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow https
sudo ufw allow ssh
sudo ufw allow in on eth1 to any port 27017
sudo ufw enable</code></pre></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>We are allowing MongoDB&rsquo;s 27017 port only for machines in the same private networking (through eth1, the public IP go through eth0). We&rsquo;re also allowing port 22 for SSH and although I am not listing it here in this article you should also consider installing and configuring <a href="https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-ubuntu-14-04"target="_blank" rel="noopener">fail2ban</a>. Digital Ocean also has a <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-14-04"target="_blank" rel="noopener">good post on UFW</a> for more details.</p>
<p>Next thing to do on the MongoDB machines is to <a href="https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/"target="_blank" rel="noopener">Disable Transparent Huge Pages (THP)</a>. For that create a file <code>/etc/init.d/disable-transparent-hugepages</code>, with this content:</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/sh
</span></span></span><span class="line"><span class="cl"><span class="c1">### BEGIN INIT INFO</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Provides:          disable-transparent-hugepages</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Required-Start:    $local_fs</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Required-Stop:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># X-Start-Before:    mongod mongodb-mms-automation-agent</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Default-Start:     2 3 4 5</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Default-Stop:      0 1 6</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Short-Description: Disable Linux transparent huge pages</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Description:       Disable Linux transparent huge pages, to improve</span>
</span></span><span class="line"><span class="cl"><span class="c1">#                    database performance.</span>
</span></span><span class="line"><span class="cl"><span class="c1">### END INIT INFO</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="nv">$1</span> in
</span></span><span class="line"><span class="cl">  start<span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="o">[</span> -d /sys/kernel/mm/transparent_hugepage <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">      <span class="nv">thp_path</span><span class="o">=</span>/sys/kernel/mm/transparent_hugepage
</span></span><span class="line"><span class="cl">    <span class="k">elif</span> <span class="o">[</span> -d /sys/kernel/mm/redhat_transparent_hugepage <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">      <span class="nv">thp_path</span><span class="o">=</span>/sys/kernel/mm/redhat_transparent_hugepage
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="m">0</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">echo</span> <span class="s1">&#39;never&#39;</span> &gt; <span class="si">${</span><span class="nv">thp_path</span><span class="si">}</span>/enabled
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s1">&#39;never&#39;</span> &gt; <span class="si">${</span><span class="nv">thp_path</span><span class="si">}</span>/defrag
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">unset</span> thp_path
</span></span><span class="line"><span class="cl">    <span class="p">;;</span>
</span></span><span class="line"><span class="cl"><span class="k">esac</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>Now you can register it as a service:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo chmod 755 /etc/init.d/disable-transparent-hugepages
sudo update-rc.d disable-transparent-hugepages defaults
sudo /etc/init.d/disable-transparent-hugepages start</code></pre></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>Stop MongoDB in all 3 machines:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo service mongod stop</code></pre></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>Now comes a complicated procedure that you should not do wrong. It&rsquo;s only complicated because you have to do it in all 4 machines minding their correct private IP addresses. If you already have your own DNS server, you can skip this, otherwise follow through carefully.</p>
<p>You will have to edit both <code>/etc/hostname</code> and <code>/etc/hosts</code>. Each machine will have a particular name and they should be able to find the other machines by name. Let&rsquo;s start by editing the <code>/etc/hostname</code> on each machine. Use the table in the beginning of this section, for example, in the machine with public IP <code>192.160.10.1</code> you must edit it&rsquo;s hostname to be <code>mongo1.yourdomain.com</code>, and so on for all the machines.</p>
<p>Once you have it done, you have to replace the line <code>127.0.0.1 localhost</code> in the <code>/etc/hosts</code> in each of them for the following:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>127.0.0.1 localhost mongo1.yourdomain.com
10.0.0.1 mongo1.yourdomain.com
10.0.0.2 mongo2.yourdomain.com
10.0.0.3 mongo3.yourdomain.com
10.0.0.4 yourdomain.com</code></pre></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>This snippet assumes you&rsquo;re in the machine with private IP <code>10.0.0.1</code>, of course. Make sure you change <code>mongo1.yourdomain.com</code> in the first line for the hostname of the machine you&rsquo;re in. If this is too difficult for you, you definitely should not try to maintain your own infrastructure, so beware.</p>
<p>Finally, let&rsquo;s edit the <code>/etc/mongod.conf</code> with these changes:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>storage:
  dbPath: /mongodb-data
...
net:
  port: 27017
  bindIp: 0.0.0.0
...
replication:
  replSetName: rs0</code></pre></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>This should be exactly the same in all machines. And you must create this <code>/mongodb-data</code> directory like this:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo mkdir /mongodb-data
sudo chown -R mongodb:mongodb /mongodb-data</code></pre></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>Now go ahead on machine <code>mongo1.yourdomain.com</code>, start up with <code>sudo service mongod start</code> and fire up the <code>mongo</code> command, and you should see something like this:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># mongo
MongoDB shell version: 3.2.8
connecting to: test
&gt;</code></pre></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>Let&rsquo;s now configure the replica set by issuing this command in the MongoDB command-line interface:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>rs.initiate()
rs.add(&#39;mongo2.yourdomain.com&#39;)
rs.add(&#39;mongo3.yourdomain.com&#39;)</code></pre></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>And you can now log in to the secondary machines and <code>sudo service mongod start</code> in all of them. They should all start joining the replica set and syncing.</p>
<p>You can check the status of the replication like this:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>&gt; rs.conf()

{
  &#34;set&#34; : &#34;rs0&#34;,
  &#34;date&#34; : ISODate(&#34;2016-08-09T17:33:10.466Z&#34;),
  &#34;myState&#34; : 1,
  &#34;term&#34; : NumberLong(-1),
  &#34;heartbeatIntervalMillis&#34; : NumberLong(2000),
  &#34;members&#34; : [
    {
      &#34;_id&#34; : 1,
      &#34;name&#34; : &#34;mongo1.yourdomain.com:27017&#34;,
      &#34;health&#34; : 1,
      &#34;state&#34; : 1,
      &#34;stateStr&#34; : &#34;PRIMARY&#34;,
      &#34;uptime&#34; : 11727,
      &#34;optime&#34; : Timestamp(1470763990, 3),
      &#34;optimeDate&#34; : ISODate(&#34;2016-08-09T17:33:10Z&#34;),
      &#34;electionTime&#34; : Timestamp(1470752553, 1),
      &#34;electionDate&#34; : ISODate(&#34;2016-08-09T14:22:33Z&#34;),
      &#34;configVersion&#34; : 6,
      &#34;self&#34; : true
    },
    {
      &#34;_id&#34; : 2,
      &#34;name&#34; : &#34;mongo2.yourdomain.com:27017&#34;,
      &#34;health&#34; : 1,
      &#34;state&#34; : 2,
      &#34;stateStr&#34; : &#34;SECONDARY&#34;,
      &#34;uptime&#34; : 11693,
      &#34;optime&#34; : Timestamp(1470763988, 4),
      &#34;optimeDate&#34; : ISODate(&#34;2016-08-09T17:33:08Z&#34;),
      &#34;lastHeartbeat&#34; : ISODate(&#34;2016-08-09T17:33:10.026Z&#34;),
      &#34;lastHeartbeatRecv&#34; : ISODate(&#34;2016-08-09T17:33:08.887Z&#34;),
      &#34;pingMs&#34; : NumberLong(0),
      &#34;syncingTo&#34; : &#34;mongo3.yourdomain.com:27017&#34;,
      &#34;configVersion&#34; : 6
    },
    {
      &#34;_id&#34; : 3,
      &#34;name&#34; : &#34;mongo3.yourdomain.com:27017&#34;,
      &#34;health&#34; : 1,
      &#34;state&#34; : 2,
      &#34;stateStr&#34; : &#34;SECONDARY&#34;,
      &#34;uptime&#34; : 11693,
      &#34;optime&#34; : Timestamp(1470763988, 4),
      &#34;optimeDate&#34; : ISODate(&#34;2016-08-09T17:33:08Z&#34;),
      &#34;lastHeartbeat&#34; : ISODate(&#34;2016-08-09T17:33:09.994Z&#34;),
      &#34;lastHeartbeatRecv&#34; : ISODate(&#34;2016-08-09T17:33:08.655Z&#34;),
      &#34;pingMs&#34; : NumberLong(0),
      &#34;syncingTo&#34; : &#34;mongo1.yourdomain.com:27017&#34;,
      &#34;configVersion&#34; : 6
    }
  ],
  &#34;ok&#34; : 1
}</code></pre></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>Each box should be syncing data to another box, one of them will be marked &ldquo;PRIMARY&rdquo; and the others will be &ldquo;SECONDARY&rdquo;. If one of them &ldquo;dies&rdquo; for some reason, one of the others will be elected as PRIMARY until you add a replacement box. Read more details on this procedure in <a href="https://www.digitalocean.com/community/tutorials/how-to-implement-replication-sets-in-mongodb-on-an-ubuntu-vps"target="_blank" rel="noopener">Digital Ocean&rsquo;s post about implementing replication sets</a>.</p>
<h4>Adding your MongoDB environment to MMS<span class="hx:absolute hx:-mt-20" id="adding-your-mongodb-environment-to-mms"></span>
    <a href="#adding-your-mongodb-environment-to-mms" class="subheading-anchor" aria-label="Permalink for this section"></a></h4><p>Another thing beginners will not realise is that it&rsquo;s a good idea to monitor your services. At the very least you should install MongoDB Cloud Manager agents into your servers. Just set up an account at <a href="https://www.mongodb.com/cloud"target="_blank" rel="noopener">MongoDB Atlas</a>.</p>
<p>It&rsquo;s beyond the point of this article to explain Atlas, but you should have no trouble installing the agents with the Group ID and API Key provided. Then install the monitoring agent and have the Manager figure out your existing deployment and replica set.</p>
<p>The basic subscription for monitoring will cost you an extra USD 39 a month, but believe me when I say it&rsquo;s worth to add all your MongoDB deployments under MMS.</p>
<p><img src="https://akitaonrails.s3.amazonaws.com/assets/image_asset/image/553/big_Deployment___Cloud_Manager__MongoDB_Cloud_Manager.png" alt="MMS"  loading="lazy" /></p>
<p><img src="https://akitaonrails.s3.amazonaws.com/assets/image_asset/image/554/big_Host___Cloud_Manager__MongoDB_Cloud_Manager.png" alt="Replica Set Graphs"  loading="lazy" /></p>
<h4>Installing a multi-instance Node.js service<span class="hx:absolute hx:-mt-20" id="installing-a-multi-instance-nodejs-service"></span>
    <a href="#installing-a-multi-instance-nodejs-service" class="subheading-anchor" aria-label="Permalink for this section"></a></h4><p>Another mistake beginners in the MEAN stack do is to start up a single Node.js instance. Yes, Node.js asynchronous I/O nature makes it &ldquo;concurrent enough&rdquo; in 1 single thread. But you do want to maximize the rented machine so you should spin up at least one Node.js instance for each CPU core. A 1 GB RAM machine has just 1 core, but you can spin up at least 2 instances.</p>
<p>First of all, we must set up the <code>yourdomain.com</code> (<code>192.160.10.4</code> or <code>10.0.0.4</code> in the example) to support Node.js, let&rsquo;s do it:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo apt-get install -y npm curl graphicsmagick nginx git bc
sudo npm install -g n
sudo npm install -g forever
sudo npm install -g forever-service
sudo n 0.10.40</code></pre></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>If you haven&rsquo;t already, <a href="https://www.digitalocean.com/community/tutorials/how-to-create-a-sudo-user-on-ubuntu-quickstart"target="_blank" rel="noopener">create a more restricted sudo user</a>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>adduser rocket # add a password when asked
usermod -aG sudo rocket
su - rocket # and always ssh in with `ssh rocket@yourdomain.com`</code></pre></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>Within rocket&rsquo;s home directory let&rsquo;s install the Rocket.chat codebase:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>cd /home/rocket
curl -L https://rocket.chat/releases/latest/download -o rocket.chat.tgz
tar zxvf rocket.chat.tgz
mv bundle Rocket.Chat
cd Rocket.Chat/programs/server
npm install</code></pre></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>And now let&rsquo;s add a way for the machine to start the Rocket.chat whenever it reboots:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>cd ~/Rocket.Chat
sudo forever-service install -s main.js -e &#34;ROOT_URL=https://rocketchat42.com/ MONGO_URL=mongodb://mongo1.yourdomain.com:27017/rocketchat MONGO_OPLOG_URL=mongodb://mongo1.yourdomain.com:27017/local PORT=3001&#34; rocketchat1
sudo forever-service install -s main.js -e &#34;ROOT_URL=https://rocketchat42.com/ MONGO_URL=mongodb://mongo1.yourdomain.com:27017/rocketchat MONGO_OPLOG_URL=mongodb://mongo1.yourdomain.com:27017/local PORT=3002&#34; rocketchat2

sudo start rocketchat1
sudo start rocketchat2</code></pre></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>Let&rsquo;s also create SSL certificates (and for that you must have a properly registered domain, of course). Again, <a href="https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-14-04"target="_blank" rel="noopener">Digital Ocean&rsquo;s documentation on Let&rsquo;s Encrypt</a> is very good. In summary, all you have to do is:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt</code></pre></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>Now edit the <code>/etc/nginx/sites-available/default</code> and add this inside the server block:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>server {
  ...
  location ~ /.well-known {
          allow all;
  }
  ...
}</code></pre></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>Now you can:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo service nginx reload

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

cd /opt/letsencrypt
./letsencrypt-auto certonly -a webroot --webroot-path=/usr/share/nginx/html -d yourdomain.com -d www.yourdomain.com</code></pre></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>Again, replace <code>yourdomain.com</code> with your own registered domain, of course. The <code>letsencrypt</code> command will prompt you to enter your e-mail address and accept terms of service.</p>
<p><a href="https://letsencrypt.org/"target="_blank" rel="noopener">Let&rsquo;s Encrypt</a> is a fantastic free SSL provider. Their certificates are short lived and are meant to expire in 90 days, so you must set up auto-renewal. Start <code>sudo crontab -e</code> and add the following lines:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>30 2 * * 1 /opt/letsencrypt/letsencrypt-auto renew &gt;&gt; /var/log/le-renew.log
35 2 * * 1 /etc/init.d/nginx reload</code></pre></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>This should take care of SSL. Now you can edit your <code>/etc/nginx/sites-available/default</code> and replace it with this template:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># Upstreams
upstream backend {
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
}

server {
  listen 443 ssl;

  server_name yourdomain.com;

  ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_dhparam /etc/ssl/certs/dhparam.pem;
  ssl_ciphers &#39;ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH&#43;AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA&#39;;
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_stapling on;
  ssl_stapling_verify on;
  add_header Strict-Transport-Security max-age=15768000;

  location / {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection &#34;upgrade&#34;;
    proxy_set_header Host $http_host;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forward-Proto http;
    proxy_set_header X-Nginx-Proxy true;

    proxy_redirect off;
  }

}

server {
  listen 80;
  server_name yourdomain.com www.yourdomain.com;
  return 301 https://$host$request_uri;
}</code></pre></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>Just for the sake of completeness, again: replace <code>yourdomain.com</code> for your domain. Usually the <code>/etc/nginx/sites-enabled/default</code> is a symlink to <code>/etc/nginx/sites-available/default</code>, just check that as well. This configuration will load balance between the 2 node.js instances we configured and started before. And you can add as many as you want following the same <code>forever-install</code> procedure and adding the new instances to the <code>upstream</code> section in the nginx configuration above.</p>
<p>If everything is correct, you can restart nginx again: <code>sudo service nginx restart</code>.</p>
<p>And now you should have <code>https://yourdomain.com</code> already up and running. The first user that sign up will be the site administrator and from there you can customize Rocket.chat internally.</p>
<h2>Conclusion<span class="hx:absolute hx:-mt-20" id="conclusion"></span>
    <a href="#conclusion" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>As you can see, this is not a simple procedure to follow and I am assuming you have experience managing your own infrastructure. If you don&rsquo;t you definitely should NOT do this by yourself.</p>
<p>If you do it correctly, you should have a functional Slack-clone with minimal reliability (thanks in large part to Digital Ocean) and minimal cost (USD 80/month in the configuration I described that should be enough for more than a 100 users). Rocket.chat also offer more <a href="https://rocket.chat/docs/installation/"target="_blank" rel="noopener">documentation</a> for other environments including Docker configurations you might want to try. But the procedure above is sufficient for my needs.</p>
<p>I said it already but it&rsquo;s better to repeat it: don&rsquo;t fall for the trap of installing everything in a single box, with single instance MongoDB, and without proper monitoring. It&rsquo;s asking for trouble.</p>
<p>For now I am in the middle of the roll out. All developers in my company are already in the new deployment and soon half of the clients should also migrate (some will not be able to leave Slack just yet), but with Franz and the ability of full history and searchability this shoudn&rsquo;t be a concern even if a developer stays offline for some period of time.</p>
<p>I also don&rsquo;t advocate that everybody should be online and responding in real-time. It&rsquo;s unfeasible, unproductive, creates unnecessary tension. People should participate when they have free time, and they should be able to concentrate without worrying that they are missing something. That&rsquo;s why they should opt-out of being notified in the more busy channels and just enable notification on the private groups that matter.</p>
<p>Coincidentally Jason Fried just posted about concerns over group chats at <a href="https://m.signalvnoise.com/is-group-chat-making-you-sweat-744659addf7d#.3qxe09una"target="_blank" rel="noopener">Signal v. Noise</a>, but the gist is that group chat should be purposeful not yet another tool to create tension. People should definitelly get offline when they need to fully concentrate in their work and have the opportunity to catch up with interesting conversations later. And really important communication should go through e-mail or other tradicional ways, a simple <code>@all</code> don&rsquo;t cut it for company-wide announcements for example.</p>
<p>I hope this exercise gives you more perspective on what you can have and also raise awareness on the need for companies to regain more control over their own data, particularly knowledge. Erase your communication channels and you&rsquo;re losing years-worth of knowledge that can be invaluable.</p>
]]></content:encoded><category>reviews</category><category>devops</category><category>bancos-de-dados</category></item><item><title>Off Topic: "I am Legend" - HORRÍVEL!</title><link>https://akitaonrails.github.io/2008/01/19/off-topic-i-am-legend-horrvel/</link><guid isPermaLink="true">https://akitaonrails.github.io/2008/01/19/off-topic-i-am-legend-horrvel/</guid><pubDate>Sat, 19 Jan 2008 02:46:00 -0200</pubDate><description>&lt;p&gt;&lt;strong&gt;DISCLAIMER:&lt;/strong&gt; Este artigo tem &lt;strong&gt;SPOILERS&lt;/strong&gt;; se você se incomoda com isso, não leia. Acho uma bobagem, mas em todo caso, eu avisei.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://s3.amazonaws.com/akitaonrails/assets/2008/1/19/photo_18.jpg" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;Faz tempo que não faço um off topic assim, mas hoje estou tão indignado que resolvi escrever.&lt;/p&gt;
&lt;p&gt;Depois de ler boas críticas (preciso mudar minhas fontes), resolvi arriscar e assistir &lt;a href="http://en.wikipedia.org/wiki/I_Am_Legend_%28film%29"target="_blank" rel="noopener"&gt;I Am Legend&lt;/a&gt;, que estreou recentemente por aqui. Gostei muito do último filme do Will Smith, &lt;a href="http://en.wikipedia.org/wiki/Pursuit_of_happyness"target="_blank" rel="noopener"&gt;The Pursuit of Happyness&lt;/a&gt;, e disseram que ele faz a linha dramática de novo. Por isso me motivei a tentar.&lt;/p&gt;</description><content:encoded><![CDATA[<p><strong>DISCLAIMER:</strong> Este artigo tem <strong>SPOILERS</strong>; se você se incomoda com isso, não leia. Acho uma bobagem, mas em todo caso, eu avisei.</p>
<p><img src="http://s3.amazonaws.com/akitaonrails/assets/2008/1/19/photo_18.jpg" alt=""  loading="lazy" /></p>
<p>Faz tempo que não faço um off topic assim, mas hoje estou tão indignado que resolvi escrever.</p>
<p>Depois de ler boas críticas (preciso mudar minhas fontes), resolvi arriscar e assistir <a href="http://en.wikipedia.org/wiki/I_Am_Legend_%28film%29"target="_blank" rel="noopener">I Am Legend</a>, que estreou recentemente por aqui. Gostei muito do último filme do Will Smith, <a href="http://en.wikipedia.org/wiki/Pursuit_of_happyness"target="_blank" rel="noopener">The Pursuit of Happyness</a>, e disseram que ele faz a linha dramática de novo. Por isso me motivei a tentar.</p>
<p>O começo do filme é muito bom. A fotografia é ótima, a edição é rápida e dinâmica. E apesar de o Will Smith ser praticamente o único ator em cena na maior parte do tempo, ele faz um bom trabalho. A equipe técnica recriou muito bem uma Nova Iorque deserta, e os momentos de tensão funcionam. Enfim, todos os truques do manual foram usados.</p>
<p>Porém, quando um dos monstros aparece pela primeira vez, já começa a decepcionar: me lembrou os horrorosos efeitos especiais de filmes como O Retorno da Múmia. Numa época pós-Matrix, pós-Lord of the Rings, não há mais desculpa para criar monstros tão ruins. Mesmo assim, isso ainda é perdoável.</p>
<p>A outra coisa ruim é que a história se baseia superficialmente no livro de <a href="http://en.wikipedia.org/wiki/I_Am_Legend"target="_blank" rel="noopener">Richard Matheson</a>. Uma adaptação superficial não era difícil de prever, mas o filme vinha criando uma boa tensão e estava divertido. Por isso mesmo o terceiro ato decepcionou em dobro. A sequência inteira que envolve a Alice Braga é descartável.</p>
<p>Começa com uma piadinha que até hoje não entendi. A personagem da Alice, Anna, diz que veio de São Paulo. No meio da conversa, o Robert, personagem do Will, pergunta se ela conhece Bob Marley. E ela faz uma cara de quem <em>“nunca ouviu falar”</em>. Ela diz isso com todas as letras!</p>
<p>Ok, a história se passa em 2012, não é tão longe assim. Até eu, praticamente um analfabeto em música, conheço Bob Marley e a música que tocou no filme. O que eles querem dizer com isso? <em>“No Brasil só tem floresta e ninguém aqui nunca ouviu falar de Bob Marley?”</em> Não é importante, mas achei esquisito. Dou o benefício da dúvida porque pode ser que eu não tenha entendido a piada. Vai saber.</p>
<p>Agora, a parte do <em>“Deus me enviou”</em> &hellip; não, não, so fucking sorry! Não deu pra engolir. O que isso tem a ver com a história?? Pior: a história levou isso a sério!! A tal Anna <em>“passou a ouvir melhor os sinais dos céus”</em>. Ela apareceu para salvar o Robert no instante em que ele seria morto, ouviu a mensagem de rádio dele porque recebeu um sinal divino, e sabe, simplesmente sabe, que existe uma colônia de sobreviventes, com endereço e tudo, mais eficiente que o Google Maps, porque <em>Deus lhe disse</em> &hellip; oh well &hellip;</p>
<p>E no final o cara realmente tem uma <em>visão</em> divina e resolve morrer! E a tal colônia realmente existe! Nossa. Detesto quando o filme começa a se achar demais.</p>
<p><img src="http://s3.amazonaws.com/akitaonrails/assets/2008/1/19/iald-06397.jpg" alt=""  loading="lazy" /></p>
<p>Me deixou um gosto pior que outro horroroso: Signs, do M. Night Shyamalan. Foi a mesma coisa: o filme começa com clima sério, explora a tensão, vai muito bem até desandar de vez, também no terceiro ato. A mulher morrendo passa uma mensagem dos céus: <em>“oh, mande girar o taco &hellip;”</em> E eles <strong>mostram</strong> os alienzinhos verdes!! E o cara gira o bastão e salva o mundo!</p>
<p>God damn! Ok, I Am Legend não tem nada a ver com o livro de mesmo nome. O livro termina de um jeito completamente diferente, e o tema é outro, bem mais interessante. Se for assistir ao filme, quando a Anna aparecer, saia do cinema. Até ali é um filme razoável; depois disso, prepare-se para uma grande decepção.</p>
<p>Estou chocado com a falta de qualidade da história. Akiva Goldsman trabalhou no screenplay, o que explica muita coisa: é a mesma pessoa que conseguiu estragar a adaptação do Código Da Vinci.</p>
<p>Já vi filmes ruins às dezenas, mas eles sabem que são ruins e não se levam tão a sério. Veja Resident Evil: medíocre, ciente disso, e pelo menos divertido pra assistir num domingo à tarde. Esse filme promete um bocado no começo e no final parece aquele cara que se vira e diz <em>“nhé, nhé, nhé, te enganei!”</em></p>
<p>A equipe de marketing desse filme é muito boa! Conseguiu extrair muitas boas críticas de muitos lugares. Mesmo no <a href="http://www.rottentomatoes.com/m/i_am_legend/"target="_blank" rel="noopener">Rotten Tomatoes</a> ele conseguiu 68% de aprovação! Muito mais do que merece. Qualquer coisa acima de um dígito, numa escala de zero a cem, já é demais.</p>
<p>O próximo filme de que estão falando bem, já gerando certo hype, é o <a href="http://web.archive.org/web/20080224041006/http://www.cloverfieldmovie.com/"target="_blank" rel="noopener">Cloverfield</a>. Resta saber se é tão bom quanto dizem.</p>
]]></content:encoded><category>cinema-e-cultura-pop</category><category>reviews</category><category>off-topic</category></item></channel></rss>