User value
Cualquier edición directa a src/content/wiki/*.md (sea manual de Edu/Dani, de un subagente, de un script) queda automáticamente reflejada en la base de datos D1 sin necesidad de pasar por Sonnet. Antes de este fix, ediciones masivas del repo (típicamente en commits supercontext: o docs:) provocaban drift D1↔repo: el lint reportaba orphans y stale fantasma mientras el repo estaba correcto. La reconciliación cierra ese gap de forma determinista, gratuita y sin tocar el LLM.
Problema observado (sesión 18, 2026-04-23)
Durante el enriquecimiento de 18 pages hub (commit c4eaaff) para cerrar las 15 orphans detectadas por wiki_lint_bulk, el Ingest hizo skip pre-LLM (correctamente: el commit era supercontext:). Resultado: el repo tenía related enriquecido con backlinks a las 15 orphans, pero bib_wiki_pages.related en D1 seguía con el valor antiguo. El lint siguió reportando las mismas 15 orphans aunque el Obsidian graph view sí las mostraba conectadas.
Causa raíz: los dos únicos caminos que actualizan D1 son (a) Sonnet procesando el commit vía MCP wiki_update_page, (b) skills/curator invocando tools MCP explícitamente. Ninguno se dispara en un skip pre-LLM o Haiku, aunque el commit haya tocado páginas wiki.
Diseño
Nuevo branch en bib_ingest.py que se ejecuta tras cualquier skip y propaga campos metadata del front-matter del repo a D1 vía MCP:
- Parser YAML minimalista (stdlib
re, sin PyYAML): soporta campos string simples y arrays inline[a, b]+ multi-línea con- item. Ignora mappings anidados comosources:de objetos (no necesarios para reconcile). - Whitelist de campos reconciliados:
title, status, owner, supersedes, last_verified(meta) +tags, related(lists). El resto se ignora. - Patch object sin
content: la tool MCPwiki_update_pageaceptapatchcomo objeto parcial de metadata. Si no se envíacontent, no hace commit al repo → no hay loop push→ingest→push. - Silencio en legacy: pages no presentes en D1 (ej. las 7 pages migradas en el backfill sesión 17 que quedaron solo-repo) devuelven “Page not found” y se contabilizan como
skipped_not_in_d1sin ser error.
Integración
Llamada en los dos puntos de skip del pipeline 3-tier:
- Tier 1 skip pre-LLM: commits
chore:,docs:,supercontext:sin paths ricos. - Tier 2 skip Haiku: cambios que el triage Haiku decidió no escalar a Sonnet.
El summary del skip se enriquece con | reconcile: N D1 pages synced cuando N > 0, visible en el Pulse en tiempo real.
Validación end-to-end (sesión 18)
Tres commits de test progresivos sobre el workspace:
190c376— toque de 1 hub (concept--biblioteca--supercontexto) →[Reconcile] D1 sync: 1 updated, 0 legacy-skip, 0 failed. Orphans 15 → 9.203ae4a— bulk touch de 17 hubs →[Reconcile] D1 sync: 10 updated, 7 legacy-skip, 0 failed(los 7 legacy son pages del backfill solo-repo). Orphans 9 → 2.0603b55— cierre de las 2 orphans restantes editando 4 hubs D1 adicionales →[Reconcile] D1 sync: 4 updated, 0 legacy-skip, 0 failed. Orphans 2 → 0.
En total, 15 pages pasaron de “orphan en D1” a conectadas sin un solo token LLM gastado en el propio reconcile.
Decisiones
- Reconcile solo en branch skip, no en éxito Sonnet: Sonnet ya escribe en D1 vía MCP cuando procesa; reconcile encima sería doble escritura y ruido de log. Si un día Sonnet procesa sin tocar un .md que sí cambió, saldrá en el lint semanal y se corregirá con un commit posterior.
- Sin content en el patch: crucial para evitar loop. El commit al repo ya está hecho por quien editó; reconcile solo propaga metadata a D1.
- Parser stdlib-only: no se añade PyYAML como dependencia. El mini-parser cubre el 100% de los campos Supercontexto relevantes; lo que no cubre (sources anidados) tampoco es campo reconciliado.
- Paridad en los 3 repos: el mismo patch se aplicó a
bib_ingest.pydel workspace y de CreaRack-Pro + doc canónica enclaude-method/biblioteca/prompts/ingest.md. CreaRack-Pro nunca editasrc/content/wiki/, pero mantener paridad de código reduce drift futuro.
Limitaciones conocidas
- Pages que no existen en D1 (como las 7 legacy del backfill sesión 17) no se sincronizan — siguen solo-repo. Para resolverlo, indexarlas con
wiki_create_page(tarea aparte). sources:no se reconcilia. Raramente cambia sin tocar el body; si emerge el caso, extender el parser con soporte de mapping anidado.
Véase también
- [[concept—biblioteca—supercontexto]]
- [[feature—supercontext—bibliotecario-lint-fase-5]]
- [[feature—supercontext—fase-4-query-con-cierre]]
- [[feature—supercontext—fase-6-metricas-utility]]
- [[entity—mcp—tool—wiki-lint-bulk]]
- [[entity—mcp—tool—wiki-curator-review]]
- [[incident—20260421—d1-bind-overflow-silent]]
Referenciado desde
- Arquitectura completa del Supercontexto / Biblioteca (mapa vivo)
- Biblioteca — Grafo + Archivo Maestro + Wiki Supercontexto
- Catálogo completo de la wiki Supercontexto
- Enrichment Agent Blueprint — Cloudflare Queues + Anthropic Batch API (50% off)
- Front-matter durables: sincronización repo→D1 de metadata (PR#136)
- Hardening del Bibliotecario · PR4 — Enriquecimiento automático de backlinks (wiki_enrich_related)
- Índice de la Wiki Supercontexto
- Ingest Bibliotecario en 3 capas: pre-LLM + Haiku + Sonnet caching
- Sistema Supercontexto · wiki auto-mantenida con grafo D1
- Tool MCP: wiki_index_metadata — Adopción de pages solo-repo a D1