DEV Community

Cover image for Harness Engineering: uma fonte de verdade entre Cursor, Kiro, Codex e seus agentes
Tiago Vilas Boas (Montanha)
Tiago Vilas Boas (Montanha)

Posted on Edited on

Harness Engineering: uma fonte de verdade entre Cursor, Kiro, Codex e seus agentes

Pensa numa receita de pão que você ensinou pra cinco pessoas. A receita é a mesma. Mas cada um fermenta o tempo diferente, usa o forno diferente, mede a farinha diferente. No final, cinco pães completamente diferentes - e você sem saber qual deu certo.

Foi exatamente isso que aconteceu com as minhas skills de IA quando a arquitetura cresceu. Cursor, Kiro, Codex, Antigravity e Grok: cada um tinha sua própria pasta de regras, seu próprio comportamento, sua própria "versão" das minhas instruções. Quando eu corrigia o tom de uma persona num harness, o outro ficava defasado. Quando eu atualizava uma skill de code review, precisava lembrar de replicar em quatro lugares.

A dor não era técnica. Era de manutenção: quem governa um conjunto de regras distribuídas sem uma fonte de verdade?

A resposta que encontrei: um repositório Git central com symlinks, mas sem forçar tudo nele.

Fonte de verdade, neste texto, é esse Git: a regra de domínio, o quê fazer, a mesma nos IDEs. Não é o código do produto. A regra do sistema continua no repositório de produto, como no case da knowledge base. O harness do fornecedor (system prompt, orquestração, formato de ferramenta) fica em cada IDE e não entra no symlink. Skill compartilhada alinha o guia. Sensor é teste, lint, log e o gate do CI. Sem sensor, a mesma receita em cinco IDEs ainda não se corrige.

Pré-leitura recomendada: Harness Engineering: as 5 camadas do agent - as cinco camadas (memory, context, skills, agents, tools) que sustentam qualquer harness.


Índice


1. Comum symlinka, particular fica

Antes de sair symlinkando tudo, precisei entender uma coisa: nem toda regra deve ser compartilhada.

O Cursor é minha IDE de desenvolvimento - lê e escreve código o dia todo, com minha presença. O Codex roda em modo danger-full-access, pra tarefas administrativas em ambiente isolado. Uma regra como "escreva direto no disco" que faz sentido no Cursor pode destruir configurações sensíveis no Codex.

O critério que emergiu foi simples:

Regra de domínio (como revisar código, qual tom usar, como estruturar um artigo): symlink - fonte única.
Regra de plataforma (como o harness acessa disco, qual API ele chama, que formato ele espera): isolada - fica no próprio harness.

Isso não é só organização. É a linha entre governança e caos.


2. O núcleo: harness-core e o setup de nova máquina

Criei o repositório harness-core. Tudo que é domínio mora lá: personas, skills de code review, observabilidade, escrita técnica, o comportamento esperado de cada agente.

Para os harnesses de execução confiável (Kiro CLI e Cursor), apaguei as pastas locais e substituí por symlinks:

# Setup de nova máquina em dois comandos:
ln -s ~/Github/harness-core/skills ~/.kiro/skills
ln -s ~/Github/harness-core/steering ~/.kiro/steering
Enter fullscreen mode Exit fullscreen mode

O resultado prático: corrijo o tom de uma persona uma vez, e no mesmo instante Kiro e Cursor aprendem o comportamento novo. Sem sincronização manual. Sem "lembra de atualizar lá também".

Para os harnesses que exigem formatos proprietários - como os arquivos .mdc do Cursor Rules - não edito à mão. Tenho um script que lê o Markdown universal do harness-core e compila as regras no formato que o Cursor espera. A fonte de verdade continua sendo o repositório central; o formato específico da plataforma é um artefato gerado.


3. Quando o compartilhamento quebra: variantes de plataforma

A maior lição foi entender quando não centralizar.

Tenho uma skill chamada Graphify, que extrai relacionamentos em grafos de bases de código. O objetivo é o mesmo em qualquer harness. Mas a mecânica diverge:

  • O Codex suporta spawn_agent nativamente - processa grafos dinâmicos direto em memória.
  • O Kiro é mais fechado - para fazer a mesma coisa, precisa de I/O em disco, escrevendo chunks físicos.

Se eu forçasse um único SKILL.md no repositório central, quebraria um dos dois. A regra de negócio é única. A implementação técnica exige variantes.

Nesses casos, o arquivo isolado vive na pasta do próprio harness e não é symlinkado. O harness-core documenta a intenção da skill; cada harness tem sua implementação.

O critério de corte:

  • Regra que responde "o quê fazer" → harness-core
  • Regra que responde "como fazer neste ambiente" → pasta local do harness

4. Credenciais: o Keychain não tira o segredo do contexto sozinho

Delegar a leitura ao sistema operacional é melhor do que manter uma senha em .env, mas o caminho entre o Keychain e o navegador precisa ser explícito.

O exemplo com security find-internet-password ... -w imprime a senha no stdout. Se essa chamada roda como ferramenta do agente, a saída pode voltar para o contexto do modelo. Touch ID autoriza o acesso ao Keychain; por si só, não garante que o segredo fique fora desse contexto.

Uma opção mais segura mantém a senha fora do contexto do modelo. Um helper local consulta o Keychain após a autorização do sistema, preenche o campo no navegador e devolve ao agente apenas o resultado: sucesso ou falha. O helper não deve imprimir, registrar nem retornar o valor da credencial.

Eu só afirmaria que o segredo não passa pelo modelo depois de verificar esse fluxo de ponta a ponta. Sem essa validação, o texto descreve o desenho pretendido, não uma garantia do comando security.


5. Estado da tarefa: o Logseq como barramento de memória

Unificar skills e credenciais resolve a atitude dos agentes. Mas tem um problema que fica: o estado da tarefa.

Você começa uma investigação profunda no chat web, vai fundo num problema, entende o contexto. Depois abre a IDE pra implementar. Como o Cursor sabe onde você parou? Não sabe - a menos que você construa uma ponte.

Em vez de subir um servidor de mensagens, usei o que já estava na arquitetura: o vault do Logseq.

Criei uma skill global de handoff. Quando digo "faça o handoff dessa tarefa", o agente atual escreve suas decisões num template e salva como pages/harness-handoff/nome-da-tarefa.md. Quando abro a IDE, peço "retome a tarefa X". O Cursor (ou o Kiro via MCP logseq-kb) lê a página, assimila o progresso e continua de onde paramos.

## Handoff: investigação refund-timeout
- Hipótese confirmada: race condition na linha 247 de RefundService
- Próximo passo: adicionar lockForUpdate antes do SELECT
- Contexto relevante: PR #4821 tem padrão similar resolvido
Enter fullscreen mode Exit fullscreen mode

Zero atrito entre harnesses. O estado da tarefa vive no vault, não na sessão de chat.


O checklist que ficou:

[ ] Regras de domínio no harness-core (symlink nos harnesses confiáveis)
[ ] Variantes de plataforma ficam isoladas no harness local
[ ] Credenciais: helper isolado injeta no navegador e retorna só sucesso/falha
[ ] Handoff via Logseq quando o trabalho atravessa harnesses
Enter fullscreen mode Exit fullscreen mode

Gists relacionados:


Governar skills distribuídas sem uma fonte de verdade é o caminho mais rápido pra ter cinco harnesses com personalidades diferentes. Com o núcleo Git, você corrige uma vez e todos aprendem.

Você tem skills compartilhadas entre seus agentes, ou cada ferramenta ainda tem suas próprias regras isoladas?

Top comments (0)