Instalação e configuração dos harnesses

Downshift por Tiago Vilas Boas. Atualizado em 19 de outubro de 2026. Código-fonte no GitHub

Downshift por Tiago Vilas Boas https://github.com/tiagovilasboas/downshift

Guia de referência para pessoas e agentes de código que instalam o Downshift em uma máquina de usuário.

Relacionados: config.md · session-models.md · harness-matrix.md · examples/README.md · Guias em português

Status dos harnesses: o Claude Code está Concluído; Codex e Cursor são Funcionais; Antigravity e KiroCrew são Experimentais (veja Harnesses experimentais); o OpenCode está em Beta (o adaptador e a rota de comunicação estão neste repositório; a integração do plugin está em desenvolvimento). As seções abaixo seguem essa ordem. Definições e evidências: harness-matrix.md.

Verificação de saúde

Depois da instalação:

downshift doctor          # versão, diretório de estado (~/.downshift), fonte do catálogo
downshift try "rename userId in auth.ts" claude-code

Teste opcional do adaptador (a partir de um clone deste repositório):

./examples/run-all.sh

A descoberta de disponibilidade e a cota de uso são configuradas à parte. Veja session-discovery.md para a lista de modelos e quota.md para a ponte da barra de status nativa do Claude Code, a coleta de transcrições do Codex, a validade dos dados e o modo de cota obrigatória. Uma descoberta bem-sucedida não prova que há crédito incluído, e instalar uma ponte não prova que ela recebeu uma observação de uso em tempo real.

Quickstart: do zero a um hook funcionando em 2 minutos

Passo 1: instalar (macOS / Linux):

curl -fsSL https://raw.githubusercontent.com/tiagovilasboas/downshift/main/install.sh | sh

O instalador baixa o arquivo da versão e o checksums.txt da mesma release no GitHub e verifica o sha256 antes de instalar qualquer coisa. Se a soma não bater ou o arquivo de checksums faltar, ele para. DOWNSHIFT_SKIP_CHECKSUM=1 instala sem verificação e avisa que fez isso. As releases também estão na página de Releases, com o mesmo checksums.txt.

Proveniência do build (opcional). As releases geradas pelo job release trazem uma atestação de proveniência do build no GitHub. Depois da verificação do sha256, se a CLI gh estiver instalada, o install.sh executa gh attestation verify <arquivo> --repo tiagovilasboas/downshift e imprime Build provenance verified. Por padrão, isso nunca bloqueia: sem gh, sem gh auth login ou com uma release anterior às atestações, ele mostra um aviso e continua só com o sha256. DOWNSHIFT_REQUIRE_ATTESTATION=1 transforma qualquer resultado diferente de "verificado" em erro, e nada é instalado; DOWNSHIFT_SKIP_ATTESTATION=1 pula a checagem. No fim, o instalador diz o que ficou comprovado: "sha256 and GitHub build provenance" ou "sha256 only" (um download íntegro, mas que não prova quem publicou). Ele aceita apenas uma versão estrita vMAJOR.MINOR.PATCH[-prerelease], baixa com curl --proto '=https' --tlsv1.2 e instala por meio de um nome temporário seguido de renomeação. Manualmente: gh attestation verify downshift_<ver>_<os>_<arch>.tar.gz --repo tiagovilasboas/downshift.

O install.sh ainda trata um argumento sem flag como a versão da release. --explicit-upshift pode vir antes ou depois dessa versão. Ele grava "explicit_upshift": true em session-models.json sem remover as listas de harnesses que já estiverem ali. A mesma chave em tempo de execução é DOWNSHIFT_EXPLICIT_UPSHIFT=1. O padrão é desligado. Veja session-models.md.

Passo 2: visualizar e depois ligar os hooks:

downshift setup --dry-run   # mostra o diff de cada harness encontrado; não grava nada
downshift setup             # pergunta antes, faz backup dos arquivos e depois mescla os hooks

No Claude Code, o setup liga PreToolUse (matcher Agent|Task), PostToolUse, PostToolUseFailure e SubagentStop, configura a barra de status quando não há nenhuma, e define "model": "opusplan" (Opus em modo plan, Sonnet na execução) e "permissions": {"defaultMode": "plan"} (as sessões começam em modo plan) para as chaves que você ainda não definiu. Valores existentes são mantidos, e --no-session-policy pula as duas coisas. O mod "You should know" embutido do Claude Code ("enabledPlugins": {"cc-plugin-you-should-know@builtin": true}) é opt-in, porque cada verificação é uma requisição cobrada ao modelo da sessão: o setup mostra uma sugestão, e downshift setup --you-should-know a grava (/plugin disable cc-plugin-you-should-know@builtin a desliga) (política de sessão principal). Ele também encontra Cursor, Codex, Antigravity e KiroCrew, mantém chaves não relacionadas e hooks existentes, e é idempotente. downshift setup --undo restaura o backup mais recente. O KiroCrew (Experimental) tem um comando de configuração próprio, que gera o wrapper e o registra; veja KiroCrew. O JSON manual está em Configuração manual abaixo.

Passo 3: testar o classificador com os seus próprios prompts:

downshift doctor                                          # checklist: binário, hooks por harness, estado, pontuações
downshift try "rename the userId variable" claude-code    # o que seria escolhido, e por quê

Passo 4: confirmar que funciona. Abra uma nova sessão do Claude Code e peça para criar um subagente para uma tarefa trivial. Você verá uma linha assim no stderr:

downshift: TRIVIAL task → downshift to claude-haiku-4-5

Essa linha significa que o hook disparou e emitiu uma reescrita antes de o subagente começar. Se o harness aplicou a reescrita é outro fato. downshift stats separa rewrite_emitted de honrada, e a matriz diz o que está verificado por plano.

Confirmar que a reescrita foi honrada (importante para a validação de saída do beta):

  • Peça ao Claude Code: "spawn a subagent to rename the userId variable in auth.ts"
  • Abra os logs internos ou o monitor do Claude Code (confira o modelo real do subagente na interface)
  • Confirme que ele começou no haiku, e não no modelo de fronteira padrão da sessão
  • Isso prova que a reescrita do hook não foi só emitida: ela foi de fato aplicada pelo harness

Passo 5: ver o que aconteceu. downshift stats --days=1 mostra decisões e tokens economizados; downshift session --tree mostra os subagentes desta sessão como uma árvore. No Claude Code, o plugin expõe /downshift:status; o alias manual opcional /downshift está em O comando /downshift.

Passo 6: (opcional) acompanhar ao vivo. downshift watch redesenha a árvore de subagentes da sessão atual (modelo, status final, tokens, motivo) a cada segundo, em todos os harnesses; downshift session --tree imprime uma vez só, e /downshift:status ou /downshift mostra isso dentro do Claude Code. O widget flutuante mais antigo continua disponível: dsmon, widget de monitoramento ao vivo.

Configuração manual (Claude Code)

Use isto no lugar do setup se preferir editar ~/.claude/settings.json por conta própria. O matcher do PreToolUse é Agent|Task. O schema de Task do Claude Code aceita só nomes de família (haiku, sonnet, opus, fable) em model. O Downshift grava o nome de família do catálogo por você, e deixa o subagente como está quando um modelo não tem um.

{
  "hooks": {
    "PreToolUse": [
      { "matcher": "Agent|Task", "hooks": [{ "type": "command", "command": "downshift claude-code" }] }
    ]
  }
}

Para o status do filho e o uso real, adicione também PostToolUse e PostToolUseFailure (downshift claude-code-post-tool-use) e SubagentStop (downshift claude-code-subagent-stop), como o setup faz.

Testar localmente antes de conectar o hook

Antes de adicionar o hook ao Claude Code, teste a lógica do classificador e do hook localmente:

Teste 1: só o classificador (terminal):

downshift try "rename the userId variable" claude-code
downshift try "rearchitect the payment flow" claude-code
downshift try "implement the CSV export" claude-code

Teste 2: hook completo (JSON):

downshift claude-code < examples/claude-code-pretooluse-session.json

Isso imita exatamente o que o Claude Code vai enviar. A saída é o JSON que o harness vai aplicar, mais o retorno no stderr com a decisão e um ID de feedback para acompanhamento.

Veja examples/ para payloads de exemplo. claude-code-pretooluse-session.json traz uma lista session_models, então mostra uma reescrita de verdade.

⚠️ Só Claude Code Pro/Max/Teams/API. O plano gratuito não tem subagentes reais e bloqueia instalações pela rede. Veja Compatibilidade de planos antes de continuar.

Instalação (Claude Code)

Status: Concluído. Reescrita observada e honrada, uso e fim do filho registrados, plugin e política de sessão (evidência, auditoria de cobrança).

Gere ou instale o binário único (sem runtime, sem dependências):

# Recomendado: instalador de uma linha (macOS / Linux, detecta a arquitetura automaticamente)
# Instala em /usr/local/bin/downshift; não precisa mexer no PATH
curl -fsSL https://raw.githubusercontent.com/tiagovilasboas/downshift/main/install.sh | sh

# Alternativa: toolchain do Go (qualquer plataforma)
go install github.com/tiagovilasboas/downshift/cmd/downshift@latest

Nota sobre o toolchain do Go: go install coloca o binário em ~/go/bin. Se aparecer downshift: command not found, adicione o bin do Go ao PATH:

export PATH="$HOME/go/bin:$PATH"   # sessão atual
echo 'export PATH="$HOME/go/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc  # permanente

O instalador curl acima evita isso, porque grava direto em /usr/local/bin.

Binários pré-compilados para macOS (arm64/amd64), Linux (arm64/amd64) e Windows (amd64) estão na página de Releases.

Caminho mais rápido: o downshift setup encontra o Claude Code, o Cursor, o Codex e o Antigravity nesta máquina e mescla todos os hooks (além da barra de status do Claude Code, quando nenhuma estiver configurada) nos arquivos de hook de cada um, usando o caminho absoluto deste binário. Ele mantém as chaves não relacionadas e os hooks existentes, é idempotente, mostra um diff e salva um backup com data e hora. --dry-run não grava nada, --yes pula a pergunta, --undo restaura o backup mais recente. Para configurar o KiroCrew (Experimental), rode downshift setup kirocrew --dry-run e depois downshift setup kirocrew; o comando gera o wrapper, registra o hook nativo e instala a instrução compacta. Veja a seção KiroCrew.

Adicione o hook em ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Agent|Task",
        "hooks": [
          { "type": "command", "command": "downshift claude-code" }
        ]
      }
    ]
  }
}

É só isso. A partir da próxima sessão, cada criação de subagente passa pelo hook; se o modelo é reescrito depende da tarefa (com confiança, sem risco) e do plano (matriz de harnesses). Em trabalho natural, a maioria das criações é segurada, e isso é intencional.

Instalação pelo plugin (Claude Code)

Os mesmos quatro hooks e o comando /downshift:status vêm como um plugin do Claude Code cuja raiz é este repositório. Ele precisa do binário downshift no PATH (passo 1 acima) e substitui o passo 2 só para o Claude Code. O downshift setup faz essa instalação por você quando consegue: executa claude plugin marketplace add e claude plugin install downshift@downshift, e depois remove os hooks do Downshift que ele gravou antes no settings.json (o plugin já os traz; manter os dois faria cada criação de subagente ser roteada duas vezes). Ele só instala o plugin quando o claude está no PATH e um shell de login resolve downshift para o mesmo binário que executa o setup, porque os hooks do plugin chamam downshift pelo nome; caso contrário, continua gravando os hooks no settings.json e diz o motivo. --no-plugin sempre mantém os hooks no settings.json. Os outros harnesses continuam usando downshift setup.

/plugin install downshift --marketplace tiagovilasboas/downshift      # Claude Code 2.1.275+

ou em dois passos, /plugin marketplace add tiagovilasboas/downshift e depois /plugin install downshift@downshift. O plugin liga PreToolUse, PostToolUse, PostToolUseFailure, SubagentStop e UserPromptSubmit (para a Inteligência de Código do Downshift) a partir de hooks/hooks.json (cada entrada só chama o binário), adiciona as skills downshift-setup, downshift-audit e cost-reducer, e o comando abaixo como /downshift:status. No Claude Code 2.1.287 ou superior, ele também carrega o mod cache-tax incluído: um envio frio em um contexto de 50 mil tokens ou mais é retido uma vez, com o preço estimado da reescrita (reenvie para pagar, ou use /cache-tax guard warn para só ser avisado), e /keepwarm 90m mantém o cache aquecido durante uma pausa, com uma pequena requisição ao modelo a cada 50 minutos ociosos, o que gasta uso. Se você já instalou cache-tax@claude-code-mods, desinstale uma das cópias; o doctor avisa. O marketplace também oferece savvy-progress e filetree, uma instalação para cada (o downshift setup instala os dois no Claude Code; manualmente: /plugin install savvy-progress@downshift, /plugin install filetree@downshift; veja mods/README.md). Ele não configura opusplan, o modo plan, a barra de status nem o mod You should know: isso são configurações, não hooks, e o downshift setup as grava (You should know só com --you-should-know). Defina "model": "opusplan" e "permissions": {"defaultMode": "plan"} em ~/.claude/settings.json por conta própria (ou /model opusplan numa sessão), e /plugin enable cc-plugin-you-should-know@builtin para o You should know (uma requisição cobrada a cada verificação), se quiser isso sem o setup; veja política de sessão principal.

Use um canal só. Um hook de plugin e um hook de configuração com o mesmo comando rodam os dois, então uma sessão ligada pelos dois roteia cada criação duas vezes. O downshift setup pula os hooks quando vê o plugin ativado em ~/.claude/settings.json (ele ainda aplica a política de sessão e a barra de status), e o downshift doctor avisa quando encontra os dois. Para trocar do setup para o plugin, rode antes downshift setup --undo. A detecção lê só o arquivo de configurações do usuário; um plugin ativado pelo .claude/settings.json de um projeto não é visto.

O comando /downshift (Claude Code)

Opcional quando a instalação é manual. É um comando de barra que mostra o que o Downshift fez na sessão atual (uma árvore de subagentes, por que o último rodou onde rodou, pausa e retomada):

mkdir -p ~/.claude/commands
cp commands/status.md ~/.claude/commands/downshift.md   # a partir deste repositório

Com o plugin, ele já existe como /downshift:status. Depois, no Claude Code: /downshift:status, /downshift:status --why, /downshift:status --pause, /downshift:status --resume. A cópia manual opcional acima mantém /downshift como alias local. O comando só executa downshift session pela ferramenta Bash, que a linha allowed-tools limita a esse comando. O mesmo downshift session funciona no terminal para qualquer harness. Veja session-view.md.

Inteligência de Código do Downshift (DCI)

O Downshift inclui um mecanismo opcional de inteligência de código que descobre o código do repositório, extrai símbolos AST (Go) e léxicos, pontua a relevância com BM25 e injeta contexto estrutural compacto (até 3.500 bytes UTF-8) pelo UserPromptSubmit no Claude Code.

Por padrão, o DCI está off. Para ativar em um repositório:

downshift dci enable active   # injeta contexto nos prompts do Claude Code
downshift dci enable observe  # observa e registra telemetria, sem injetar
downshift dci status          # mostra o modo ativo e as estatísticas do cache
downshift dci doctor          # confere permissões, descoberta e latências
downshift dci benchmark       # roda benchmarks locais de desempenho e relevância

Para ver a telemetria e as métricas do DCI:

downshift stats --dci         # mostra os prompts, as injeções e as latências do DCI

Veja code-intelligence.md para os detalhes de arquitetura.

Instalação (Cursor)

Status: Funcional. A reescrita é emitida numa criação real de subagente; a aplicação pelo harness não está confirmada, e ela é descartada nos planos Free e Pro legado (evidência, diagnóstico de lacunas).

O protocolo de hooks do Cursor espelha o do Claude Code: a mesma interceptação preToolUse, com updated_input para reescrever o modelo do subagente. Gere o binário e depois adicione o hook em .cursor/hooks.json (nível do projeto) ou ~/.cursor/hooks.json (global):

{
  "version": 1,
  "hooks": {
    "preToolUse": [
      { "command": "downshift cursor", "matcher": "Task" }
    ]
  }
}

O matcher: "Task" limita o hook às criações de subagentes. O Cursor observa o arquivo de configuração e o recarrega ao salvar.

Instalação (Codex)

Status: Funcional. A reescrita é emitida numa criação real de subagente; a aplicação pelo harness é inferida, não observada (evidência).

O Codex cria subagentes por uma ferramenta reservada spawn_agent, no multi_agent_v2. Você não consegue colocar um modelo na chamada visível ao provedor, mas um hook PreToolUse pode injetar o modelo e o reasoning_effort na entrada da ferramenta antes de o filho começar, que é exatamente onde o downshift roda.

Ative as flags de recurso em config.toml:

[features]
hooks = true

[features.multi_agent_v2]
enabled = true

Registre o hook em .codex/hooks.json (projeto) ou ~/.codex/hooks.json (global). O matcher cobre os nomes de ferramenta Agent e o spawn_agent com namespace:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "(^Agent$|.*spawn_agent$)",
        "hooks": [
          { "type": "command", "command": "downshift codex" }
        ]
      }
    ]
  }
}

Confie no hook antes de testar

O Codex não executa hooks locais recém-configurados até você revisar e confiar no comando exato. Isso é um controle de segurança do Codex, não um erro do downshift. Depois de salvar a configuração, abra o Codex e rode:

/hooks

Revise e confie no hook downshift codex, e depois abra uma nova sessão antes de pedir ao Codex para criar um subagente. Enquanto o hook não for confiável, o Codex o ignora e o subagente mantém o modelo da sessão sem mudança.

No Codex, o downshift roteia dois eixos ao mesmo tempo: o tier do modelo e o esforço de raciocínio (low para trabalho trivial, até high para trabalho de fronteira). Numa sessão que oferece GPT-6 Sol e Luna, um subagente trivial pode ir de gpt-6-sol para gpt-6-luna com esforço baixo, desde que a lista permitida da sessão e o Codex aceitem a entrada reescrita.

O Downshift aplica o esforço de raciocínio escolhido, exceto quando uma trava segura a decisão (o subagente mantém o esforço pedido) ou quando a decisão não tem confiança e não reescreve o modelo. Uma revisão de código é uma tarefa de fronteira, então uma sessão com gpt-5.6-terra roteia o subagente para gpt-5.6-sol com esforço alto. gpt-6-astra está marcado com routing: "explicit_only" no catálogo. Com o explicit_upshift desligado por padrão, o downshift não o escolhe. Se o subagente atual já roda no Astra, o modelo é preservado sem mudança. Defina "explicit_upshift": true em session-models.json, exporte DOWNSHIFT_EXPLICIT_UPSHIFT=1 ou rode install.sh --explicit-upshift para que o upshift o escolha quando ele estiver no conjunto de créditos deste harness (ou quando este harness não informar conjunto de créditos). O claude-fable-5-1-thinking-high do Cursor segue o mesmo princípio de opt-in. O claude-fable-5-1 do Claude Code não é explicit_only; acrescente esse id à lista da sessão para ativá-lo. Para marcar qualquer outro modelo como explicit-only, adicione "routing": "explicit_only" à entrada dele em ~/.downshift/catalog.json (o diretório de estado; ~/.harness-downshift/ só é lido quando é o diretório legado em uso).

Um prompt puramente mecânico, como Use a subagent to only list the .go files, é roteado para gpt-6-luna com esforço baixo, quando esse id exato está na lista permitida da sessão.

A especificação de criação multi_agent_v2 do Codex ainda está evoluindo. O downshift preserva os campos reservados e falha de forma aberta, mas fixe a versão exata do Codex que você usa e mantenha um teste de aceitação com uma criação real.

Lista permitida da sessão

O Downshift só grava um id de modelo quando esse id está na sessão atual. O catálogo fornece tier, custo, família e esforço para os ids que também estão na sessão. Ele nunca adiciona um id que a sessão não tem. Se a lista da sessão não puder ser determinada, o hook deixa o modelo atual sem mudança.

Os hooks do Cursor, do Claude Code e do Codex enviam o modelo ativo, não a lista completa do seletor. O Codex também envia um ID de sessão; o Downshift valida e faz hash desse ID antes de registrar, para que as decisões locais possam ser agrupadas sem guardar o identificador bruto. Registre os ids de modelo selecionáveis em ~/.downshift/session-models.json (legado: ~/.harness-downshift/). Uma lista no nível superior do harness é um fallback; uma lista exata sessions.<harness>.<session_id> tem precedência. As listas são mantidas pelo operador: o Downshift não consulta o seletor de modelos do Codex nem infere a elegibilidade da conta. A exceção é o Claude Code: sem lista de nenhuma fonte, ele infere a sessão pelo modelo atual (a escada de tiers do catálogo abaixo, terminando nesse modelo), então pode fazer downshift, mas nunca upshift além do que a sessão já roda; DOWNSHIFT_INFER_SESSION=off desliga isso. Se um payload do hook trouxer session_models ou available_models, essa lista é usada e o arquivo é ignorado. Detalhes e evidências: session-models.md. session-models.example.json é uma sessão do Cursor de 27/09/2026. É um exemplo, não o padrão para todo usuário.

Para a cota do Cursor, o hook pode ler, offline, uma exportação nativa completa indicada por DOWNSHIFT_CURSOR_NATIVE_FILE, antes do cache de cota canônico. Uma exportação configurada malformada ou desatualizada segura o roteamento. A extensão externa experimental foi testada no Cursor 3.24.9 e não conseguiu acessar a API cursor, que só existe embutida, mesmo com uma flag explícita de API proposta; nenhuma exportação foi gerada. Instalar essa extensão não ativa a coleta nessa versão. Veja o diagnóstico de runtime. A pertinência ao provedor continua sendo a fonte de verdade; não a substitua por uma lista fixa de modelos.

Harnesses experimentais

Experimental (prova de conceito). O KiroCrew roda só em modo de política (bloqueia e tenta de novo, sem reescrita no lugar), e a reescrita do Antigravity usa um envelope overwrite que não é um campo documentado do fornecedor; cada um tem um filho observado numa build e nenhum registra o fim do filho. Todo recurso continua calculado para eles (regra de camadas, cmd/downshift/conformance_test.go), e os adaptadores, os testes e os hooks ficam no repositório, mas trate-os como provas de conceito, não como instalações suportadas. Instale-os só se você aceitar isso.

Antigravity (Google DeepMind)

Status: Experimental. Um filho observado no desktop 2.21.1 (evidência); nenhum fim de filho registrado.

O Antigravity executa subagentes por invoke_subagent e aceita a modificação de argumentos no protocolo de hook PreToolUse por meio de overwrite.

Registre o hook em ~/.gemini/config/hooks.json:

{
  "PreToolUse": [
    {
      "matcher": "invoke_subagent",
      "command": "downshift antigravity"
    }
  ]
}

Quando o Antigravity tenta criar um subagente (por exemplo, herdando o modelo pai ou pedindo pro), o downshift antigravity intercepta a chamada da ferramenta, classifica a última entrada de Subagents que tem um Prompt não vazio (não necessariamente Subagents[0]; linhas finais sem Prompt são ignoradas) e reescreve o Model desse subagente (flash_lite para tarefas mecânicas, flash para o tier intermediário), por meio de um envelope overwrite que não é um campo documentado do fornecedor. O evento de roteamento vai para ~/.downshift/events.jsonl.

KiroCrew (modo de política pelo hook nativo da Kiro CLI)

Status: Experimental. Bloqueio e nova tentativa observados uma vez na Kiro CLI 2.29.0; sem reescrita no lugar (evidência).

Para a Kiro CLI 2.29, registre o Downshift pela configuração persistente agent.kiro_hooks do KiroCrew. O KiroCrew gera a especificação de agente consumida pela Kiro CLI, cujo hook nativo preToolUse roda antes da ferramenta: exit 0 permite; exit 2 bloqueia e devolve o stderr ao agente. Não existe canal updated_input, então o adaptador usa o modo de política. Ele classifica uma criação pendente com um modelo filho explícito e:

  • tier certo já → exit 0, permite em silêncio;
  • divergência de tier com confiança → exit 2, bloqueia com uma mensagem que nomeia o modelo para recriar (e, para um tier pequeno, um lembrete para reduzir o contexto e caber na janela menor);
  • downshift incerto, modelo desconhecido ou ferramenta que não é de subagente → exit 0, falha de forma aberta. O roteador nunca bloqueia uma criação por causa da própria dúvida.

Use a ferramenta MCP spawn_run do kirocrew-core com os argumentos task e model explícitos. O pipeline nativo use_subagent / crew pode omitir o modelo filho; essas chamadas ficam fora da cobertura do roteamento. O Downshift nunca infere o modelo filho a partir do modelo do pai nem de um título da interface. O classificador é determinístico; o agente precisa tentar de novo uma criação bloqueada com o modelo recomendado.

Configuração automática

Rode os comandos no seu terminal. O modo de prévia mostra o diff sem gravar; depois, execute a configuração:

downshift setup kirocrew --dry-run
downshift setup kirocrew

O Downshift grava um wrapper em ~/.downshift/bin/kirocrew-pre-tool-use.sh (.cmd no Windows), registra-o em agent.kiro_hooks.preToolUse no ~/.kiro/crew/config.json existente e instala a instrução compacta. Se o arquivo de configuração não existir, o KiroCrew ainda não está configurado; se a gravação do wrapper falhar, o arquivo não é alterado. downshift setup --undo restaura os dois. Depois, reinicie o KiroCrew para regenerar a especificação do agente e rode downshift doctor.

O Agent Dashboard do KiroCrew mostra o histórico e a saúde dos agentes a partir do runs.db do ecossistema ao qual está conectado. Ele não lê o diretório de estado do Downshift, então não mostra decisões de roteamento nem economias; use downshift stats para isso.

Configuração manual

Importante: existem dois caminhos de hook. ~/.kiro/agents/kirocrew.json é gerado pelo KiroCrew e sobrescrito a cada reinício; edições ali se perdem. O caminho durável de registro é ~/.kiro/crew/config.json, via agent.kiro_hooks. ~/.kiro/crew/hooks.json é um registro de hooks separado e informativo (um run_count crescente prova que foi invocado; o código de saída não bloqueia o caminho da ferramenta). Use config.json para a aplicação de políticas. Confirmado na Kiro CLI 2.29.0, em 10/10/2026.

  1. Gere o binário:
    go build -o downshift ./cmd/downshift
  2. Torne executável o wrapper versionado:
    chmod +x scripts/kirocrew-pre-tool-use.sh
    O wrapper chama o binário downshift do repositório com o subcomando kirocrew. Mantenha-o ao lado deste build, no checkout do repositório.
  3. Mescle esta entrada em ~/.kiro/crew/config.json, preservando a configuração e os hooks existentes. Troque o caminho de exemplo pelo caminho absoluto do wrapper no seu checkout:
    {
      "agent": {
        "kiro_hooks": {
          "preToolUse": [
            {
              "matcher": "*",
              "command": "/absolute/path/to/downshift/scripts/kirocrew-pre-tool-use.sh"
            }
          ]
        }
      }
    }
    O KiroCrew mescla kiro_hooks com os hooks embutidos dele ao gerar a especificação do agente. Ele aceita command como um caminho absoluto de executável existente, preserva command e matcher, e descarta timeout_ms. Comandos com argumentos de shell são rejeitados. O wrapper carrega o subcomando, então ele sobrevive à geração. Não edite ~/.kiro/agents/kirocrew.json: o KiroCrew regenera esse arquivo e suas edições se perderão.
  4. Preencha a lista de modelos da sessão kirocrew com os modelos realmente selecionáveis na Kiro CLI instalada. Siga session-models.md para a ordenação e a precedência da descoberta. Sem um alvo elegível conhecido, o modo de política permite a criação sem mudança.
  5. Carregue kirocrew-routing-guide.md nas instruções do agente e reinicie o KiroCrew para que ele regenere a especificação. Confirme que o preToolUse gerado inclui o wrapper e os hooks embutidos existentes.
  6. Teste de fumaça do adaptador com modelos disponíveis conhecidos (sem criar subagente):
    printf '%s\n' '{"tool_name":"spawn_run","tool_input":{"task":"rename a variable","model":"YOUR_AVAILABLE_FRONTIER_MODEL"}}' \
      | ./scripts/kirocrew-pre-tool-use.sh
    # Uma divergência confiante com um alvo elegível retorna exit 2 e model=...
    Troque o marcador por um modelo real e atual. Isso verifica só a saída do adaptador; não prova que o harness bloqueia a execução.

Os hooks de ferramenta ~/.kiro/crew/hooks.json são informativos: podem executar depois que a ferramenta começa, e o código de saída deles não bloqueia esse caminho. Um run_count crescente prova apenas a invocação. Não use esse registro como aplicação de política, nem mantenha uma duplicata informativa do hook de política nativo.

Evidência de aceitação e cobertura

As instruções vinculadas são o guia inferencial do eixo de comportamento. O hook de política pré-ferramenta nativo é o sensor computacional dessa mesma preocupação. Teste um spawn_run real com uma tarefa trivial e um modelo de fronteira explícito: prove que ele é bloqueado antes de o filho começar e, depois, tente de novo uma vez com o modelo recomendado. Confira o modelo real do filho no registro nativo de subagentes do KiroCrew. Chamadas sem modelo precisam passar sem mudança.

A regeneração da especificação e um reinício seguido desses testes são o sensor computacional de aderência da arquitetura, pareado com este guia de configuração. As decisões de roteamento no events.jsonl do diretório de estado dão observações locais contínuas (padrão ~/.downshift; legado ~/.harness-downshift). Uma decisão bloqueada só prova a aplicação quando pareada com o resultado nativo; ela não prova a execução bem-sucedida do filho, o uso nem a economia. Um observador de conformidade PostToolUse continua sendo uma ferramenta separada de mantenedor (DS-04); esta configuração não instala um. O bloqueio nativo, a nova tentativa e o reconhecimento do modelo servido foram observados em 10/10/2026 com a Kiro CLI 2.29.0; veja a evidência específica da build.

dsmon: widget de monitoramento ao vivo

Prefira downshift watch. A árvore de sessão ao vivo está embutida no binário downshift (sem build separado, em todos os harnesses): veja session-view.md. O dsmon continua compilável e está documentado abaixo.

cmd/dsmon é um comando separado neste repositório: um widget flutuante de terminal que mostra trocas de modelo, harness, distribuição de tiers e economia estimada em tokens em tempo real. Ele lê ~/.downshift/events.jsonl e atualiza a cada 800 ms. Sem dependências externas; só a biblioteca padrão do Go.

╭──────────────────────────────────────────────────────╮
│  dsmon  downshift monitor                            │
│  harness  kirocrew        ◉ live                     │
│ switches today ────────────────────────────────────  │
│  04:03  opus   → haiku   trivial  -75%               │
│  04:02  haiku  → opus    complex  ↑                  │
│  04:01  opus   → sonnet  medium   -50%               │
│ stats ──────────────────────────────────────────────  │
│  35 events   22↓  2↑  8✓                             │
│  est. saved  ~7K tokens ¹                            │
│  ¹ estimated · actual tokens not yet tracked         │
╰──────────────────────────────────────────────────────╯
  04:03:51 · ctrl+c to quit

Compilar e executar

# Compila o monitor (separado do binário de hook `downshift`)
go build -o dsmon ./cmd/dsmon

# Executa no terminal atual
./dsmon

# Abre uma janela flutuante de terminal (detecta iTerm2 / kitty / Ghostty / Terminal.app)
./cmd/dsmon/launch.sh

O que ele mostra

Campo Origem Observações
Harness events.jsonl → campo harness Último harness visto hoje
Trocas events.jsonl → verdict + campos de modelo Últimas 7 decisões de roteamento
Eventos / ↓ ↑ ✓ events.jsonl Contagens de hoje por veredito
Economia estimada (tokens) Tokens de filhos que rodaram em modelo mais barato que o pedido, na visão compartilhada telemetry.TokenSavings Observado onde o harness informa tokens; não é cobrança
Tokens Tokens observados do filho, quando o harness os informa Não vem da fatura do provedor

Nota sobre o consumo de tokens. O hook de roteamento PreToolUse não recebe dados de uso de tokens. No Claude Code, um hook SubagentStop separado (downshift claude-code-subagent-stop) lê a transcrição do filho concluído e registra as contagens de tokens e o modelo informados; veja session-models.md. As visualizações atuais do Downshift atribuem e comparam esses tokens, sem valores em dólar. Tokens movidos para um modelo mais barato não provam que menos tokens foram consumidos ou que a fatura foi menor. Consulte separadamente o painel de cobrança do provedor para verificar os valores cobrados.

CLI do Grok (configuração, não hook)

A CLI do Grok é a exceção honesta, e vale ser preciso sobre o motivo.

O Grok tem subagentes (spawn_subagent, até cerca de 8 em paralelo) e lê os arquivos de hook do Claude Code / Cursor. Mas o contrato do hook PreToolUse dele é só permitir ou negar: { "decision": "deny", "reason": "…" }. Não há updatedInput documentado, então um hook não consegue reescrever o modelo de um subagente como faz no Claude Code, no Cursor e no Codex. Um hook do downshift no Grok só poderia bloquear uma criação, e isso não é o trabalho dele.

Há uma segunda complicação: até a redação deste texto, o Grok Build traz um único modelo de código (grok-4.6, com raciocínio configurável), não uma escada de modelos pequeno/médio/fronteira. Então, no Grok, o roteamento não é "trocar o modelo": é ajustar o esforço de raciocínio. Trabalho barato roda o grok-4.6 com esforço baixo; as tarefas difíceis rodam com esforço alto. O mesmo princípio, outro botão.

O Grok expõe os dois como configuração de primeira classe, o que é mais robusto que uma reescrita em tempo de execução. Defina o raciocínio por papel de subagente em ~/.grok/config.toml:

# Tipos somente leitura embutidos → raciocínio baixo (barato e rápido).
[subagents.personas.explore]
reasoning_effort = "low"

# Papéis personalizados têm o próprio padrão de raciocínio.
[subagents.roles.reviewer]
description = "Reviews generated changes before commit"
default_capability_mode = "read-only"
reasoning_effort = "low"

[subagents.roles.architect]
description = "Cross-cutting design and migrations"
reasoning_effort = "high"    # torque para as curvas difíceis

# Se o seu catálogo ganhar modelos mais baratos ou mais fortes, fixe-os por tipo também:
# [subagents.models]
# explore = "grok-4.6"

A precedência é: substituição explícita na criação → padrão do papel → padrão da persona → sessão pai. Assim, esses fixos valem a não ser que o agente seja instruído de outra forma. downshift try "<prompt>" grok informa qual tier uma tarefa pede; mapeie esse tier para o esforço de raciocínio de um papel na configuração, uma vez.

Se uma build futura do Grok adicionar updatedInput ao PreToolUse (ou um catálogo multimodelo), um adaptador de hook downshift grok vira um encaixe direto: o classificador e a política já são independentes de harness. Até lá, a configuração é a alavanca certa e documentada.

Compatibilidade de planos (leia antes de instalar)

Nem todo plano suporta roteamento de modelos de subagentes. Esta é uma restrição rígida no nível do harness, não um bug do Downshift. Matriz de evidências: harness-matrix.md.

Claude Code

Plano Existem subagentes? O roteamento de modelos funciona?
Free ❌ Não há subagentes reais —
Pro / Max / Teams ✅ Sim ✅ Observado em 06/10/2026 (modelo filho informado pela API)
API (direta) ✅ Sim Esperado (mesmo caminho de hook); a evidência de 06/10/2026 não registrou o plano

O Claude Code no plano gratuito roda num contêiner isolado, sem saída de rede; então go install vai falhar. O recurso de subagentes só existe nos planos pagos.

Cursor

Plano / preço Existem subagentes? O roteamento de modelos funciona?
Free ✅ Limitado ⚠️ updated_input.model é ignorado silenciosamente (problema conhecido)
Pro (por requisição / legado) ✅ Sim ⚠️ o campo model em Task só aceita "fast"; a substituição é descartada silenciosamente
Pro / Ultra (por uso) ✅ Sim ⚠️ Reescrita emitida; modelo filho não confirmado (P1.6)

O hook preToolUse do Cursor dispara e o Downshift roda, mas a reescrita de model é descartada silenciosamente nos planos legados e gratuitos. Registrado no fórum do Cursor. Nos planos Pro/Ultra por uso, em que a seleção de modelo de subagentes é ampliada, o Downshift emite a reescrita; se o harness roda o filho nesse modelo não está confirmado (ainda não há prova do modelo filho — P1.6, linha Não confirmado da matriz).

Codex

Plano Existem subagentes? O roteamento de modelos funciona?
Qualquer (com multi_agent_v2 ativado) ✅ Sim ✅ Inferido em 02/10/2026 (a criação seguinte pediu o modelo escrito), não observado

Requer [features] multi_agent_v2 e hooks = true em config.toml.

Resumo

O Downshift atende a todos os harnesses acima a partir do mesmo núcleo, e o Claude Code é o harness principal: o mais completo (modelo de sessão inferido, hooks de uso e de fim do filho, /downshift:status, barra de status) e o mais verificado. Escolha-o quando puder.

O Downshift é mais eficaz em:

  • Claude Code Pro / Max / Teams / API: roteamento completo de modelos pelo hook
  • Codex com multi_agent_v2 ativado: modelo + reasoning_effort emitidos; a aplicação é inferida, não observada
  • Cursor Pro/Ultra em planos por uso: reescrita emitida; modelo filho não confirmado (P1.6)

Em planos gratuitos ou no preço legado do Cursor, o hook roda, mas as reescritas de modelo podem ser ignoradas silenciosamente pelo harness. A ferramenta falha de forma aberta: o subagente é criado mesmo assim, só sem a troca de modelo.

Solução de problemas

downshift: command not found depois do go install

O go install coloca o binário em ~/go/bin, que pode não estar no seu PATH.

export PATH="$HOME/go/bin:$PATH"          # sessão atual
echo 'export PATH="$HOME/go/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc  # permanente

O instalador curl (install.sh) evita isso, porque grava direto em /usr/local/bin.

O hook roda, mas o modelo não muda (Cursor)

Nos planos gratuitos do Cursor e nos planos legados por requisição, updated_input.model é descartado silenciosamente pelo harness. Este é um problema conhecido do Cursor. O hook dispara e o binário roda (você verá a saída no stderr), mas a reescrita do modelo não tem efeito. Veja Compatibilidade de planos.

Nenhuma saída no stderr: o hook não dispara

Confira o matcher. A ferramenta de subagente do Claude Code é Agent (builds antigas: Task), então o matcher precisa ser "Agent|Task", como o setup e o plugin gravam. Confirme o binário em si com:

# Deve imprimir de imediato uma decisão de permissão em JSON
echo '{"hook_event_name":"PreToolUse","tool_name":"Task","model":"claude-opus-5-5","tool_input":{"prompt":"test"}}' | downshift claude-code

Se isso imprimir JSON, o binário funciona. Se o hook ainda não disparar numa sessão real, confira se o settings.json é um JSON válido e se o caminho para o downshift é o caminho absoluto (ou se ele está no PATH).

go install falha no Claude Code gratuito

O Claude Code gratuito roda num contêiner isolado, sem saída de rede. Instale o binário na sua máquina local primeiro, e depois use o hook: o binário roda na sua máquina, não dentro do contêiner do Claude Code.

O veredito mostra UNKNOWN em vez de DOWNSHIFT

UNKNOWN significa que nenhum modelo atual foi informado. Passe o modelo atual como terceiro argumento para o try:

downshift try "rename the variable" claude-code claude-opus-5-5
# → DOWNSHIFT

No hook em execução, isso é tratado automaticamente: o evento traz o modelo da sessão e o adaptador o lê.