CreaRack-SL

Sincronización de metadatos durables (.md ↔ D1)

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:

  1. Leía el .md del repo (sin la actualización).
  2. Extraía el front-matter antiguo.
  3. 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:

  1. Fetch del .md actual del repo via GitHub API.
  2. Extrae el bloque front-matter.
  3. Reemplazo quirúrgico de las líneas afectadas usando applyFrontMatterLines().
  4. Commit directo con el .md actualizado.

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_PAT disponible.
  • Algún campo en metaUpdates está en DURABLE_FM_FIELDS.

Entonces:

  1. Obtiene SHA y contenido actual del .md via GitHub API.
  2. Extrae front-matter.
  3. Aplica cambios quirúrgicos con applyFrontMatterLines().
  4. Si related cambió, también refresca la sección `

Véase también

  • [[docsupercontextatlas-arquitecturafichasworkspace-ws3-wikimd]]
  • [[concept—saas—multi-tenancy]]
  • [[entity—functions—handler—wiki]]