Volver a la wiki

Cairn cherry-pick #2: Señal de co-cambio git en bib_impact_query

Resumen

Fusiona el grafo estático de la Biblioteca (imports, calls, direct docs) con el historial git: bib_impact_query ahora enriquece sus resultados con un campo cochanged_files que contiene los archivos que históricamente cambian juntos al consultado, capturando acoplamiento empírico cross-capa invisible para las aristas declaradas.

Ejemplo real del backfill: monitoring/api/signage.py ↔ static/js/pages/signage/SignageContentManager.js (backend ↔ frontend) — esta dependencia nunca aparece en imports ni calls, pero el historial git lo revela.


Contexto: ¿Por qué co-cambio?

El grafo estático de la Biblioteca se construye a partir de:

Pero no cubre:

La señal de co-cambio (número de commits donde dos archivos cambiaron juntos) es un indicador empírico de este acoplamiento que el grafo estático nunca vería.


Componentes

1. Tabla D1 bib_cochanges (migración 0043)

Almacena pares de archivos y cuántas veces cambiaron juntos:

CREATE TABLE bib_cochanges (
    id INTEGER PRIMARY KEY,
    repo TEXT NOT NULL,           -- 'CreaRack-Pro' | 'CreaRackSL-workspace'
    file_a TEXT NOT NULL,         -- par ordenado: file_a < file_b
    file_b TEXT NOT NULL,
    count INTEGER NOT NULL,       -- nº de merges donde cambiaron juntos
    last_seen TEXT NOT NULL,      -- timestamp del último cambio conjunto
    UNIQUE (repo, file_a, file_b)
);

2. MCP Handler bib_record_cochanges (interno)

Registra co-cambios en D1. No está en la lista pública de tools; se invoca desde:

Modos de entrada:

Anti-ruido:

3. Enriquecimiento de bib_impact_query

Cuando se consulta bib_impact_query(file_path=X), el resultado JSON ahora incluye:

{
  "cochanged_files": [
    { "file": "monitoring/api/signage.py", "count": 7, "last_seen": "2026-06-08T10:22:00Z" },
    { "file": "static/js/pages/signage/SignageContentManager.js", "count": 6, "last_seen": "2026-06-07T15:44:00Z" }
  ]
}

4. Post-merge ingest (record_cochanges())

Función en .github/scripts/bib_ingest.py que se ejecuta incondicional después de cada merge:

def record_cochanges(changed_files: list[str], mcp_token: str, repo_name: str) -> dict:
    """Registra qué archivos cambian JUNTOS en este merge."""
    # Filtra solo código (mismas reglas que backfill)
    code_paths = [f for f in changed_files if ...]
    if len(code_paths) < 2:
        return {"recorded_pairs": 0, "skipped": "..."}
    # Llama a bib_record_cochanges con modo `files`
    raw = call_mcp("bib_record_cochanges", {"files": code_paths, "repo": repo}, mcp_token)
    return json.loads(raw)

Verificación

✅ tsc --noEmit verde (TS tipado en handlers). ✅ ruff verde en ingest. ✅ Backfill dry-run produce señal limpia: 1561 pares con count ≥ 2, top = acoplamiento código ↔ plantilla/frontend (esperado).


Despliegue

Orden crítico:

  1. Aplicar migración 0043 a D1 PROD: wrangler d1 execute --remote < migrations/0043_create_bib_cochanges.sql.
  2. CF Pages despliega Functions automáticamente (handlers + enriquecimiento en bib_impact_query).
  3. Backfill one-shot desde CreaRack-Pro/scripts/bib_cochange_backfill.py (PR companion, opcional pero recomendado para historial completo).

Si el backfill no se ejecuta, bib_impact_query igualmente funciona: registra co-cambios desde el merge actual en adelante.


Ventajas


Véase también

Subir