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

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.

CI Latest release Protocol 2.0 Stable Node.js 22.23.2 or newer MIT License

English · 한국어 · 日本語 · 简体中文

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.

demonstração do commitlore imprime duas decisões registradas para src/pricing.ts, entrega apenas a ativa com seu limite e a alternativa que descartou, e diz que a decisão substituída permanece no Git sem ser entregue como orientação atual.


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

ComportamentoCaminho do produto
CapturaPreserva 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
PreservaArmazena 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 vidaMantém decisões ativas, substituídas e expiradas distintas.commitlore stale
EscopoSeleciona decisões para o caminho que um agente está prestes a editar.commitlore context
Classifica confiançaEntrega registros como diretivas, alegações ou conteúdo retido.modo padrão / assinado
EntregaDá 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.

Modelo de segurança →

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

Para src/pricing.ts, a decisão ativa no histórico do Git entra no contexto entregue antes da próxima edição, carregando seu limite e a alternativa que descartou. Uma decisão anterior que também cobria cotações de admin foi substituída e permanece no histórico sem avançar como orientação atual.

  1. Captura — um agente redige apenas o contexto de decisão que o diff não consegue mostrar.
  2. Verifica — o CommitLore confere o rascunho contra a sessão e o diff preparado.
  3. Preserva — o registro aceito vive no Git com identidade e ciclo de vida.
  4. 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

HostEntrega pré-ediçãoFluxo de captura verificadoCaptura determinística em todo commit
Claude CodeAutomática pelo pluginDisponível pela skill do pluginNão certificada
CodexAutomática pelo pluginDisponível pela skill do pluginNão certificada
HermesDisponível após commitlore hermes installDisponível após instalação do hostNão certificada
Gemini CLI, Cursor, Windsurf, opencodeEntrega MCP onde o host usa o registroProcedimento exposto via MCPNão
Hosts AGENTS.mdSomente procedimentoSomente procedimentoNã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 aconteceO que carrega o registroConfiguração
git merge --squash localmenteO hook prepare-commit-msg instalado, de SQUASH_MSGNenhuma — commitlore init já fez
Botão Squash and merge do GitHubA GitHub Action action/preserveO 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 / RAGCommitLore
Pergunta principalQual texto antigo está relacionado?Quais decisões ainda se aplicam aqui agora?
AutoridadeArmazenamento de memória ou provedorGit
EscopoSimilaridade semânticaCaminhos do repositório
Ciclo de vidaFrequentemente append-firstAtivo · substituído · expirado
ConfiançaTexto recuperadoDiretiva · alegação · bloqueado
CapturaTranscrição ou armazenamento de notasRegistro de decisão verificado por evidência
PortabilidadeDependente de backendGit 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

PerguntaResultado medidoLimite
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) semum modelo, um harness, tarefas construídas
O filtro de ciclo de vida entregou registros aposentados na projeção ativa medida?0 registros aposentadosregistros substituídos estavam presentes; expiração não estava
A busca indexada escala?496 ms p50 em 100k commitso 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:

rotaregistros visíveis ao modeloregistros relevantestokens visíveis ao modelo
injetar tudo10.0022/21.004.554
top-k lexical21/2190
escopo de caminho do CommitLore22/2335

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ões commitlore.trustedSigner local 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 Read bem como em Edit, Write, MultiEdit e NotebookEdit, 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 coverage relata 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 em refs/notes/commitlore está ausente de um clone comum até que commitlore init configure 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.

Modelo de segurança completo →

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.

Instalação e atualizações →

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.

Guia humano → · Especificação normativa →

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.

Evidências → · Autoauditoria →


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

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.