Engram

Previene la regresión al proporcionar datos de Blast Radius a la IA basados en tu historial de git.

Documentación

Engram

El motor de "Contexto Faltante" para Agentes de IA.

Engram le da a tu agente de IA el contexto que no puede ver solo en el código.

Mientras que los LLM son excelentes analizando los archivos específicos que les das, carecen del contexto más amplio del historial y las salvaguardas de tu repositorio. Engram llena esta brecha al revelar dependencias ocultas (a través del historial de git) y comportamientos requeridos (a través de intenciones de prueba) que la IA de otro modo no tendría a su disposición, ignoraría o pasaría por alto.

¿Por qué Engram?

  • Historial temporal: Responde "¿Qué cambia normalmente cuando este archivo cambia?" para prevenir el ciclo de "arreglar una cosa, romper otra".
  • Intención de prueba: Extrae cadenas de intención de prueba (por ejemplo, "debería manejar saldo negativo") para que la IA entienda qué comportamiento debe preservar.
  • Memoria organizacional: Un almacenamiento persistente para que tú o el LLM registren restricciones arquitectónicas no documentadas, asegurando que las lecciones aprendidas no se pierdan cuando comienzas una nueva conversación.

Hecho para la privacidad. Público para la integridad.

  • Local primero: Todo el procesamiento ocurre en tu hardware local.
  • Cero telemetría: No rastreamos tu uso, tu código, ni tu identidad.
  • Audítalo tú mismo: El código fuente está disponible más abajo.

Ejemplo del mundo real: El bug que las pruebas no pueden detectar

Un servicio TypeScript (TransactionExportService) escribe líneas separadas por pipes como TXN-001|2024-11-15|250.00|COMPLETED.

Un trabajo cron de JavaScript heredado (legacy-mainframe-sync.js) los analiza usando índices de matriz codificados - parts[2] para el monto, parts[3] para el estado.

No hay imports entre ellos. No hay tipos compartidos. Nada en el código los conecta.

La tarea: "Agregar un campo currency junto al monto."

Sin Engram

El agente de IA actualiza el servicio TypeScript y las pruebas. El formato de exportación se convierte en ID|DATE|AMOUNT|CURRENCY|STATUS. Todas las pruebas pasan. El PR se publica.

El problema: El script heredado aún lee parts[3] esperando un estado como COMPLETED - pero ahora obtiene USD. parseFloat("USD") devuelve NaN. El mainframe recibe datos corruptos. Nada falló. Nada advirtió. Rotura silenciosa en producción.

Con Engram

Antes de escribir cualquier código, el agente llama a get_impact_analysis. Engram revisa el historial de git y devuelve:

Riesgo crítico (0.99): bin/legacy-mainframe-sync.js — Cambiados juntos en 21 de 21 commits (100%)

El agente lee el archivo señalado, encuentra el analizador posicional, y actualiza ambos archivos juntos. Misma funcionalidad, cero rupturas.

Después de la corrección, el agente llama a save_project_note:

"El formato de línea de exportación es consumido por bin/legacy-mainframe-sync.js usando índices posicionales codificados. Cualquier cambio en el orden de los campos DEBE reflejarse allí. Formato actual: ID|FECHA|MONTO|MONEDA|ESTADO (índices 0-4)."

Ahora cada agente futuro recibe esta advertencia automáticamente - antes de escribir una sola línea de código.


Qué hace

1. Grafo temporal

  • Qué: Extrae el historial de git para encontrar archivos que se commitean con frecuencia junto a tu archivo objetivo.
  • Por qué: Para revelar dependencias ocultas. Si A.ts y B.ts cambiaron juntos 40 veces el último año, tu IA necesita saber sobre B.ts antes de editar A.ts.

2. Grafo de validación

  • Qué: Localiza automáticamente pruebas relevantes y extrae sus cadenas de intención específicas (por ejemplo, it("should validate JWT expiration")).
  • Por qué: Para proporcionar salvaguardas de comportamiento. La IA puede verificar su plan contra tus requisitos de prueba existentes sin necesidad de leer toda la suite de pruebas.
  • Frameworks admitidos:
    • JS/TS: Vitest, Jest, Mocha, Playwright, Cypress (it, test, describe)
    • JVM (Java/Kotlin/Scala): JUnit 4, JUnit 5 (@DisplayName), Kotest, ScalaTest
    • Rust: Nativo #[test]
    • Python: Pytest, Unittest (def test_...)
    • Go: Nativo func Test...

3. Grafo de conocimiento

  • Qué: Un almacenamiento persistente donde el LLM puede guardar/recuperar "memorias" sobre decisiones arquitectónicas, casos límite o peculiaridades del proyecto.
  • Por qué: Para cerrar la brecha entre sesiones. Si la IA aprende que "Auth requiere un reinicio al cambiar la configuración", guarda esa nota para que el próximo agente de IA también lo sepa.

Llamadas a herramientas

1. get_impact_analysis - Cálculo del radio de impacto para un archivo objetivo

Para un archivo dado, devuelve los archivos afectados, sus intenciones de prueba y cualquier nota almacenada.

Ejemplo:

{
  "file_path": "src/Auth.ts",
  "repo_root": "/path/to/repo"
}

Devuelve:

{
  "summary": "Changing src/Auth.ts may affect 2 files. 1 critical risk, 1 medium risk.\n\n⚠️ Critical Risk (0.89): src/Session.ts\n   Changed together in 48 of 50 commits (96%)\n   Notes: Session requires Redis connection\n\n⚠ High Risk (0.72): src/Auth.test.ts\n   Changed together in 31 of 50 commits (62%)\n   Current test behaviour (may need updating):\n     - should login with valid credentials\n     - should reject invalid password\n     - should handle OAuth callback",
  "formatted_files": [
    {
      "path": "src/Session.ts",
      "risk_level": "Critical",
      "risk_score": 0.89,
      "description": "Changed together in 48 of 50 commits (96%)",
      "memories": ["Session requires Redis connection"]
    },
    {
      "path": "src/Auth.test.ts",
      "risk_level": "High",
      "risk_score": 0.72,
      "description": "Changed together in 31 of 50 commits (62%)",
      "test_intents": [
        "should login with valid credentials",
        "should reject invalid password",
        "should handle OAuth callback"
      ]
    }
  ],
  "coupled_files": [...],
  "commit_count": 50
}

2. save_project_note - Recordar contexto sobre archivos

Almacena notas persistentes que aparecen automáticamente en futuros análisis de impacto.

Ejemplo:

{
  "file_path": "src/Auth.ts",
  "note": "Uses JWT tokens, must validate expiry timestamp",
  "repo_root": "/path/to/repo"
}

3. read_project_notes - Recuperar contexto guardado

Busca notas por contenido o ruta de archivo, o lista todo el conocimiento del proyecto.

Ejemplo:

{
  "query": "Redis",
  "repo_root": "/path/to/repo"
}

Rendimiento

Engram está diseñado para ser invisible hasta que lo necesites. Utiliza una Estrategia de Indexación Adaptativa que respeta tu CPU y escala desde proyectos secundarios hasta monorepos masivos.

Comparado con el núcleo de Linux

Nos tomamos el rendimiento en serio. Engram está comparado con el repositorio Linux Kernel (más de 1.2 millones de commits).

Objetivos de rendimiento

Repos estándar (la mayoría de los proyectos)

  • Primera ejecución: < 2 segundos (Indexación histórica completa)
  • Ejecuciones siguientes: < 200ms

Repos masivos (ej., Linux Kernel)

  • Primera ejecución (por archivo): < 2 segundos (Indexación filtrada por ruta)
  • Ejecuciones siguientes: < 200ms

Arquitectura

┌─────────────┐
│ AI Agent    │ ← MCP protocol over stdio
└──────┬──────┘
       │
┌──────▼──────────────┐
│ Node.js Adapter     │ ← TypeScript MCP server
│ (adapter/)          │
└──────┬──────────────┘
       │ spawns & communicates via JSON
┌──────▼──────────────┐
│ Rust Core Binary    │ ← Fast git indexing + SQLite
│ (core/)             │
└──────┬──────────────┘
       │ reads
┌──────▼──────────────┐
│ .engram/engram.db   │ ← Persistent SQLite database
└─────────────────────┘

Bajo el capó

  • Estrategia adaptativa: Engram detecta automáticamente el tamaño del repositorio. Para repos pequeños, indexa todo. Para repos masivos, cambia a una estrategia filtrada por ruta para evitar bloquear al agente.
  • Huella baja: Sin demonios pesados en segundo plano. La indexación ocurre bajo demanda dentro de presupuestos de tiempo estrictos, utilizando rusqlite y modo WAL para concurrencia de alto rendimiento.
  • Filtrado inteligente: Ignora automáticamente el ruido como archivos de bloqueo, archivos binarios y código generado automáticamente para mantener la señal alta.

Configuración

Engram es un servidor MCP y funciona con cualquier cliente compatible con MCP.

Claude Code

claude mcp add --scope user --transport stdio engram -- npx -y @spectra-g/engram-adapter

Cursor

Configuración > General > Servidores MCP > Agregar nuevo servidor MCP:

  • Nombre: engram
  • Tipo: command
  • Comando: npx -y @spectra-g/engram-adapter

Instrucción del sistema (Recomendado)

Para asegurar que tu IA use Engram de manera efectiva, agrega esto a las reglas de tu proyecto (.cursorrules o CLAUDE.md).

## Engram Workflow Policy
You have access to a tool called `engram` (specifically `get_impact_analysis` and `save_project_note`).
You MUST follow this strictly sequential workflow for EVERY code modification request:

### Phase 1: Analysis (MANDATORY START)
1.  **Blast Radius Check**: Before reading code or proposing changes, you MUST call `get_impact_analysis` on the target file(s).
2.  **Context Loading**:
    *   **Coupling**: If "High" or "Critical" risk files are returned, evaluate if they are *functionally related*.
        *   *Action:* Read the file (`read_file`) if it poses a logical regression risk.
        *   *Ignore:* Skip files that appear coincidental (e.g., lockfiles, gitignore, bulk formatting updates).
    *   **Memories**: Pay close attention to any "Memories" returned in the analysis summary.
    *   **Tests**: If `test_intents` are present, treat them as strict behavioural constraints. If absent, proceed with standard code analysis.

### Phase 2: Execution
3.  **Fix/Refactor**: Proceed with the code changes. Update tests if the behaviour is intentionally changing.

### Phase 3: Knowledge Capture (MANDATORY END)
4.  **Save Learnings**: Before finishing, ask: *"Would a future developer be **surprised** by something I discovered?"*
    *   **IF YES** (Hidden dependencies, non-obvious bugs, env quirks): You MUST use `save_project_note`.
    *   **IF NO** (Typos, standard refactors, documented behaviour): Do NOT save a note.

Desarrollo y comparación de rendimiento

Compilar desde el código fuente

Requiere Rust (1.70+) y Node.js (18+).

npm run build:all    # Build Rust core + TypeScript adapter
npm run test:all     # Run standard test suite

Comparación de rendimiento

Para verificar el rendimiento contra el núcleo de Linux (requiere un clon local de linux como directorio hermano):

# 1. Clone linux kernel to ../linux
# 2. Run the ignored performance tests
npm run test:all-local

Contribuyendo

Damos la bienvenida a reportes de errores y correcciones de la comunidad. Ten en cuenta que al contribuir a este repositorio, otorgas a spectra-g una licencia perpetua e irrevocable para incluir tus cambios tanto en el código fuente público como en las versiones con licencia comercial del software.

Licencia

Este proyecto está licenciado bajo la Licencia No Comercial PolyForm 1.0.0.

  • Uso personal/sin fines de lucro: Gratuito.
  • Uso comercial: Requiere una licencia comercial.

Ver Licencia | Comprar Licencia Comercial