Servicio: computeDriftChecks + Endpoint /api/biblioteca/drift-checks
Servicio: computeDriftChecks + Endpoint /api/biblioteca/drift-checks
Descripción
computeDriftChecks es la función central del pipeline KB vs Graph (Fase 5, ADR decision--20260514--knowledge-base-vs-graph). Lee la tabla D1 bib_drift_checks —poblada por el cron wiki-drift-check.yml vía el handler MCP bib_check_drift_for_doc— y agrega las estadísticas de una ventana temporal configurable (default 7 días).
Ubicación en el repo
| Artefacto | Ruta |
|---|---|
| Función principal | functions/_lib/drift_checks.ts |
| Endpoint CF Pages | functions/api/biblioteca/drift-checks/index.ts |
Interfaces TypeScript
// Input de la tabla D1
interface DriftCheckItem {
slug: string;
checked_at: string; // ISO8601 / datetime SQLite
confidence: number; // 0.0–1.0 (score Haiku)
summary: string | null; // Resumen del drift detectado
draft_slug_created: string | null; // Slug del draft creado si aplica
}
// Resultado agregado devuelto por computeDriftChecks()
interface DriftChecksReport {
generated_at: string; // ISO8601
window_days: number; // Ventana solicitada (1–∞)
total_checks: number; // Nº de rows en bib_drift_checks en la ventana
drift_detected: number; // Nº de checks donde drift_detected=1
drift_pct: number; // (drift_detected / total_checks) * 100
avg_confidence: number; // Media de confidence en la ventana
total_cost_usd: number; // COALESCE(SUM(haiku_cost_usd), 0)
drafts_created: number; // Nº de páginas con draft_slug_created != NULL
last_check_at: string | null;
top_drifts: DriftCheckItem[]; // Top N por confidence DESC, checked_at DESC
}
Firma de la función
export async function computeDriftChecks(
db: D1Database,
opts: { windowDays?: number; limit?: number } = {},
): Promise<DriftChecksReport>
Parámetros:
db: instanciaD1Database(bindingDBdel Worker/Pages Function).opts.windowDays: ventana en días (default7, mínimo1).opts.limit: máximo de items entop_drifts(default5, rango1–50).
Queries SQL ejecutadas
La función hace dos queries sobre bib_drift_checks:
- Aggregate:
COUNT,SUM(drift_detected),AVG(confidence),SUM(haiku_cost_usd),SUM(CASE WHEN draft_slug_created IS NOT NULL...),MAX(checked_at)— filtrado porchecked_at >= <since_iso>. - Top drifts:
SELECT slug, checked_at, confidence, summary, draft_slug_created WHERE drift_detected=1 ORDER BY confidence DESC, checked_at DESC LIMIT ?.
Endpoint HTTP
URL: GET /api/biblioteca/drift-checks
Autenticación: Bearer token vía /api/_middleware.ts (mismo mecanismo que el resto de endpoints de la biblioteca).
Query params:
| Param | Tipo | Default | Rango |
|---|---|---|---|
window_days | int | 7 | ≥1 |
limit | int | 5 | 1–50 |
Response: application/json, Cache-Control: no-store.
{
"generated_at": "2026-05-14T15:32:01.000Z",
"window_days": 7,
"total_checks": 25,
"drift_detected": 4,
"drift_pct": 16.0,
"avg_confidence": 0.82,
"total_cost_usd": 0.100,
"drafts_created": 0,
"last_check_at": "2026-05-14 14:00:00",
"top_drifts": [...]
}
Nota sobre la ruta: el endpoint vive en
drift-checks/index.ts(subcarpeta) para evitar que el catch-all[id].tsde/api/biblioteca/lo intercepte como un node ID. Mismo patrón quedrift/.
Patron de integración
Sigue el mismo patrón que functions/_lib/drift.ts (drift Escriba):
- Best-effort en el cliente: si el fetch falla, el PulsePanel muestra
—en lugar de romper la UI. no-storeenCache-Controlpara que cada carga del Pulse refleje el estado real.
Estado operativo
| Fase | Fecha | Estado |
|---|---|---|
Calibración (dry_run=true, max_pages=5) | 14-05-2026 → ~28-05-2026 | 🟡 Activa |
Régimen permanente (dry_run=false, max_pages=20) | ~28-05-2026 → | ⏳ Pendiente flip |
Durante calibración: drafts_created = 0, acumulación ~25 checks/semana.
Véase también
- [[decision—20260514—knowledge-base-vs-graph]]
- [[feature—biblioteca—pulse-drift-checks-widget]]