
A memória do seu agente precisa da palavra 'não' — e de uma forma de provar que ninguém a editou
o caro fracasso na codificação assistida por IA não é uma linha de código ruim — linters e testes capturam isso. é um agente reimplementando algo que sua equipe já tentou e descartou. essa tem sido a proposta desde o início: um armazenamento apenas de anexos onde o agente registra seu próprio raciocínio no momento da mudança, para que "nós tentamos isso e quebrou a revogação" sobreviva à sessão que aprendeu isso.
v0.3.10 resolveu a entrega — a memória agora chega no início da sessão em vez de esperar para ser solicitada ("Entrega, Não Armazenamento" [arXiv:2607.20972] mediu por que isso importa: zero operações de memória voluntárias em 114 turnos contra um armazenamento pré-selecionado, enquanto a injeção determinística ocorreu todas as vezes).
v0.3.11 trata das duas metades da frase "caminhos rejeitados, retidos." primeiro: tornando a rejeição em si uma classe primária. segundo: fazendo retidos algo que você pode verificar em vez de algo que você aceita da minha palavra.
as rejeições agora são resultados declarados, não inferências
até agora, o selvedge poderia te dizer que um caminho foi abandonado principalmente lendo folhas de chá: um evento remove próximo a um add, uma janela de proximidade, uma pontuação de confiança heurística. útil, mas é inferência — e inferência é exatamente o que esta ferramenta existe para substituir por testemunho.
três mudanças tornam o abandono um fato declarado:
change_type="reject". o contraparte de revert, para caminhos nunca tomados. revert diz "nós tentamos isso e revertermos." reject diz "nós consideramos isso e decidimos contra" — nenhum código foi escrito, e a decisão ainda vale um registro permanente, porque o agente da próxima sessão também a considerará. nenhuma nova ferramenta MCP; é um valor no log_change existente.
prior_attempts cresce um nível exact. uma tentativa encerrada por um evento explícito reject ou revert agora relata confidence: "exact" — o resultado é declarado no log, não inferido pela proximidade. a antiga heurística cai para desempate para tentativas sem um resultado declarado. (se você filtrar por confidence, aceite exact junto com proximity_high — as linhas se movem.)
expires_when finalmente faz algo. uma rejeição armazenada sem a condição que a invalidaria é um dado que apodrece silenciosamente. a coluna foi enviada dormente na v0.3.8; a v0.3.11 envia o avaliador, com uma gramática deliberadamente fechada — quatro formas, validadas no momento da escrita, tudo o mais rejeitado em vez de armazenado:
library:django>=5.0 # revisitar quando uma dependência nomeada alcançar uma versão
entity:users.email:changes # revisitar quando essa entidade mudar novamente
date:2027-01-15 # revisitar em uma data
manual:security-review # nunca dispara automaticamente; um rótulo para humanos
selvedge stale avalia isso localmente — metadados do pacote instalado, o próprio log de eventos e o relógio. sem rede, sem LLM, e sem esperteza: uma condição library: cujo pacote não é observável localmente retorna como manual_review, não uma suposição, e uma pré-lançamento nunca conta como seu lançamento final. uma decisão que sabe quando deve morrer é uma decisão que você ainda pode confiar em um ano.
nudge de tempo de captura fecha o ciclo: registre um reject ou revert sem stale_when nem expires_when e o validador sugere registrar a condição invalidante. ele avisa, nunca rejeita — mesma postura que os avisos de forma secreta.
o log agora pode provar a si mesmo
aqui está a pergunta desconfortável sob todo o produto: o diferencial do selvedge é que decisões rejeitadas permanecem no registro. apenas anexos. permanente. consultável. e até este lançamento, essa era uma promessa sobre nossa própria conduta — nada no armazenamento poderia mostrar que uma linha era a linha que o agente escreveu.
a v0.3.11 adiciona uma cadeia de hash à prova de adulteração. cada evento registrado recebe um registro de cadeia SHA-256 em uma tabela lateral, escrito na mesma transação, cada registro vinculando o anterior e seu próprio número de sequência. selvedge verify ganha duas verificações: chain_intact recomputa tudo e falha severamente — nomeando o número de sequência exato — quando uma linha encadeada foi editada, excluída ou reordenada fora de banda. chain_coverage avisa (nunca falha) sobre linhas que precedem a cadeia: não encadeado, não inválido.
o problema de design que vale um parágrafo, porque generaliza o passado do selvedge: alguns campos são vinculados tardiamente. o SHA do commit não existe quando o evento é registrado — o evento descreve o trabalho que produz o commit, e um hook pós-commit o carimba depois. uma cadeia de "hash a linha inteira" ingênua chama seu próprio hook git de atacante. o corte do selvedge: git_commit fica fora do núcleo protegido, declarado em voz alta no manifesto de atestação — tolerável porque um hash de commit é verificável de forma independente contra o git, que é ele mesmo uma cadeia de hash mantida por outro software. tudo o mais — raciocínio, diff, caminho da entidade, tipo de mudança, os links de substituição — está encadeado. mutações legítimas não quebram nada: migrate-paths anexa um registro amend, e a poda com portão destrutivo anexa um tombstone contabilizando o que foi excluído. uma poda com portão verifica limpo; um silencioso sqlite3 "UPDATE events SET reasoning=..." não.
e o escopo honesto, que está na docstring do módulo e pertence a este post também: isso detecta modificação casual e acidental, e produz uma exportação verificável de forma independente. não é prova contra um atacante local motivado. não há chave. alguém que controla o arquivo pode recomputar cada digest. o que a cadeia te compra é que ninguém edita o registro casualmente — nenhum script, nenhuma limpeza bem-intencionada, nenhum caminho de código futuro com bugs muta uma decisão sem que o próximo selvedge verify nomeie a linha exata.
nós consumimos a comida do cachorro no primeiro dia: o próprio armazenamento do selvedge cruzou sua gênese de cadeia com este lançamento, e as primeiras linhas encadeadas são as decisões por trás da v0.3.11 — incluindo um verdadeiro change_type="reject" para o comando retroativo chain seal que decidimos não enviar, com o raciocínio anexado.
os itens menores
-
selvedge supersedeganha-d/--diff,--revisit-after, e--expires-when(#31) — paridade comselvedge log, através das mesmas verificações de tamanho e forma secreta. - um supersede sem id não reabre mais cada reverter anterior no caminho (#30) — o fallback agora espelha a regra de auto-link e reabre no máximo a única remoção à qual teria se vinculado no momento da escrita.
- ambos foram divulgados como conhecidos e não corrigidos na postagem da v0.3.10; ambos estão fechados agora.
- contratos de hook, fixados: o lembrete PreCompact é byte-idêntico em disparos repetidos, fica silencioso uma vez que você registra, e agora distingue "editado sem log" de "log existe mas foi truncado" — problemas diferentes, correções diferentes. a digestão do SessionStart é uma contrato documentado com um fixture de regressão semeada para a corrida de supersede-meio-render.
números: testes 984 → 1114, cobertura 89,4%. as verificações de cadeia são verificadas por mutação — exclua as verificações de thread e a suíte fica vermelha. o custo da superfície da ferramenta MCP residente se moveu neste lançamento (4445 tokens co
Empresas brasileiras que utilizam agentes de IA podem se beneficiar da implementação de registros imutáveis, aumentando a confiança nas decisões automatizadas. A capacidade de registrar rejeições e reverter ações pode melhorar a eficiência e a segurança em processos de automação. Isso é crucial para garantir que as decisões tomadas por IA sejam auditáveis e confiáveis.
