Tablero de planificación con un roadmap por fases y una matriz de impacto y dificultad

Roadmap MarkeUP

Roadmap MarkeUP: 40 ideas de mejora por impacto y dificultad

Roadmap de MarkeUP: auditoría profunda del vault con hallazgos reales, incoherencias y debilidades, y un catálogo priorizado de ideas por impacto y dificultad.

Admin6 de octubre de 2026, 17:0029 min de lectura

Esta nota es una auditoría profunda del vault y un catálogo de ideas, hecho el 2026-10-06 sobre el estado real del repositorio. No sustituye a la auditoría publicada: aquí el objetivo es otro — encontrar debilidades e incoherencias y proponer un abanico de mejoras con su impacto y su dificultad medidos. Se lee mejor de arriba abajo, pero cada sección se sostiene sola.

Cómo se hizo: modo lectura sobre el árbol real (no sobre lo que dice la documentación). Se corrieron npm run verify:content, npm run test, npm run doctor, npm run tools:stats, npm run tools:auditar, npm run validate:wikilinks, npm run validate:slugs y gh run list. Escritura concurrente (Syncthing): ninguna nota tocada en los últimos 10 minutos, así que las cifras son deterministas para la fecha.

Actualización (2026-10-06, mismo día): tras escribir este informe se aplicaron en local la Fase 0 / U1, U2 y U4 — el mktemp portable del gate, la fecha imposible de psicomotricidad-relacional (a 20:26) y la reconciliación del CI en AGENTS.md y docs/deploy.md. El CI pasará a verde en el próximo push (que hace Cloudflare Pages al desplegar); hasta entonces gh run list seguirá mostrando los runs antiguos en rojo.

Actualización (2026-10-06, 2.ª ronda): en la misma sesión se cerró el resto de la Fase 0, salvo U8. U3 — el gate de frontmatter ahora bloquea una fecha con la forma ISO pero valor imposible (T25:26): regla nueva fechaISOImposible en lib/frontmatter-spec.mjs + 6 tests. La causa era más fina de lo que parecía: el regex solo miraba la forma y, además, YAML coacciona un ISO sin comillas a Date y rueda el desbordamiento en silencio (T25:26 → día siguiente 01:26), así que el validador ahora relee el texto crudo del frontmatter para recuperar el valor original. U5 — fuera del árbol los artefactos que no son fuente del sitio: Modelfile, workflow-n8n.json, un Pasted image …png de 1,3 MB que llegaba a publicarse y un .DS_Store versionado, con reglas nuevas en .gitignore (src/content/posts/*.png, Modelfile, workflow-n8n.json) y la línea obsoleta del árbol de la arquitectura ya quitada. U6 — git gc --prune=now: la basura del repo (13,5 MB de un tmp_pack huérfano) desaparece y .git queda en un solo pack (~532 MB). U7 — vault-index.md regenerado (165 posts, 520 tags, 11 huérfanos prioritarios). U8 queda bloqueado: no se puede regenerar la caché de render mientras haya un astro dev vivo (borrarla deja el servidor sirviendo el vault vacío hasta reiniciarlo). Suite: 768/768 verdes, verify:content 6/6.

Actualización (2026-10-06, 3.ª ronda): abordadas las filas ⭐5-8 de la matriz. G1 — el mecanismo del vocabulario controlado de tags está hecho: scripts/mjs/lib/tags-vocabulary.mjs (lista maestra editable + SINONIMOS de fusión) y validate-frontmatter ahora avisa —en una línea resumen, no por post— de los tags fuera de la lista, que con --strict se suman a los errores (objetivo G3); +10 tests. La consolidación de la cola larga (≈400 tags de un solo uso) queda pendiente de aprobación: es decisión de contenido, no de script. G2 — tools:huerfanos ya priorizaba; se corrigió el falso positivo del extractor (contaba como enlaces los ejemplos dentro de backticks y el pipe escapado \| de las tablas), así que los huérfanos bajan de 213 a 191 reales. G4 — la PWA ya era instalable: site.webmanifest + iconos 192/512/maskable (npm run icons:pwa) + <link rel="manifest"> en BaseLayout, con el Service Worker ya registrado; el offline sigue parcial a propósito (cachear HTML reactiva el CSP obsoleto, ver public/sw.js). G6 (tiempo de lectura + barra .m-progress) y G7 (backlinks) ya estaban implementados: esta ronda solo los verifica y los marca. Suite: 778/778 verdes, verify:content 6/6.

Actualización (2026-10-06, 4.ª ronda): cerrado el circuito de G1 (consolidación del vocabulario de tags). Se detectó un hueco real: el informe pedía «aplica con npm run tools:tagfix», pero ese comando (Python) solo corrige 3 typos y no lee SINONIMOS, así que no había forma de aplicar al vault las fusiones declaradas. Entregado: (1) scripts/mjs/lib/tag-consolidation.mjs + CLI npm run tags:report → informe revisable en docs/tag-consolidation.md que clasifica el vocabulario en variantes · familias · islas y estima la reducción (no es un gate: propone); (2) scripts/mjs/lib/tag-apply.mjs + scripts/mjs/tags-apply.mjs + npm run tags:apply → aplicador que lee SINONIMOS y reescribe solo el campo tags del frontmatter (dry-run por defecto; -- --apply para escribir; preserva comillas e indentación; deduplica; nunca toca aliases ni el cuerpo). Con él se aplicaron las 7 variantes puras (ia/ai, consciencia, neurobiologia, orientalismo, skills, tailwindcss): 15 posts tocados (14 fusiones + 1 duplicado retirado) y el vault pasa de 520 → 513 tags únicos con 0 variantes. Quedan 33 familias (cabeza a crear o fusionar) y 322 islas de un solo uso, listas en el informe para el criterio editorial (fusionar, promover a wikilink o retirar). Tests nuevos del módulo de consolidación y del aplicador: +16 (→ 794/794). verify:content 6/6. Detalle en docs/tag-consolidation.md.

Actualización (2026-10-06, 5.ª ronda): aplicada la consolidación editorial de familias (G1 sigue 🟡). Con npm run tags:apply se fusionaron 44 tags en 39 posts (43 renombrados + 2 retirados por duplicado) ampliando SINONIMOS: sinónimos entre idiomas/número (la-mentira→mentira, coraza-muscular→corazas, image/imagenes→imagen, laban-analisis-movimiento/labanotacion→laban) y sub-tag → cabeza (historia-del-yoga→historia, terapia-*→terapia, psicologia-*→psicologia, salud-*→salud, movimiento-*→movimiento, conciencia-*→conciencia, respiracion-*→respiracion, ui*→ui-ux, danza*→danza-movimiento-terapia, anatomia-*→anatomia, estructura-osea→estructura…). El vocabulario suma 12 canónicos de cabeza (anatomia, aplicaciones, arquitectura, autoconciencia, corazas, estructura, imagen, laban, medicina, mentira, registros, rendimiento) → 122 canónicos. Falsas familias descartadas a propósito (el agrupado del informe es léxico): personas (carl-jung/carl-rogers, peter-*, mary-*), pares sin relación (deep-learning/deepseek) y cabezas que perderían sentido (desarrollo/desarrollo-motor, integracion-emocional/integracion-funcional, metodo-*, gimnasia-*, expresion*, psicoterapia*) más la familia agent* (Hermes vs docker). El vault pasa de 513 → 470 tags con 0 variantes, 12 familias (antes 33) y 322 islas; los tags fuera de la lista maestra bajan de 404 → 349. Los 67 avisos de calidad del gate no cambian (son longitud/estilo, no tags). Se endureció el aplicador: ahora también colapsa líneas de tag exactamente repetidas (+1 test) y se limpiaron los 2 duplicados que la fusión dejó (la-mentira, material-design-3). Suite: 795/795 verdes, verify:content 6/6. Detalle en docs/tag-consolidation.md.

Actualización (2026-10-06, 6.ª ronda): abordado I2 — búsqueda semántica (⭐9), el primer diferenciador de la Fase 3. Entregado un canal «buscar por significado» opt-in en el buscador (/search): LSA sobre TF-IDF precalculada en build (src/lib/semantic/, módulos puros y probados) y servida como /api/semantic.json, con la consulta y el coseno resueltos en el navegador — sin servidor, sin cookies, sin embeddings ni dependencias nuevas. Los vectores se cuantizan a int8 + base64, así que el índice baja de 938 KB a 440 KB (296 KB gzip) con dim 96 y vocabCap 3000. El canal está apagado por defecto: el índice solo se descarga al activar el interruptor (o al restaurar la preferencia de localStorage) y, si algo falla, el buscador sigue en modo léxico. Los aciertos que llegan solo por significado van a un grupo propio con badge; y si el léxico no encuentra nada, aparece un CTA para reintentar «por significado». Tests del subsistema semántico: +45 (→ 840/840). Manual técnico nuevo: docs/search.md. verify:content 6/6.

Actualización (2026-10-06, 8.ª ronda): búsqueda semántica medible (cierre con evidencia de I2). Se añadió un arnés de evaluación —scripts/data/search-golden.json (~32 consultas doradas, cada una con su slug esperado y su tipo: exacta/inflexión/parcial/alias/paráfrasis/typo) y src/lib/semantic/eval.ts (MRR + recall@3/5/10)— con un test que falla si el MRR cae del suelo (MRR_FLOOR 0.80; se salta si no hay build, para no romper el CI, que corre los tests antes del build) y un barrido opt-in de hipersparámetros (SEMANTIC_SWEEP=1). Sobre esa métrica, cada palanca se mide y solo se conserva si sube: (1) tolerancia a typos en la consulta (withinEditDistance1, Damerau-Levenshtein ≤ 1 → «resperacion» → «respiracion») — 0.732 → 0.774 de MRR; (2) aliases como campo del índice (peso 2) + dim 96 → 160 — MRR 0.814, recall@5 90.6 %, recall@10 96.9 %, índice 694 KB; (2b) aliases forzados al vocabulario (alwaysTerms: un alias raro que el vocabCap dejaba fuera —el nombre original en inglés de una técnica, p. ej.— igualmente entra y se recupera) — MRR 0.847, recall@5 93.8 %, recall@10 100 %, índice 713 KB (~429 KB gzip), medido aislado (off/on sobre el mismo corpus); (3) se implementó y descartó la realimentación Rocchio (β 0.2–0.8: subía el MRR por debajo del ruido de la métrica —1/32 por consulta— y costaba una segunda pasada de scoring), mismo criterio con que ya se revirtió la potenciación de la SVD. El límite conocido —un alias raro (poca masa) se quedaba fuera del vocabulario— quedó cerrado con alwaysTerms. Tests del subsistema: +12 (→ 64 en src/lib/semantic/, con 3 casos nuevos para alwaysTerms). Doc actualizada (docs/search.md § «Evaluación»; doc-buscador § 11.2/12.5/15). verify:content 6/6.

Actualización (2026-10-06, 9.ª ronda): el arnés dorado se ensancha y se afila. El conjunto de consultas doradas de la búsqueda semántica pasó de ~32 a ~56 (mismos seis tipos: exacta/inflexión/parcial/alias/paráfrasis/typo), lo que baja el ruido del gate (1/56 ≈ 0.018 por consulta) y lo hace más fiable. Sobre él se midió y se conservó una nueva palanca del lado consulta (sin reindexar): el backoff raíz↔plural (stemBackoff) — una palabra que casa exacto en el vocabulario (p. ej. el plural «movimientos») añade también su singular si está («movimiento») a peso reducido, de modo que una consulta en plural alcanza las notas que solo usan el singular—, que sube el MRR 0.836 → 0.849 con tres consultas que ganan puesto y ninguna que empeore (comparación aislada on/off sobre el mismo índice). El arnés ganó una salida verbosa por consulta (EVAL_VERBOSE=1 npm run search:eval) que imprime el rango de cada acierto, no solo los fallos. Queda una consulta difícil honesta («arquitecturas» → doc-arquitectura, término de idf bajo). Tests del subsistema semántico: +2 (→ 66 en src/lib/semantic/). Doc actualizada (docs/search.md § «Evaluación»; doc-buscador § 11.2/12.5/15).

Actualización (2026-10-06, 10.ª ronda): el vocabulario fuerza el tema declarado. Se midió, ya sobre las 56 consultas, forzar al vocabulario del índice semántico los términos del tema declarado de cada nota —concept y title— además de los aliases curados (alwaysTerms): una palabra distintiva del título que el vocabCap cortaba dejaba de recuperar las consultas que solo apuntan a ella. Es una palanca del lado índice (reindexa, a diferencia del stemBackoff) y se conservó: sube el MRR 0.850 → 0.871 y el recall@5 92.9 % → 94.6 % con cuatro consultas que ganan puesto y ninguna que empeore, por +16 KB (índice 713 → 729 KB · ≈ 428 KB gzip), y con ello el suelo sube (MRR_FLOOR 0.80 → 0.85). También se descartó tras medirlo lo que no compensaba: forzar los términos de la description (+61 KB sin ganancia), los tags (regresaban consultas) y aflojar los FIELD_WEIGHTS (bajaba el MRR). Doc actualizada (docs/search.md § «Evaluación»; doc-buscador § 11.2/12.5/15).

MétricaValor real (2026-10-06, tras Fase 0 + 5.ª ronda)ObjetivoEstado
Posts escaneados165——
Errores de frontmatter00✅
Avisos de frontmatter670⚠️ deuda
Avisos de SEO500⚠️ deuda
Tests unitarios795 / 795todo verde✅
Gate de contenido (verify:content)6/6 validadores OKverde✅
CI de GitHub Actions3 runs en rojo (mktemp — corregido)verde🔧 fix local, pendiente de push
Tags únicos470vocabulario controlado🟡 0 variantes · 12 familias (G1 aplicado)
Tags con 1 sola aparición351bajo⚠️ ruido
Huérfanos (tools:auditar)191< 15 %⚠️
Huérfanos (validate:wikilinks)176< 15 %⚠️
Notas sin wikilinks20⚠️
Posts sin imagen real40⚠️
Tamaño de .git532 MBestable✅ (gc 2026-10-06)

El nivel global es BUENO con asteriscos: el contenido no rompe nada (el gate está verde y 795 tests pasan) y la incoherencia de infraestructura que dejaba el CI en rojo ya está corregida en local (pendiente del próximo push); queda deuda de higiene acumulada y una capa de metadatos (tags, huérfanos) que pide criterio humano, no más scripts.


Nota de lectura: las cifras y los hallazgos de esta sección son la foto de la auditoría (2026-10-06, por la mañana). Los bichos 1 (el mktemp del CI) y 2 (la fecha imposible) ya están resueltos en la Fase 0; el 3 (la caché de render) siguió pendiente hasta cerrar el dev server. El estado aplicado está en la tabla de la sección 0 y en la matriz de la sección 6.

1. El CI está en rojo y nadie lo mira. Los tres últimos push a main fallan en el paso «Verify content». La causa no es el contenido: es un mktemp no portable. En scripts/sh/verify-content.sh la línea 87 hace mktemp -t markeup-content-gates; el mktemp de GNU/Linux exige al menos tres X en la plantilla y aborta con too few X's in template. En macOS (BSD) se tolera, por eso pasa en local y falla en el runner. Un verify:content verde en tu Mac convive con un CI rojo desde el 2026-10-04.

2. Una fecha imposible viaja por el vault. Humano/psicomotricidad-relacional.md tiene pubDate: 2026-09-08T25:26:00.000Z (hora 25). Un parser YAML estricto lanza hour must be in 0..23; new Date('…T25:26…') en JavaScript da Invalid Date. El esquema Zod lo tapa (cae a new Date() por el transform), así que no rompe el build, pero cualquier herramienta que lea esa fecha fuera de Astro ve basura. Es exactamente el tipo de dato que el gate debería avisar y hoy no ve.

3. El render cacheado bloquea la publicación en frío. npm run doctor marca en ✗ la caché de render: src/lib/tts/speech.ts es más reciente que la caché y hay un astro dev vivo en :4321. Mientras el dev server esté abierto, content:cache no puede invalidar y un build serviría el HTML viejo de las notas. No es un fallo del código: es un estado del entorno que conviene que el flujo detecte antes de intentar publicar (documentado, pero fácil de pisar).

4. AGENTS.md desinforma sobre el CI. El contrato del workspace afirma que «hoy GitHub Actions no arranca (facturación de la cuenta)». La realidad medida con gh run list: el workflow sí corre y falla (tres runs completados con failure). Un agente que se fíe del AGENTS.md dará por bueno el verde local y no mirará el runner. La documentación y la verdad deben reconciliarse (arreglar el mktemp o contar el estado real).

5. Dos sistemas de documentación paralelos. El sistema se documenta en docs/*.md (deploy, media, grafos, TTS…) pero la cara pública y buena parte de la operación vive en posts Documentación/doc-* y Documentación/skill-*. Hay contenido duplicado con fecha de última revisión distinta en cada copia. No es un error por sí mismo, pero cada cambio obliga a tocar dos sitios y ya hay deriva (ver punto 8).

6. El índice del vault nace viejo. src/content/hermes/memory/vault-index.md dice «Total notas: 161 … Huérfanos: 246» (2026-10-05). El vault real tiene 164 posts y 176–213 huérfanos según la definición. Quien cree un post leyendo el índice parte de una foto caducada; solo npm run tools:index lo refresca, y no forma parte de ningún gate.

7. doc-auditoria.md describe un proyecto que ya no existe. Su cabecera habla de 74 posts y 76 tests; hoy son 164 y 762. El post que un lector usa para entender «el estado técnico» da cifras de hace semanas. Igual que el índice, envejece sin que nada lo avise.

8. 67 avisos de frontmatter y 50 de SEO. El bloque dominante son tags de 7 valores (la spec recomienda 2-6), title fuera de 50-75 y updatedDate anterior a pubDate (los 9 posts skill-*, generados por npm run skills:publish). Nada bloquea, pero es la cola que hace que el SEO se lea «casi» bien en vez de perfecto.

9. 514 tags para 164 posts, 397 de un solo uso. El vocabulario está disperso: casi el 77 % de las etiquetas aparece una sola vez. Las páginas /tags/<tag> de un tag de un uso no aportan navegación; el buscador y el grafo cargan con ruido. documental (106), somatica (23), hermes (19), biodanza (14) son los que de verdad estructuran; el resto pide criterio (fusionar, subir a wikilink o retirar), no automatización a ciegas.

10. 213 huérfanos y 26 aliases redundantes. Los huérfanos son normales (conceptos transversales sin nota), pero hay un puñado prioritarios por repetición: teoria-polivagal (13×), psicomotricidad-relacional-desarrollo-personal (8×), homeostasis-biologica (5×), sistema-nervioso (4×), test-muscular (4×). El alias [[slug|slug]] (redundante) sigue apareciendo en 26 avisos de validate:slugs.

11. .git volvió a engordar: 546 MB. La auditoría de septiembre lo dejó en 207 MB; hoy git count-objects dice 530 MB en pack (más 13,5 MB de garbage: un tmp_pack_* huérfano). Los binarios de contenido (PNG, audios) re-añadidos a lo largo de los commits reconstruyeron el historial. Toca git gc/repack y decidir la política de binarios.

12. Basura versionada dentro del contenido.

  • src/content/posts/Pasted image 20261003163800.png (1,3 MB, trackeado) — pegote de Obsidian en la raíz del contenido.
  • src/content/posts/Base.base (vista de Obsidian) en el working tree; tmp/, .smart-env/, .obsidian/, .DS_Store conviven con los posts.
  • En la raíz: Modelfile (residuo de Ollama), workflow-n8n.json (n8n sin uso), AUDIT.md y logs/. Ninguno es fuente del sitio.

13. Artefactos generados que engordan el disco. public/audpublic 83 MB, public/img 112 MB, dist 308 MB, src 475 MB. Buena parte es necesaria (los audios son el producto), pero conviene saber qué pesa y por qué antes de que el build se vuelva lento por acumulación.

14. Cuatro categorías y una dominante. Humano 108, Máquina 28, Documentación 25, Literatura 2, Opinión 1. Es coherente con el foco del autor, pero /category/Literatura y /category/Opinión muestran una sola página en su grafo: se ven desnudas. Y el tag documental está en 106 de 164 posts (≈65 %): funciona, pero casi todo es «documental», así que como filtro discrimina poco.


No todo lo «urgente» es urgente. Solo entra aquí lo que ya está roto o bloquea trabajo futuro. Todo es de impacto alto y dificultad baja: son arreglos, no proyectos.

#IdeaPor qué es P0ImpactoDificultadEsfuerzoCómo
✅ U1Arreglar el mktemp del gate (mktemp -t markeup-content-gates.XXXXXX o "$(mktemp -d)/gates.log")El CI lleva días rojo por esto; deja «verde» una puerta que no lo esAltoBaja15 mineditar verify-content.sh (ruta + .XXXXXX) + gh run list para confirmar
✅ U2Corregir la fecha 2026-09-08T25:26 de psicomotricidad-relacionalInvalid Date en cualquier lector; YAML estricto revientaMedioBaja5 mineditar el frontmatter a T20:26 (hora asumida)
✅ U3Que verify:content avise de fechas no-ISO (hora >23, mes >12)Es el agujero por el que entró U2; un aviso lo cierra para siempreMedio-altoBaja1 hregla en lib/frontmatter-spec.mjs + test
✅ U4Reconciliar AGENTS.md con el estado del CIDocumentación que miente es peor que ausente; guía a los agentes al errorMedioBaja20 minreescribir el párrafo de CI en AGENTS.md
✅ U5Sacar la basura del contenido y de la raíz (Pasted image…png, Base.base, tmp/, Modelfile, workflow-n8n.json)Contenido y fuente mezclados; el .png pesa 1,3 MB y se publicaMedioBaja30 mingit rm, .gitignore, borrar temporales
✅ U6git gc --prune=now + borrar el tmp_pack huérfano546 MB y creciendo; el clon y el diff se degradanMedioBaja20 mingit gc + git count-objects -vH
✅ U7Refrescar vault-index.md y el recuento de doc-auditoria.mdQuien los lee trabaja con una foto vieja (161 vs 164, 74 vs 164)Bajo-medioBaja20 minnpm run tools:index + editar el post
U8Regenerar la caché de render (npm run content:cache -- --force) tras cerrar el devCon un astro dev vivo, el build puede servir HTML viejoMedioBaja5 mincerrar el dev y relanzar

Cosas que se notan y que se hacen con lo que ya existe. Dificultad media, beneficio claro y acumulativo.

Estado: ✅ hecho · 🟡 parcial (la herramienta está hecha; falta contenido o criterio) · ⬜ pendiente.

#EstadoIdeaQué gana el sitioImpactoDificultad
G1🟡 ParcialVocabulario controlado de tags (mecanismo + informe + aplicador): lista maestra editable (scripts/mjs/lib/tags-vocabulary.mjs) y el gate avisa de los tags fuera de ella (--strict los suma a los errores, +10 tests); npm run tags:report clasifica la cola (variantes · familias · islas) y npm run tags:apply fusiona las variantes aprobadas en el frontmatter (520 → 470 tags, 0 variantes); quedan 12 familias y 322 islas por criterio humano/tags y los filtros vuelven a orientar; el grafo pierde ruidoAltoMedia
G2🟡 ParcialAtaque a huérfanos priorizados: tools:huerfanos ya ordena por apariciones (🔴/🟡/🟢) y se corrigió el falso positivo de código (backticks y pipe escapado |): 213 → 191 reales; queda crear 5-8 notas para los conceptos con 3+ aparicionesMejora la densidad de wikilinks y el grafo; content realAltoMedia
G3⬜ PendienteCero avisos en validate:frontmatter -- --strict y validate:seoPrestigio interno; el SEO deja de ser «casi»MedioMedia
G4🟡 ParcialPWA instalable (instalable hecho; offline no): site.webmanifest + iconos 192/512/maskable (npm run icons:pwa) + <link rel="manifest">, con el Service Worker ya registrado. El offline sigue siendo parcial a propósito (el HTML no se cachea: el CSP viaja con el documento, ver public/sw.js); precachear posts recientes es una decisión aparteLectura sin red en móvil; instalableMedio-altoMedia
G5⬜ PendienteRSS por categoría y por tag (/category/Humano/feed.xml)Suscripción granular; más superficie de descubrimientoMedioBaja-media
G6✅ HechoTiempo de lectura + barra de progreso (hecho): getReadingTime en PostHero y barra .m-progress en CSS puro (animation-timeline: scroll(), vigilada por verify:motion)Percepción de calidad y retenciónBajo-medioBaja
G7✅ HechoBacklinks visibles (hecho): bloque «Posts que enlazan a este artículo» (getBacklinksInSection + setBacklinks, con contexto ?from=), cubierto por verify:previewEl vault se explora como red, no como listaMedioMedia
G8⬜ PendienteComentarios con giscus (usa allowComments que ya existe pero hoy no lleva a ningún sitio)Comunidad sin backend propioMedioBaja-media
G9⬜ PendientePágina de estado /status con conteos vivos (posts, tags, huérfanos, último build)Transparencia y una home de operación del vaultBajo-medioMedia
G10⬜ PendienteTests E2E de humo con Playwright: home → post → grafo → buscador, sin errores de consolaCorta regresiones visuales/graph antes de producciónMedio-altoMedia
G11⬜ PendienteLimpieza de aliases redundantes (26 avisos `[[slugslug]]`)Higiene y menos ruido del linterBajo
G12⬜ PendienteHigiene de dependencias y npm audit en CISeguridad sostenidaMedioBaja

Funciones que aprovechan lo que ya tienes (grafo, TTS, búsqueda en el navegador, Ollama local, Hermes) y elevan mucho la percepción. Dificultad alta, pero cada una es un diferenciador real.

#IdeaEl «wow»ImpactoDificultad
I1«Pregunta al vault» (RAG 100 % estático): pre-generar embeddings en build y responder consultas en el navegador con recuperación localUn chat que cita tus notas, sin servidor ni cookiesAltoAlta
I2Búsqueda semántica junto a la léxica de Pagefind — hecho (2026-10-06): sin embeddings ni dependencias nuevas, LSA sobre TF-IDF precalculada en build (src/lib/semantic/), canal opt-in en /search y /api/semantic.json cuantizado a int8 (índice ~729 KB · ~428 KB gzip, dim 160, con el tema declarado —concept + title— y los aliases forzados al vocabulario), con evaluación dorada (MRR ≥ 0.85) y tolerancia a typos en la consulta«Encuentra por significado», no por palabra exactaAltoAlta
I3Podcast automático del vault: usar el TTS ya montado para narrar cada post y servirlo como audio público con feed propioEl blog se escucha; canal nuevo enteroAltoAlta
I4Grafo temporal: animar cómo crece la red de notas por fecha de publicaciónCuenta la historia del vault en el tiempoMedio-altoAlta
I5Modo libro: leer una categoría de corrido, con navegación secuencial, índice lateral y progresoUna categoría deja de ser lista y pasa a ser obraMedio-altoMedia-alta
I6Resúmenes y «lo esencial» con Ollama local en build (sin nube): 3 bullets por post y una sinopsis por categoríaEnriquecimiento masivo, gratis y privadoMedio-altoMedia-alta
I7Ficha comparadora de terapias/enfoques (tabla interactiva por familia, a partir de los tags)Convierte 100 notas sueltas en un mapa consultableMedio-altoMedia-alta
I8Espejo del grafo en 3 archivos: exportar el grafo a GEXF/GraphML/JSON descargableInvestigadores y Obsidian pueden reusarloMedioMedia
I9«Nota aleatoria» / serendipia y «sigue leyendo» por afinidad de grafoDescubrimiento entretenido, sesiones más largasMedioMedia
I10Timeline visual de publicaciones y de temas (por mes y por categoría)Da contexto y ritmo al catálogoMedioMedia
I11Modo foco / lectura zen (oculta cromo, tipografía a medida, guarda posición)Lectura larga sin fricciónBajo-medioMedia
I12Export a ePub del vault o de una categoríaTu contenido, portable y offlineMedioMedia-alta

Ideas que cambian qué es el proyecto, no solo cómo se ve. Alto riesgo, alto retorno; se abordan solo si las fases anteriores están verdes.

#IdeaApuestaImpactoDificultad
M1MCP server del vault: exponer búsqueda, grafo y notas como herramientas para agentesEl vault se vuelve una fuente para IA, no un sitioAltoAlta
M2Vault como API: /api/posts.json ya existe; publicar endpoints de grafo, tags, búsqueda y relaciones documentadasTerceros construyen sobre tu contenidoAltoMedia-alta
M3i18n bilingüe (es/en) con hreflang real (hoy descartado por prematuro)Doble audiencia y alcance SEOAltoMuy alta
M4Espacio de trabajo interactivo: cliente ligero sobre el mismo grafo para editar/curar el vault desde el navegadorDeja de ser solo lecturaMedio-altoMuy alta
M5Newsletter con generación de entregas desde el RSS y las categoríasCanal propio, lista de correoMedio-altoMedia-alta
M6«Cite this» / BibTeX por post y DOI-like para el vaultUso académicoMedioMedia
M7Storybook / catálogo de componentes vivo en el sitioDocumenta y luce el sistema de diseñoBajo-medioMedia
M8Observabilidad propia: dashboard de salud del build (páginas, peso, LCP) versionado como JSONOperación con datos, no a ojoMedioMedia-alta
M9Modo «constelación de una consulta»: dado un tema, ilumina el subgrafo relevante y ordena una ruta de lecturaConvierte la búsqueda en un recorrido guiadoAltoAlta
M10Changelog público automático desde los feat/fix de git, con enlaces a los posts afectadosTransparencia y narrativa de productoMedioMedia

La regla práctica es quick wins → cimientos → apuestas: primero lo de alto impacto y baja dificultad (te devuelve tiempo y credibilidad), luego lo estructural, y solo después lo caro que luce.

Estado: ✅ hecho · 🟡 parcial · ⬜ pendiente. La columna Horizonte es la fase prevista, no un estado.

PrioridadIdeaCuadranteEstadoHorizonte
⭐ 1U1 — arreglar mktemp (CI)Alto impacto / baja dificultad✅ HechoEsta semana (Fase 0)
⭐ 2U2 — fecha imposibleAlto valor / trivial✅ HechoEsta semana (Fase 0)
⭐ 3U4 — reconciliar AGENTS.md con el CIConfianza / trivial✅ HechoEsta semana (Fase 0)
⭐ 4U3 — fecha imposible en el gateHigiene / bajo coste✅ HechoEsta semana (Fase 0)
⭐ 4U5 + U6 + U7 — basura, git gc e índiceHigiene / bajo coste✅ HechoEsta semana (Fase 0)
⭐ 5G1 — vocabulario de tagsAlto / medio🟡 Parcial (mecanismo + informe + aplicador; variantes y familias aplicadas, 520→470; quedan 12 familias residuales e islas)Este mes (Fase 1)
⭐ 6G2 — huérfanos prioritariosAlto / medio🟡 Parcial (herramienta; faltan 5-8 notas)Este mes (Fase 1)
⭐ 7G4 — PWA offlineNotable / medio🟡 Parcial (instalable; offline no)Trimestre (Fase 2)
⭐ 8G7 + G6 — backlinks + tiempo de lecturaPercepción / medio✅ HechosTrimestre (Fase 2)
⭐ 9I2 — búsqueda semánticaWow / alto✅ Hecho (canal opt-in en /search; src/lib/semantic/ LSA, sin dependencias)Trimestre (Fase 3)
⭐ 10I1 — «pregunta al vault»Wow / alto⬜ PendienteTrimestre (Fase 3)
⭐ 11I3 — podcast del vaultWow / alto⬜ PendienteTrimestre (Fase 3)
⭐ 12M1 — MCP del vaultApuesta / alto⬜ PendienteSin fecha (Fase 4)

Esto es el cuándo (el orden en que se hacen), no el estado. Qué está hecho / parcial / pendiente se lee en §3 y §6; aquí las fases solo reparten lo que falta.

Fase 0 — Saneamiento (esta semana). U1 a U8 (U1 a U7 hechos; U8 bloqueado por el dev server vivo). Objetivo: CI en verde de verdad, sin datos imposibles, sin basura en el camino, .git en forma. Todo de dificultad baja; el efecto es inmediato y desbloquea lo demás.

Fase 1 — Cimientos de contenido (este mes). G1, G2, G3, G11, G12. Vocabulario de tags, huérfanos priorizados y cero avisos. Es el trabajo que hace que el grafo y el buscador rindan con lo que ya tienes, antes de añadir funciones nuevas. (G1: mecanismo ✅ + tags:report/tags:apply (variantes y familias aplicadas: 520→470; quedan 12 familias residuales e islas); G2: herramienta ✅.)

Fase 2 — Experiencia (próximo trimestre). G4, G5, G6, G7, G8, G9, G10. La capa que el visitante siente: offline, suscripción, backlinks, comentarios, tests E2E. (G4: instalable ✅ — offline completo pendiente; G6 y G7 ✅ hechos.)

Fase 3 — Diferenciadores (trimestre+). I1 a I12. Aquí el sitio deja de competir con un blog y pasa a ser un sistema de conocimiento: búsqueda semántica, podcast, grafo temporal, modo libro. (I2 ✅ hecho el 2026-10-06: canal «buscar por significado» opt-in en /search, detalle en docs/search.md.)

Fase 4 — Apuestas (sin fecha). M1 a M10. Se decide con las fases 0-3 cerradas y con datos: MCP, API pública, i18n.

Para que cualquier agente o tú mismo reproduzcáis las cifras:

cd /Users/ernestouriszar/markeup
export PATH="/opt/homebrew/bin:$PATH"

npm run verify:content        # gate de contenido (6 validadores) — verde en local
npm run validate:frontmatter  # 165 posts · 0 errores · 67 avisos
npm run validate:seo          # 50 avisos de calidad
npm run validate:slugs        # 0 colisiones · 26 aliases redundantes
npm run validate:wikilinks    # 176 huérfanos · 0 sin alias
npm run tools:stats           # 470 tags únicos · counts por categoría
npm run tags:report           # informe de consolidación (470 tags · 0 variantes · 12 familias · 322 islas)
npm run tools:auditar         # 191 huérfanos · 2 notas sin wikilinks
npm test                      # 794 tests · 46 ficheros
npm run doctor                # 6 ✓ · 0 ⚠ · 1 ✗ (caché de render)
gh run list --limit 3         # ⚠️ 3 runs en rojo (mktemp)

Dos notas de lectura, para no repetir diagnósticos: los huérfanos tienen dos definiciones válidas (191 cuenta todo destino sin nota; 176 descuenta los que resuelven por alias) — siempre hay que citar de qué comando sale el número. Y los «avisos» de los gates de frontmatter/SEO son deuda de calidad, no fallos: no bloquean la publicación.

Siguiente paso natural: con la Fase 0 cerrada (U8 sigue pendiente del dev server vivo), entrar en la Fase 1 — consolidar el vocabulario de tags (propuesta + aplicador ya están: variantes y familias aplicadas, 520→470; quedan 12 familias residuales e islas por criterio), atacar los huérfanos prioritarios y, si se quiere dejar el gate a cero, activar el --strict (G3).

Para el contexto técnico, ver la arquitectura del proyecto, el buscador, los grafos y los medios embebidos; y la lista de trabajo de contenido, en el TODO de terapias somáticas. La operación diaria está en la guía de operación y la publicación en publicar.

Roadmap MarkeUP

Explora las ramas del artículo

Posts que enlazan a este artículo

doc-buscador-MarkeUP