1

Pitch: closure_drift: a mesma versão apontando para código diferente, e o que aprendi medindo agentes de IA

Uma versão é uma string que alguém edita à mão. Quando duas releases têm a mesma versão e código diferente, o mesmo endereço passa a nomear duas coisas, e nada avisa.

Fiz uma ferramenta pequena para checar isso: o closure_drift. Um arquivo Python, só leitura, sem dependências, sem rede. Ela lê as tags do git e responde uma de três coisas: limpo (exit 0), drift (exit 1) ou "não deu para decidir" (exit 2, que nunca é aprovação).

Um exemplo real: no psf/requests, a tag v2.16.1 ainda declara a versão 2.16.0. Dá para conferir sem a ferramenta: git show v2.16.1:requests/__version__.py.

O primeiro uso de fora

Um amigo rodou em dois projetos dele. Nos dois, achou drift que ele não sabia que tinha: a versão 0.0.0 nomeava 26 estados diferentes do código desde o primeiro commit. Ele escreveu um relato com cinco atritos, e quase todos viraram melhorias na versão seguinte.

Agentes de IA

Agente que faz bump, tag e publica também repete versão. Por isso há uma skill (padrão Agent Skills) e um servidor MCP. A skill diz ao agente quando checar e como ler a resposta.

Medi como um agente (Claude Code com Sonnet) se comporta, em seis cenários registrados antes de rodar. O achado mais útil foi sobre o meu próprio texto: a regra que eu mandava colar no AGENTS.md dizia "suba a versão e faça commit", e o agente obedeceu, criando a tag sem perguntar. Corrigi para "pergunte qual versão" e, na rodada seguinte, ele perguntou. É um piloto, uma rodada por cenário, então mostra o que pode acontecer, não com que frequência.

Para testar

git clone -q https://github.com/luizfnsilva/closure_drift && python3 closure_drift/examples/demo.py
python3 closure_drift/closure_drift.py /caminho/do/seu/repo

Com agente: gh skill install luizfnsilva/closure_drift closure-drift --agent claude-code (ou codex, cursor, gemini-cli).

Repositório: https://github.com/luizfnsilva/closure_drift

Se rodar no seu projeto, o resultado (mesmo anônimo) entra na tabela de resultados de terceiros. Um resultado mostrando que a ferramenta errou é o mais útil.

Carregando publicação patrocinada...
1

Um caso que talvez valha a ferramenta reconhecer: projeto que tira a versão da própria tag, com setuptools-scm ou hatch-vcs no Python. Ali não tem string editada à mão, a versão sai do git na hora do build, então esse drift nem tem como acontecer. Se o closure_drift detectar isso no pyproject e responder limpo dizendo o motivo, evita cair no "não deu para decidir" à toa.

Gostei do achado do AGENTS.md, "suba a versão e faça commit" parece inofensivo até o agente seguir ao pé da letra.

1

Boa. Ela já reconhece setuptools-scm, hatch-vcs, versioneer e afins: o relatório diz "version from (the tag)" e explica que não há arquivo de versão para conferir. Mas você pegou uma coisa: a última linha ainda dizia "nada foi decidido", o que contradiz a explicação.

Corrigi agora. No --would-tag desses projetos ela passa a dizer de onde ainda pode vir drift (nome de tag reaproveitado ou movido, ou v1.0 e 1.0 em códigos diferentes), lista os rótulos já usados e diz para dar à tag nova um nome que nenhuma outra usa. Continua exit 2, porque a tag ainda não existe para ser conferida, mas o texto não diz mais "não deu".

Sai hoje na 1.3.1, com crédito a você no CHANGELOG: https://github.com/luizfnsilva/closure_drift/commit/ef7993af9b3b7dd32130bf8e332045a5ea41a0b1

Valeu pelo apontamento.

1
0

E se puder, passa para mais um amigo rodar no repositório dele. São dois comandos:

git clone -q https://github.com/luizfnsilva/closure_drift
python3 closure_drift/closure_drift.py /caminho/do/repo

Só lê o git e não manda nada para lugar nenhum. Cada repositório novo acha um caso que eu não tinha visto, como o seu de hoje.