Resumen
Fix + Feature que resuelve el bug s195 donde los cambios de metadata (status, tags, related, supersedes, last_verified) quedaban atrapados en D1 y se revertían automáticamente durante el reconcile nocturno repo→D1, porque la lectura del .md rancio en el repo sobrescribía el estado actualizado en la base de datos.
Implementa una sincronización quirúrgica de campos “durables” al front-matter de .md, garantizando que el reconcile no revierte cambios ya persisten en el repositorio.
Problema (s195)
Cuando el editor wiki (wiki_update_page) actualizaba un campo de metadata en D1 solamente, el siguiente reconcile nocturno:
- Leía el
.mddel repo (sin la actualización). - Extraía el front-matter antiguo.
- Escribía ese frente-matter en D1, revertiendo el cambio.
Resultado: 3 promociones perdidas en una sesión porque los cambios a status/tags/related se evaporaban silenciosamente.
Afectados: campos relativos a governance (status, tags, related, supersedes) y auditoría (last_verified).
Solución: DURABLE_FM_FIELDS
Se introduce una lista explícita de campos cuyo cambio DEBE reflejarse en el .md:
const DURABLE_FM_FIELDS = ['status', 'tags', 'related', 'supersedes', 'last_verified'];
Cuando wikiUpdatePage() realiza un patch metadata-only (sin body) que toca al menos un campo durable:
- Fetch del
.mdactual del repo via GitHub API. - Extrae el bloque front-matter.
- Reemplazo quirúrgico de las líneas afectadas usando
applyFrontMatterLines(). - Commit directo con el
.mdactualizado.
Campos no durables (ej: drift-checks aislados de last_updated_by) siguen siendo D1-only → no spamean commits innecesarios.
Implementación técnica
applyFrontMatterLines(fmBlock: string, lines: Record<string, string>): string
Reemplazo de líneas sin re-serialización completa del front-matter:
- Por cada field en
lines, intenta hacer replace de la línea existente (^field:.*$). - Si no existe, inserta antes del cierre
---. - Preserva orden, comentarios, y otros campos sin tocar.
Evita arrastrar cambios indeseados o romper sintaxis YAML.
Modificación en wikiUpdatePage()
Tras actualizar D1, si:
newBody === null(patch metadata-only).!deferCommit(commit directo, no parkeo).env.GH_PATdisponible.- Algún campo en
metaUpdatesestá enDURABLE_FM_FIELDS.
Entonces:
- Obtiene SHA y contenido actual del
.mdvia GitHub API. - Extrae front-matter.
- Aplica cambios quirúrgicos con
applyFrontMatterLines(). - Si
relatedcambió, también refresca la sección `
Véase también
- [[docsupercontextatlas-arquitecturafichasworkspace-ws3-wikimd]]
- [[concept—saas—multi-tenancy]]
- [[entity—functions—handler—wiki]]