Há menos de um mês escrevi um post inteiro explicando como usar três camadas de memória com Claude Code: Linear para estratégia, Beads para tática e Tasks para execução. Uma pirâmide bonita e elegante.

Pois é, não rolou.

Hoje aposento o Beads. E não por capricho, mas porque a realidade se encarregou de demonstrar que uma ferramenta que te dá mais problemas do que resolve não é uma ferramenta. É um peso morto.

O que o Beads oferecia

Para quem não leu o post original, Beads era um issue tracker com base no git. Um plugin para Claude Code que armazenava issues em arquivos JSONL dentro do seu repo. A ideia era brilhante na teoria:

  • Persistência no git: os issues viviam em .beads/ e faziam commit junto com seu código.
  • Dependências: um issue podia bloquear outro.
  • Offline: funcionava sem conexão.
  • O LLM via diretamente: sem APIs, sem configuração. O agente lia os arquivos e pronto.

A promessa: uma camada intermediária entre “o que quero fazer esta semana” (Linear) e “o que estou fazendo agora” (Tasks). A cola tática.

O que deu errado

Tudo foi bem até que parou de funcionar. E parou de funcionar de maneiras criativas.

O daemon do inferno

Beads roda um daemon em background para gerenciar a base de dados SQLite e sincronizar com git. Parece razoável. Na prática:

DATABASE MISMATCH DETECTED!

This database belongs to a different repository:
  Database repo ID:  d1f9ca0c
  Current repo ID:   01eac8ea

⚠️ CRITICAL: This mismatch can cause beads to incorrectly
   delete issues during sync!

Essa mensagem aparece ao iniciar qualquer sessão. O daemon falha, a sincronização falha, e você fica com issues que existem no seu SQLite local mas não no git, ou vice-versa. Um estado quântico de bugs: seus issues existem e não existem ao mesmo tempo.

A sincronização fantasma

bd sync é o comando para sincronizar seus issues com o git remoto. Exceto quando não funciona:

→ Pulling from remote...
Error: pulling: git pull failed: exit status 1
remote: Repository not found
fatal: repository 'https://git.frr.dev/frr/wuwei.git/' not found

Acontece que o beads pega o remote do git, mas se você tem vários remotes (coisa comum), pode escolher o errado. E se esse remote aponta para um repo que não existe ou mudou de nome, o daemon cospe erros em cada operação. Silenciosamente, seus issues param de sincronizar e você só descobre quando abre outra sessão e tudo sumiu.

O custo cognitivo

Cada sessão com Claude Code começava assim:

  1. Claude lê o prompt do beads (injetado via hooks)
  2. O daemon tenta iniciar
  3. Falha com erro de mismatch
  4. Claude tenta bd sync
  5. Falha com erro de remote
  6. Você fala “ignora isso”
  7. Agora sim, vamos trabalhar

Seis passos de atrito antes de fazer algo produtivo. Seis passos que consomem contexto, tempo e paciência.

O que mudou

Duas coisas fizeram o Beads passar de “ferramenta útil com bugs” para “overhead desnecessário”:

1. Tasks amadureceu

Quando escrevi o post das três camadas, Tasks era básico. Agora tem:

  • TaskCreate com descrições, activeForm para spinners, e metadados
  • TaskUpdate com dependências (addBlocks, addBlockedBy)
  • TaskList e TaskGet para inspeção
  • Persistência opcional entre sessões com CLAUDE_CODE_TASK_LIST_ID

Ou seja: Tasks já faz tudo que Beads fazia para o trabalho intra-sessão. E faz sem daemon, sem SQLite, sem sincronização git, e sem erros fantasma.

2. Linear CLI chegou

O MCP do Linear era, sendo generoso, uma merda. Intermitente, lento, e com uma mania especial de falhar justo quando você mais precisava.

A alternativa era a API direto com GraphQL. Que funciona, sim, até você tentar inserir caracteres especiais nas descrições dos issues:

# Tentativa 1: bash com interpolação de strings
# Resultado: JSON quebrado por parênteses e setas

# Tentativa 2: Python com urllib
# Resultado: 401 porque op read não é avaliado dentro do Python

# Tentativa 3: chorar um pouco
# Resultado: catártico mas improdutivo

E então descobri o linear CLI:

brew install schpet/tap/linear
linear auth login -k "$(op read 'op://FRR DEV/Linear/api-key')"

E criar um issue se torna:

linear issue create --team RST --no-interactive \
  -t "Port: agent/loop" \
  --project "Phase 1: Core Loop" \
  --priority 1 \
  -l port \
  -d "Port agent loop (476 LOC). Heart of the agent."

Sem escaping de GraphQL. Sem daemon. Sem sincronização quebrada. Criei 49 issues em menos de um minuto com um script bash. Com o MCP do Linear e com a API teria levado uma hora e meia brigando com escape de caracteres.

A nova pirâmide (que já não é pirâmide)

O modelo de três camadas era bonito. Mas a realidade é que duas camadas são suficientes:

NecessidadeAntesAgora
Visão estratégicaLinear (MCP/API)Linear (linear CLI)
Trabalho táticoBeadsLinear (linear CLI)
Execução em sessãoTasksTasks

Linear + seu CLI cobre estratégia e tática. Tasks cobre execução. Beads não cobre nada que as outras duas não cubram melhor.

Antes:
Linear (semanas) → Beads (dias) → Tasks (horas)

Agora:
Linear (semanas/dias) → Tasks (horas)

Menos camadas, menos atrito, menos coisas que podem quebrar.

Lição aprendida

Isso me lembra de algo que sempre falo: a complexidade desnecessária é o inimigo silencioso. Beads resolvia um problema real (a amnésia do LLM entre sessões), mas fazia isso adicionando uma camada de infraestrutura que, a longo prazo, gerava mais problemas do que resolvia.

É a mesma história de sempre na engenharia: a solução correta às vezes não é adicionar algo, mas perceber que o que você já tem melhorou o suficiente para não precisar mais dela.

O MCP do Linear era uma merda → chegou o CLI. Tasks era básico → amadureceu. Beads ficou no meio, sem espaço.

O rm -rf definitivo

rm -rf .beads/
git add -A && git commit -m "chore: remove beads"

Duas linhas. Assim se aposenta uma ferramenta. Sem cerimônia, sem drama.

Beads foi útil enquanto foi. Agora não é mais. E tudo bem.


TL;DR: Retiro Beads do meu fluxo de trabalho com Claude Code. O CLI do Linear (schpet/linear-cli) resolve o gerenciamento de issues sem as dores do MCP nem da API GraphQL. Tasks amadureceu o suficiente para cobrir o tracking intra-sessão. Duas camadas bastam: Linear para estratégia e tática, Tasks para execução.

Posts anteriores sobre o tema:


Este artigo foi escrito originalmente em espanhol e traduzido com a ajuda de IA.