CommitLore

Memoria de decisiones nativa de Git para agentes de codificación, almacenada como trailers de Git y refs/notes.

Documentación

CommitLore

CommitLore

Deja de revisar la misma mala idea.

Autoridad de decisiones para agentes de código, propiedad de Git.
Mantén restricciones, alternativas rechazadas y advertencias en Git — y luego entrega solo lo que sigue vigente, para que un agente no reciba una decisión que el repositorio ya revirtió.

Sin memoria alojada. El repositorio es dueño del registro.

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

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

Instala una vez. Luego inicializa cada repositorio donde quieras que funcione.

curl -fsSL https://raw.githubusercontent.com/MongLong0214/commitlore/v1.7.3/install.sh | sh -s v1.7.3
¿Prefieres leer el instalador primero?
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

Instala una copia fija del código fuente y un envoltorio que ejecuta node <checkout>/dist/commitlore.mjs — sin descarga compilada, sin paso de compilación.

commitlore demo prints two recorded decisions for src/pricing.ts, delivers only the active one with its limit and the alternative it ruled out, and says the superseded decision remains in Git without being delivered as current guidance.


El código sobrevive. El juicio no.

Un agente propone un enfoque. Tu equipo lo rechaza por una restricción no obvia. El código final preserva el resultado, pero normalmente no el porqué se rechazó la alternativa. Un agente posterior ve solo el código y propone la misma idea otra vez.

CommitLore mantiene ese juicio junto al código.

Qué hace CommitLore

ComportamientoRuta del producto
CapturaPreserva restricciones, alternativas rechazadas y advertencias que un diff no puede mostrar. Los candidatos se verifican contra la transcripción de la sesión y el diff preparado.commitlore capture
PreservaAlmacena registros aceptados en trailers o notas de Git en lugar de una base de datos de memoria alojada.hooks de commit · refs/notes/commitlore
Rastrea ciclo de vidaMantiene distintas las decisiones activas, superadas y expiradas.commitlore stale
AlcanceSelecciona decisiones para la ruta que un agente está a punto de editar.commitlore context
Clasifica confianzaEntrega registros como directivas, afirmaciones o contenido retenido.modo predeterminado / firmado
EntregaDa a los agentes compatibles contexto actual antes de una edición.hook de plugin · MCP

La mayoría de los commits no deberían llevar ningún registro. CommitLore es para juicios que el código no puede preservar, no para narrar cada cambio.

60 segundos para agentes conscientes de decisiones

1. Instala la CLI

macOS y 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

Requiere Node.js 22.23.2+ y Git. El script verifica ambos antes de escribir nada.

2. Conecta tu agente

Claude Code:

/plugin marketplace add MongLong0214/commitlore
/plugin install commitlore@commitlore

Codex:

commitlore plugin install-codex

El plugin no pone commitlore en PATH, así que los comandos de abajo necesitan también la instalación de la CLI. Los instaladores también detectan y conectan hosts MCP compatibles donde pueden hacerlo de forma segura; la matriz exacta está abajo.

3. Inicializa un repositorio

cd your-repository
commitlore init
commitlore context .

Inicia una nueva sesión de agente después de instalar o actualizar un plugin: una sesión en ejecución mantiene el runtime que cargó.

Luego trabaja y haz commits normalmente. En integraciones de habilidades compatibles, CommitLore se considera durante solicitudes de commit ordinarias y permanece en silencio cuando no hay nada que valga la pena preservar. No necesitas nombrar CommitLore en cada commit.

¿Quieres que los registros aceptados se preparen sin un aviso por registro? El repositorio puede optar una vez con commitlore auto on. Esa política es propiedad del repositorio y se aplica al equipo, por lo que no se habilita silenciosamente desde esta página.

Qué recibe el agente

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 "considera esto como información". Un repositorio puede optar por el modo más fuerte de autoridad firmada. La entrega da contexto al agente; no bloquea la edición.

Modelo de seguridad →

¿Por qué Git?

El repositorio debería ser dueño del juicio detrás de su código.

CommitLore almacena registros en trailers y notas ordinarios de Git, para que se ramifiquen, fusionen, clonen, revisen y sobrevivan a cambios de proveedor junto con el código que explican.

SQLite es solo un índice reconstruible. Bórralo y Git aún conserva el registro.

Encontrar una decisión antigua no es suficiente

Un sistema general de memoria o recuperación pregunta:

¿Qué texto antiguo parece relacionado?

CommitLore pregunta:

¿Qué decisiones registradas siguen aplicando a esta ruta ahora?

Una decisión superada puede ser muy relevante y aun así estar equivocada como guía actual. Relevancia y autoridad son preguntas diferentes.

Cómo funciona

For src/pricing.ts, the active decision in Git history moves into the context delivered before the next edit, carrying its limit and the alternative it ruled out. An earlier decision that also covered admin quotes has been superseded and stays in history without moving forward as current guidance.

  1. Captura — un agente redacta solo el contexto de decisión que el diff no puede mostrar.
  2. Verifica — CommitLore comprueba el borrador contra la sesión y el diff preparado.
  3. Preserva — el registro aceptado vive en Git con identidad y ciclo de vida.
  4. Entrega — antes de una edición posterior, solo se devuelven los registros activos para esa ruta.

La mayoría de los commits no llevan ningún registro. El hook de commit valida un registro cuando está presente; no lo inventa.

Un hook existente no se sobrescribe. commitlore init respeta core.hooksPath, mueve cualquier hook ya instalado a <hook>.commitlore-chained, y lo llama primero; commitlore hooks uninstall lo devuelve.

Qué sucede automáticamente

HostEntrega previa a la ediciónFlujo de captura verificadoCaptura determinista en cada commit
Claude CodeAutomática a través del pluginDisponible a través de la habilidad del pluginNo certificado
CodexAutomática a través del pluginDisponible a través de la habilidad del pluginNo certificado
HermesDisponible después de commitlore hermes installDisponible después de la instalación del hostNo certificado
Gemini CLI, Cursor, Windsurf, opencodeEntrega MCP donde el host usa el registroProcedimiento expuesto sobre MCPNo
AGENTS.md hostsSolo procedimientoSolo procedimientoNo

"Disponible" significa que existe el flujo de trabajo preparar → verificar → preparar. No significa que cada commit elegible se evalúe automáticamente.

Los usuarios en hosts con habilidades compatibles no necesitan decir "registra esto en CommitLore" en cada commit. La limitación restante es la iniciación del host, no un comando de usuario requerido por registro.

Repositorios con fusión squash

Una fusión squash reemplaza los commits de una rama con un nuevo commit, y ese commit no lleva los trailers de la rama. Si tu repositorio se fusiona con el botón de squash, un registro hecho en una rama se descarta en la fusión a menos que algo lo lleve al commit que lo aplastó.

Dos rutas cubren esto, y una de ellas necesita una configuración única:

Cómo ocurre el squashQué lleva el registroConfiguración
git merge --squash localmenteEl hook prepare-commit-msg instalado, desde SQUASH_MSGNinguna — commitlore init ya lo hizo
Botón Squash and merge de GitHubLa acción de GitHub action/preserveEl flujo de trabajo de abajo

GitHub realiza esa fusión en sus propios servidores, donde no se ejecuta ningún hook local de git, así que el hook local no puede verlo. La Acción es el único lugar que tiene lo que necesita en ese momento: la solicitud de extracción, sus commits y el commit en el que se aplastaron.

Añade .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

Dos reglas para quien edite esto a continuación, porque pull_request_target se ejecuta con un token escribible: nunca hagas checkout de la cabeza de la solicitud de extracción aquí, y nunca ejecutes nada alcanzable desde refs/commitlore/pr-head. Los commits del fork llegan como datos para leer trailers, no como código para ejecutar.

commitlore doctor informa si esto está activado, bajo squash inheritance. Lo dice antes de que se pierda un registro; squash conservation es la fila que informa registros ya perdidos.

Si fusionas con commits de fusión o rebase, los registros sobreviven por sí solos y esta configuración es innecesaria.

Un informe de campo, no una medición

Una ejecución, en un repositorio no relacionado, por alguien que instala v1.2.1 por primera vez. Nada aquí fue medido y nada de esto está en los registros de evidencia. Está en esta página porque el párrafo anterior afirma un bucle que ninguna tabla aquí cubre.

Pidieron a un agente que arreglara un error de redondeo, mencionaron de paso que una biblioteca decimal ya se había considerado y descartado, y terminaron con "haz el commit". CommitLore nunca fue nombrado. Parte de lo que llevó el commit:

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

El Warn no fue dictado al agente. Cayó en la trampa mientras trabajaba y lo dejó para quien viniera después. Provenance: drafted registra que ningún humano leyó el registro, lo que lo clasifica como claim — entregado como un informe para considerar, no una orden.

Una sesión posterior sin historial compartido recibió la tarea de adoptar la biblioteca decimal después de todo. No lo hizo, y nombró el registro como su razón. También leyó la clasificación: un claim no es una instrucción, así que verificó la razón declarada contra el código antes de estar de acuerdo.

A diferencia del almacenamiento de memoria

Memoria general / RAGCommitLore
Pregunta principal¿Qué texto antiguo está relacionado?¿Qué decisiones siguen aplicando aquí ahora?
AutoridadAlmacén de memoria o proveedorGit
AlcanceSimilitud semánticaRutas del repositorio
Ciclo de vidaA menudo solo añadeActiva · superada · expirada
ConfianzaTexto recuperadoDirectiva · afirmación · bloqueada
CapturaTranscripción o almacenamiento de notasRegistro de decisión verificado con evidencia
PortabilidadDependiente del backendGit ordinario

CommitLore es intencionalmente más estrecho. No es un sistema general de memoria de usuario, archivo de conversación o reemplazo de base de datos vectorial.

Evidencia

PreguntaResultado medidoLímite
¿El contexto de grado afirmación cambió la re-propuesta en el estudio registrado?2.8% (16/580) con CommitLore vs 18.8% (109/579) sinun modelo, un arnés, tareas construidas
¿El filtrado de ciclo de vida entregó registros retirados en la proyección activa medida?0 registros retiradoslos registros superados estaban presentes; la expiración no
¿La búsqueda indexada escala?496 ms p50 a 100k commitsel respaldo sin índice es mucho más lento

El tiempo de construcción del índice sigue el número de registros, no el número de commits: la pasada costosa se ejecuta una vez por registro, así que un historial largo con poco registrado se construye más rápido que uno corto denso en registros.

El alcance de ruta es lo que mantiene un historial grande fuera del modelo. En el corpus #167, solo 2 de 10,002 registros lo hicieron:

rutaregistros visibles al modeloregistros relevantestokens visibles al modelo
inyectar todo10,0022/21,004,554
léxico top-k21/2190
alcance de ruta CommitLore22/2335

Eso mide exposición y recuperación en un presupuesto fijo de dos registros — no costo de tokens, costo facturado, precisión o comportamiento del agente. Un corpus, una consulta, un modelo de incrustación fijado.

El estudio de agentes no establece un efecto universal del modelo. La entrega no es prueba de que un modelo leyó o siguió un registro.

Métodos, tablas completas, exclusiones y resultados negativos →

Límites, confianza y privacidad

  • La captura es asistida, no determinista. Las habilidades compatibles consideran solicitudes de commit ordinarias, pero ningún host está certificado para evaluar cada commit elegible.
  • El modo de directiva predeterminado no es autenticación. Coincide con el encabezado del autor del commit, y cualquiera que pueda escribir un commit puede establecer ese encabezado — por lo que un [directive] en modo predeterminado es metadatos de política, no prueba de identidad. El modo de firma además requiere el estado verificado propio de Git y una coincidencia en la lista de permitidos de commitlore.trustedSigner local al repositorio; una lista de permitidos de firmantes ausente, vacía o ilegible no autoriza a nadie, por lo que el modo falla de forma cerrada.
  • Guard es un aviso experimental, no una red de seguridad: precisión 44.8% (IC de Wilson del 95%: 32.7%–57.5%), recall 22.0% en el corpus de 417 decisiones. Un resultado vacío de Guard no es un veredicto de seguridad.
  • La entrega gasta tokens en cada llamada de herramienta coincidente. El hook previo a la edición se activa en Read así como en Edit, Write, MultiEdit y NotebookEdit, por lo que se ejecuta con mucha más frecuencia de la que un agente de edición hace commits. Cada activación gasta hasta el presupuesto de carga útil — 800 tokens por defecto, modificado con --budget. Un repositorio sin registros no gasta nada, lo que significa que este es un costo que llega con la adopción, no con la instalación.
  • Una respuesta puede ser parcial. La cobertura se divulga; la ausencia en un resultado parcial no es prueba de que no exista ningún registro. commitlore coverage informa lo que alcanzó un escaneo.
  • Los trailers de commit viajan con un clon; las notas no. Git no obtiene refs/notes/* por defecto, por lo que un registro en refs/notes/commitlore está ausente de un clon ordinario hasta que commitlore init configura ese espejo.
  • No hay backend alojado. Pero una vez que el servidor o hook devuelve contexto, el host maneja ese contexto bajo su propia política; CommitLore no controla ese flujo de datos.

Seguridad · Compatibilidad · Evidencia

Modelo de seguridad y confianza

Los registros no son confiables hasta que se califican. La coincidencia de autor predeterminada es metadatos de política, no autenticación. El modo de directiva firmada requiere verificación de Git y una lista de permitidos de firmantes local al repositorio; una lista ausente o ilegible no autoriza a nadie. La carga útil con forma de inyección se retiene de las rutas legibles por modelos.

Modelo de seguridad completo →

Instalación, actualizaciones y generaciones antiguas de hooks

El instalador CLI no puede reescribir hooks dentro de repositorios que no conoce, y las sesiones de host en ejecución conservan el runtime que cargaron. commitlore doctor names both states and their repair, and commitlore upgrade informa si existe una versión más reciente.

Instalación y actualizaciones →

Protocolo y almacenamiento de Git

Los registros son trailers o notas ordinarios de Git. El protocolo 2.0 define el ciclo de vida, los grados de confianza, la validación y la compatibilidad.

Guía humana → · Especificación normativa →

Evidencia y resultados negativos

El repositorio publica los métodos, las exclusiones, las mediciones fallidas y los casos donde el benchmark o diagnóstico original era incorrecto.

Evidencia → · Autoauditoría →


Pruébalo en un repositorio con historial.
Cuéntanos dónde falla el alcance de ruta, el ciclo de vida, la captura o la instalación.

Reporta un caso de fallo · Lee la autoauditoría


Documentación

Contribuciones

CONTRIBUTING.md cubre el protocolo de registros al que este repositorio se adhiere, la puerta de lanzamiento y cómo reproducir la evidencia.

Licencia

MIT — ver LICENSE.