CommitLore
Memória de decisão nativa do Git para agentes de codificação, armazenada como trailers do Git e refs/notes.
Documentação
CommitLore
Pare de revisar a mesma má ideia.
Autoridade de decisão para agentes de código, controlada pelo Git.
Mantenha restrições, alternativas rejeitadas e avisos no Git — e entregue
apenas o que ainda está em vigor, para que um agente não receba uma decisão
que o repositório já reverteu.
Sem memória hospedada. O repositório é o dono do registro.
Instale uma vez. Depois inicialize cada repositório onde você quer que funcione.
curl -fsSL https://raw.githubusercontent.com/MongLong0214/commitlore/v1.7.3/install.sh | sh -s v1.7.3
Prefere ler o instalador primeiro?
curl -fsSLO https://raw.githubusercontent.com/MongLong0214/commitlore/v1.7.3/install.sh
sh install.sh v1.7.3
# Or skip the script: the checkout it makes is one you can make yourself.
git clone --depth 1 --branch v1.7.3 https://github.com/MongLong0214/commitlore
node commitlore/dist/commitlore.mjs --version
Ele instala um checkout fixo do código-fonte e um wrapper que executa
node <checkout>/dist/commitlore.mjs — sem download compilado, sem etapa de build.
O código sobrevive. O julgamento não.
Um agente propõe uma abordagem. Sua equipe a rejeita por causa de uma restrição não óbvia. O código final preserva o resultado, mas geralmente não o motivo pelo qual a alternativa foi rejeitada. Um agente posterior vê apenas o código e propõe a mesma ideia novamente.
O CommitLore mantém esse julgamento ao lado do código.
O que o CommitLore faz
| Comportamento | Caminho do produto | |
|---|---|---|
| Captura | Preserva restrições, alternativas rejeitadas e avisos que um diff não consegue mostrar. Os candidatos são verificados contra a transcrição da sessão e o diff preparado. | commitlore capture |
| Preserva | Armazena registros aceitos em trailers ou notas do Git, em vez de um banco de memória hospedado. | hooks de commit · refs/notes/commitlore |
| Rastreia ciclo de vida | Mantém decisões ativas, substituídas e expiradas distintas. | commitlore stale |
| Escopo | Seleciona decisões para o caminho que um agente está prestes a editar. | commitlore context |
| Classifica confiança | Entrega registros como diretivas, alegações ou conteúdo retido. | modo padrão / assinado |
| Entrega | Dá a agentes suportados contexto atual antes de uma edição. | hook de plugin · MCP |
A maioria dos commits não deve carregar registro. O CommitLore é para julgamento que o código não consegue preservar, não para narrar cada mudança.
60 segundos para agentes conscientes de decisões
1. Instale a CLI
macOS e Linux:
curl -fsSL https://raw.githubusercontent.com/MongLong0214/commitlore/v1.7.3/install.sh | sh -s v1.7.3
Windows:
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/MongLong0214/commitlore/v1.7.3/install.ps1))) v1.7.3
Requer Node.js 22.23.2+ e Git. O script verifica ambos antes de escrever qualquer coisa.
2. Conecte seu agente
Claude Code:
/plugin marketplace add MongLong0214/commitlore
/plugin install commitlore@commitlore
Codex:
commitlore plugin install-codex
O plugin não coloca commitlore em PATH, então os comandos abaixo precisam da
instalação da CLI também. Os instaladores também detectam e conectam hosts MCP suportados onde
podem fazê-lo com segurança; a matriz exata está abaixo.
3. Inicialize um repositório
cd your-repository
commitlore init
commitlore context .
Inicie uma nova sessão de agente após instalar ou atualizar um plugin: uma sessão em execução mantém o runtime que carregou.
Depois trabalhe e faça commits normalmente. Em integrações de skill suportadas, o CommitLore é considerado durante solicitações de commit comuns e permanece silencioso quando não há nada que valha a pena preservar. Você não precisa nomear o CommitLore em todo commit.
Quer que registros aceitos sejam preparados sem um prompt por registro? O repositório pode
optar por isso uma vez com commitlore auto on. Essa política é de propriedade do repositório e
se aplica à equipe, então não é habilitada silenciosamente por esta página.
O que o agente recebe
Antes de editar src/pricing.ts:
commitlore: active records for src/pricing.ts
Limit
[claim] r-price01 a1b2c3d4 calculatePrice owns final checkout pricing only
Ruled-out
[claim] r-price01 a1b2c3d4 Reuse it for admin quotes | eligibility and rounding semantics differ
[claim] significa "considere isso como informação." Um repositório pode optar pelo
modo mais forte de autoridade assinada. A entrega dá contexto ao agente; ela não
bloqueia a edição.
Por que Git?
O repositório deve ser dono do julgamento por trás do seu código.
O CommitLore armazena registros em trailers e notas comuns do Git, então eles fazem branch, merge, clone, revisão e sobrevivem a mudanças de provedor junto com o código que explicam.
SQLite é apenas um índice reconstruível. Apague-o e o Git ainda mantém o registro.
Encontrar uma decisão antiga não é suficiente
Um sistema geral de memória ou recuperação pergunta:
Qual texto antigo parece relacionado?
O CommitLore pergunta:
Quais decisões registradas ainda se aplicam a este caminho agora?
Uma decisão substituída pode ser altamente relevante e ainda assim estar errada como orientação atual. Relevância e autoridade são perguntas diferentes.
Como funciona
- Captura — um agente redige apenas o contexto de decisão que o diff não consegue mostrar.
- Verifica — o CommitLore confere o rascunho contra a sessão e o diff preparado.
- Preserva — o registro aceito vive no Git com identidade e ciclo de vida.
- Entrega — antes de uma edição posterior, apenas registros ativos para aquele caminho são retornados.
A maioria dos commits não carrega registro. O hook de commit valida um registro quando um está presente; ele não inventa um.
Um hook existente não é sobrescrito. commitlore init honra core.hooksPath,
move qualquer hook já instalado para <hook>.commitlore-chained e o chama
primeiro; commitlore hooks uninstall o coloca de volta.
O que acontece automaticamente
| Host | Entrega pré-edição | Fluxo de captura verificado | Captura determinística em todo commit |
|---|---|---|---|
| Claude Code | Automática pelo plugin | Disponível pela skill do plugin | Não certificada |
| Codex | Automática pelo plugin | Disponível pela skill do plugin | Não certificada |
| Hermes | Disponível após commitlore hermes install | Disponível após instalação do host | Não certificada |
| Gemini CLI, Cursor, Windsurf, opencode | Entrega MCP onde o host usa o registro | Procedimento exposto via MCP | Não |
Hosts AGENTS.md | Somente procedimento | Somente procedimento | Não |
"Disponível" significa que o fluxo de preparar → verificar → preparar existe. Não significa que todo commit elegível é avaliado automaticamente.
Usuários em hosts de skill suportados não precisam dizer "registre isso no CommitLore" em todo commit. A limitação restante é a iniciação do host, não um comando de usuário obrigatório por registro.
Repositórios com squash merge
Um squash merge substitui os commits de uma branch por um novo commit, e esse commit não carrega os trailers da branch. Se seu repositório faz merge com o botão de squash, um registro feito em uma branch é descartado pelo merge, a menos que algo o carregue para o commit que fez o squash.
Dois caminhos cobrem isso, e um deles precisa de uma configuração única:
| Como o squash acontece | O que carrega o registro | Configuração |
|---|---|---|
git merge --squash localmente | O hook prepare-commit-msg instalado, de SQUASH_MSG | Nenhuma — commitlore init já fez |
| Botão Squash and merge do GitHub | A GitHub Action action/preserve | O workflow abaixo |
O GitHub executa esse merge em seus próprios servidores, onde nenhum hook git local roda de jeito nenhum, então o hook local não consegue vê-lo. A Action é o único lugar que tem o que precisa naquele momento: o pull request, seus commits e o commit no qual eles foram esmagados.
Adicione .github/workflows/commitlore-preserve.yml:
name: CommitLore squash inheritance
# pull_request_target, not pull_request: a pull request from a fork gets a
# read-only token on pull_request, so the job would build the record and then
# fail to publish it.
on:
pull_request_target:
types: [closed]
permissions:
contents: write # the one push to refs/notes/commitlore
concurrency:
group: commitlore-notes
cancel-in-progress: false
jobs:
preserve:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# the merge commit is on the base branch, and a closed pull request
# has no merge ref left to check out
ref: ${{ github.event.pull_request.base.ref }}
fetch-depth: 0
# the mirror this action writes; publishing from a checkout that never
# read it would fork the notes history
- run: git fetch --no-tags origin '+refs/notes/commitlore:refs/notes/commitlore'
# a squash merge usually deletes the branch, and then the pull request's
# own ref is the only one still reaching the commits that carry records
- run: git fetch --no-tags --force origin
'+refs/pull/${{ github.event.pull_request.number }}/head:refs/commitlore/pr-head'
# The action runs CommitLore from a checkout of this repository: the
# package is private, so there is no published npm name to fall back to.
# `dist/` is committed (ADR-0011), so nothing needs building.
- uses: actions/checkout@v4
with:
repository: MongLong0214/commitlore
ref: v1.7.3
path: .commitlore-cli
persist-credentials: false
- uses: MongLong0214/commitlore/action/preserve@v1.7.3
with:
cli-path: .commitlore-cli/dist/cli.js
Duas regras para quem editar isso a seguir, porque pull_request_target roda com um
token gravável: nunca faça checkout da head do pull request aqui, e nunca execute
nada acessível a partir de refs/commitlore/pr-head. Os commits do fork chegam como
dados para ler trailers, não como código para executar.
commitlore doctor informa se isso está ativado, em
squash inheritance. Ele diz isso antes de um registro ser perdido;
squash conservation é a linha que relata registros já perdidos.
Se você faz merge com merge commits ou rebase, os registros sobrevivem por conta própria e esta configuração é desnecessária.
Um relato de campo, não uma medição
Uma execução, em um repositório não relacionado, por alguém instalando v1.2.1 pela primeira vez. Nada aqui foi medido e nada disso está nos logs de evidência. Está nesta página porque o parágrafo acima afirma um loop que nenhuma tabela aqui cobre.
Eles pediram a um agente para corrigir um bug de arredondamento, mencionaram de passagem que uma biblioteca decimal já havia sido considerada e descartada, e terminaram com "faça o commit". O CommitLore nunca foi nomeado. Parte do que o commit carregou:
Ruled-out: adopting a decimal library such as Decimal.js | the backend is a
number contract, so it is meaningless
Warn: do not revert the test file to console.assert: it exits 0 even on
failure, so CI passes silently
Provenance: drafted
O Warn não foi ditado ao agente. Ele caiu na armadilha enquanto trabalhava e a deixou
para quem viesse depois. Provenance: drafted registra que nenhum humano leu o
registro, o que o classifica como claim — entregue como um relatório para considerar, não uma ordem.
Uma sessão posterior sem histórico compartilhado foi solicitada a adotar a biblioteca decimal
afinal. Ela não adotou e citou o registro como motivo. Também leu a
classificação: um claim não é uma instrução, então verificou o motivo declarado contra
o código antes de concordar com ele.
Diferente de armazenamento de memória
| Memória geral / RAG | CommitLore | |
|---|---|---|
| Pergunta principal | Qual texto antigo está relacionado? | Quais decisões ainda se aplicam aqui agora? |
| Autoridade | Armazenamento de memória ou provedor | Git |
| Escopo | Similaridade semântica | Caminhos do repositório |
| Ciclo de vida | Frequentemente append-first | Ativo · substituído · expirado |
| Confiança | Texto recuperado | Diretiva · alegação · bloqueado |
| Captura | Transcrição ou armazenamento de notas | Registro de decisão verificado por evidência |
| Portabilidade | Dependente de backend | Git comum |
O CommitLore é intencionalmente mais estreito. Não é um sistema de memória de usuário geral, arquivo de conversa ou substituto de banco vetorial.
Evidência
| Pergunta | Resultado medido | Limite |
|---|---|---|
| O contexto de grau de alegação mudou a re-proposta no estudo registrado? | 2,8% (16/580) com CommitLore vs 18,8% (109/579) sem | um modelo, um harness, tarefas construídas |
| O filtro de ciclo de vida entregou registros aposentados na projeção ativa medida? | 0 registros aposentados | registros substituídos estavam presentes; expiração não estava |
| A busca indexada escala? | 496 ms p50 em 100k commits | o fallback sem índice é muito mais lento |
O tempo de construção do índice segue o número de registros, não o número de commits: a passagem cara roda uma vez por registro, então um histórico longo com pouco registrado constrói mais rápido do que um curto e denso em registros.
O escopo de caminho é o que impede um histórico grande de chegar ao modelo. No corpus #167, apenas 2 de 10.002 registros chegaram:
| rota | registros visíveis ao modelo | registros relevantes | tokens visíveis ao modelo |
|---|---|---|---|
| injetar tudo | 10.002 | 2/2 | 1.004.554 |
| top-k lexical | 2 | 1/2 | 190 |
| escopo de caminho do CommitLore | 2 | 2/2 | 335 |
Isso mede exposição e recall em um orçamento fixo de dois registros — não custo de tokens, custo cobrado, precisão ou comportamento do agente. Um corpus, uma consulta, um modelo de embedding fixado.
O estudo de agente não estabelece um efeito universal de modelo. A entrega não é prova de que um modelo leu ou seguiu um registro.
Métodos, tabelas completas, exclusões e resultados negativos →
Limites, confiança e privacidade
- A captura é assistida, não determinística. As habilidades suportadas consideram solicitações de commit comuns, mas nenhum host é certificado para avaliar todo commit elegível.
- O modo de diretiva padrão não é autenticação. Ele corresponde ao cabeçalho
do autor do commit, e qualquer pessoa que possa escrever um commit pode definir
esse cabeçalho — portanto, um
[directive]no modo padrão é metadado de política, não prova de identidade. O modo de assinatura exige adicionalmente o status verificado do próprio Git e uma correspondência na lista de permissõescommitlore.trustedSignerlocal do repositório; uma lista de permissões de signatários ausente, vazia ou ilegível não autoriza ninguém, então o modo falha de forma segura. - O guard é um aviso experimental, não uma rede de segurança: precisão de 44,8% (IC de Wilson de 95%: 32,7%–57,5%), recall de 22,0% no corpus de 417 decisões. Um resultado de guard vazio não é um veredito de segurança.
- A entrega gasta tokens em cada chamada de ferramenta correspondente. O hook
de pré-edição dispara em
Readbem como emEdit,Write,MultiEditeNotebookEdit, então ele roda com muito mais frequência do que um agente de edição faz commit. Cada disparo gasta até o orçamento de payload — 800 tokens por padrão, alterado com--budget. Um repositório sem registros não gasta nada, o que significa que este é um custo que chega com a adoção, não com a instalação. - Uma resposta pode ser parcial. A cobertura é divulgada; a ausência em um
resultado parcial não é prova de que nenhum registro existe.
commitlore coveragerelata o que uma varredura alcançou. - Os trailers de commit viajam com um clone; as notas não. O Git não busca
refs/notes/*por padrão, então um registro emrefs/notes/commitloreestá ausente de um clone comum até quecommitlore initconfigure esse espelho. - Não há backend hospedado. Mas uma vez que o servidor ou hook retorna contexto, o host lida com esse contexto sob sua própria política; o CommitLore não controla esse fluxo de dados.
Segurança · Compatibilidade · Evidências
Modelo de segurança e confiança
Os registros não são confiáveis até serem classificados. A correspondência padrão de autor é metadado de política, não autenticação. O modo de diretiva assinada exige verificação do Git e uma lista de permissões de signatários local do repositório; uma lista ausente ou ilegível não autoriza ninguém. Payload com formato de injeção é retido das rotas legíveis por modelo.
Instalação, atualizações e gerações antigas de hooks
O instalador da CLI não pode reescrever hooks dentro de repositórios que não
conhece, e sessões de host em execução mantêm o runtime que carregaram. commitlore doctor names both states and their repair, and commitlore upgrade relata
se existe uma versão mais recente.
Protocolo e armazenamento Git
Os registros são trailers ou notas Git comuns. O Protocolo 2.0 define ciclo de vida, graus de confiança, validação e compatibilidade.
Evidências e resultados negativos
O repositório publica os métodos, exclusões, medições malsucedidas e os casos em que o benchmark ou diagnóstico original estava errado.
Experimente em um repositório com histórico.
Diga-nos onde o escopo de caminho, ciclo de vida, captura ou instalação falha.
Relate um caso de falha · Leia a autoauditoria
Documentação
- Instalar, atualizar e desinstalar
- Referência da CLI
- Fluxo de captura
- Protocolo de registro
- Modelo de segurança
- Evidências e limitações
- Contrato de produção
Contribuindo
CONTRIBUTING.md cobre o protocolo de registro ao qual este repositório se submete, o gate de lançamento e como reproduzir as evidências.
Licença
MIT — veja LICENSE.