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.
Navegando en el blogver navegación en todos los blogs
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:slugsygh 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
mktempportable del gate, la fecha imposible depsicomotricidad-relacional(a20:26) y la reconciliación del CI enAGENTS.mdydocs/deploy.md. El CI pasará a verde en el próximo push (que hace Cloudflare Pages al desplegar); hasta entoncesgh run listseguirá 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 nuevafechaISOImposibleenlib/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 aDatey rueda el desbordamiento en silencio (T25:26→ día siguiente01: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, unPasted image …pngde 1,3 MB que llegaba a publicarse y un.DS_Storeversionado, 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 untmp_packhuérfano) desaparece y.gitqueda en un solo pack (~532 MB). U7 —vault-index.mdregenerado (165 posts, 520 tags, 11 huérfanos prioritarios). U8 queda bloqueado: no se puede regenerar la caché de render mientras haya unastro devvivo (borrarla deja el servidor sirviendo el vault vacío hasta reiniciarlo). Suite: 768/768 verdes,verify:content6/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 +SINONIMOSde fusión) yvalidate-frontmatterahora avisa —en una línea resumen, no por post— de los tags fuera de la lista, que con--strictse 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:huerfanosya 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">enBaseLayout, con el Service Worker ya registrado; el offline sigue parcial a propósito (cachear HTML reactiva el CSP obsoleto, verpublic/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:content6/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 leeSINONIMOS, así que no había forma de aplicar al vault las fusiones declaradas. Entregado: (1)scripts/mjs/lib/tag-consolidation.mjs+ CLInpm run tags:report→ informe revisable endocs/tag-consolidation.mdque 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 leeSINONIMOSy reescribe solo el campotagsdel frontmatter (dry-run por defecto;-- --applypara escribir; preserva comillas e indentación; deduplica; nunca tocaaliasesni 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:content6/6. Detalle endocs/tag-consolidation.md.
Actualización (2026-10-06, 5.ª ronda): aplicada la consolidación editorial de familias (G1 sigue 🟡). Con
npm run tags:applyse fusionaron 44 tags en 39 posts (43 renombrados + 2 retirados por duplicado) ampliandoSINONIMOS: 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 familiaagent*(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:content6/6. Detalle endocs/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) condim96 yvocabCap3000. El canal está apagado por defecto: el índice solo se descarga al activar el interruptor (o al restaurar la preferencia delocalStorage) 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:content6/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) ysrc/lib/semantic/eval.ts(MRR + recall@3/5/10)— con un test que falla si el MRR cae del suelo (MRR_FLOOR0.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) +dim96 → 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 elvocabCapdejaba 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 conalwaysTerms. Tests del subsistema: +12 (→ 64 ensrc/lib/semantic/, con 3 casos nuevos paraalwaysTerms). Doc actualizada (docs/search.md§ «Evaluación»; doc-buscador § 11.2/12.5/15).verify:content6/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 ensrc/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 —
conceptytitle— además de losaliasescurados (alwaysTerms): una palabra distintiva del título que elvocabCapcortaba dejaba de recuperar las consultas que solo apuntan a ella. Es una palanca del lado índice (reindexa, a diferencia delstemBackoff) 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_FLOOR0.80 → 0.85). También se descartó tras medirlo lo que no compensaba: forzar los términos de ladescription(+61 KB sin ganancia), lostags(regresaban consultas) y aflojar losFIELD_WEIGHTS(bajaba el MRR). Doc actualizada (docs/search.md§ «Evaluación»; doc-buscador § 11.2/12.5/15).
| Métrica | Valor real (2026-10-06, tras Fase 0 + 5.ª ronda) | Objetivo | Estado |
|---|---|---|---|
| Posts escaneados | 165 | — | — |
| Errores de frontmatter | 0 | 0 | ✅ |
| Avisos de frontmatter | 67 | 0 | ⚠️ deuda |
| Avisos de SEO | 50 | 0 | ⚠️ deuda |
| Tests unitarios | 795 / 795 | todo verde | ✅ |
Gate de contenido (verify:content) | 6/6 validadores OK | verde | ✅ |
| CI de GitHub Actions | 3 runs en rojo (mktemp — corregido) | verde | 🔧 fix local, pendiente de push |
| Tags únicos | 470 | vocabulario controlado | 🟡 0 variantes · 12 familias (G1 aplicado) |
| Tags con 1 sola aparición | 351 | bajo | ⚠️ ruido |
Huérfanos (tools:auditar) | 191 | < 15 % | ⚠️ |
Huérfanos (validate:wikilinks) | 176 | < 15 % | ⚠️ |
| Notas sin wikilinks | 2 | 0 | ⚠️ |
| Posts sin imagen real | 4 | 0 | ⚠️ |
Tamaño de .git | 532 MB | estable | ✅ (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
mktempdel 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_Storeconviven con los posts.- En la raíz:
Modelfile(residuo de Ollama),workflow-n8n.json(n8n sin uso),AUDIT.mdylogs/. 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.
| # | Idea | Por qué es P0 | Impacto | Dificultad | Esfuerzo | Cómo |
|---|---|---|---|---|---|---|
| ✅ U1 | Arreglar 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 es | Alto | Baja | 15 min | editar verify-content.sh (ruta + .XXXXXX) + gh run list para confirmar |
| ✅ U2 | Corregir la fecha 2026-09-08T25:26 de psicomotricidad-relacional | Invalid Date en cualquier lector; YAML estricto revienta | Medio | Baja | 5 min | editar el frontmatter a T20:26 (hora asumida) |
| ✅ U3 | Que verify:content avise de fechas no-ISO (hora >23, mes >12) | Es el agujero por el que entró U2; un aviso lo cierra para siempre | Medio-alto | Baja | 1 h | regla en lib/frontmatter-spec.mjs + test |
| ✅ U4 | Reconciliar AGENTS.md con el estado del CI | Documentación que miente es peor que ausente; guía a los agentes al error | Medio | Baja | 20 min | reescribir el párrafo de CI en AGENTS.md |
| ✅ U5 | Sacar 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 publica | Medio | Baja | 30 min | git rm, .gitignore, borrar temporales |
| ✅ U6 | git gc --prune=now + borrar el tmp_pack huérfano | 546 MB y creciendo; el clon y el diff se degradan | Medio | Baja | 20 min | git gc + git count-objects -vH |
| ✅ U7 | Refrescar vault-index.md y el recuento de doc-auditoria.md | Quien los lee trabaja con una foto vieja (161 vs 164, 74 vs 164) | Bajo-medio | Baja | 20 min | npm run tools:index + editar el post |
| U8 | Regenerar la caché de render (npm run content:cache -- --force) tras cerrar el dev | Con un astro dev vivo, el build puede servir HTML viejo | Medio | Baja | 5 min | cerrar 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.
| # | Estado | Idea | Qué gana el sitio | Impacto | Dificultad |
|---|---|---|---|---|---|
| G1 | 🟡 Parcial | Vocabulario 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 ruido | Alto | Media |
| G2 | 🟡 Parcial | Ataque 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+ apariciones | Mejora la densidad de wikilinks y el grafo; content real | Alto | Media |
| G3 | ⬜ Pendiente | Cero avisos en validate:frontmatter -- --strict y validate:seo | Prestigio interno; el SEO deja de ser «casi» | Medio | Media |
| G4 | 🟡 Parcial | PWA 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 aparte | Lectura sin red en móvil; instalable | Medio-alto | Media |
| G5 | ⬜ Pendiente | RSS por categoría y por tag (/category/Humano/feed.xml) | Suscripción granular; más superficie de descubrimiento | Medio | Baja-media |
| G6 | ✅ Hecho | Tiempo 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ón | Bajo-medio | Baja |
| G7 | ✅ Hecho | Backlinks visibles (hecho): bloque «Posts que enlazan a este artículo» (getBacklinksInSection + setBacklinks, con contexto ?from=), cubierto por verify:preview | El vault se explora como red, no como lista | Medio | Media |
| G8 | ⬜ Pendiente | Comentarios con giscus (usa allowComments que ya existe pero hoy no lleva a ningún sitio) | Comunidad sin backend propio | Medio | Baja-media |
| G9 | ⬜ Pendiente | Página de estado /status con conteos vivos (posts, tags, huérfanos, último build) | Transparencia y una home de operación del vault | Bajo-medio | Media |
| G10 | ⬜ Pendiente | Tests E2E de humo con Playwright: home → post → grafo → buscador, sin errores de consola | Corta regresiones visuales/graph antes de producción | Medio-alto | Media |
| G11 | ⬜ Pendiente | Limpieza de aliases redundantes (26 avisos `[[slug | slug]]`) | Higiene y menos ruido del linter | Bajo |
| G12 | ⬜ Pendiente | Higiene de dependencias y npm audit en CI | Seguridad sostenida | Medio | Baja |
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.
| # | Idea | El «wow» | Impacto | Dificultad |
|---|---|---|---|---|
| I1 | «Pregunta al vault» (RAG 100 % estático): pre-generar embeddings en build y responder consultas en el navegador con recuperación local | Un chat que cita tus notas, sin servidor ni cookies | Alto | Alta |
| I2 | Bú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 exacta | Alto | Alta |
| I3 | Podcast automático del vault: usar el TTS ya montado para narrar cada post y servirlo como audio público con feed propio | El blog se escucha; canal nuevo entero | Alto | Alta |
| I4 | Grafo temporal: animar cómo crece la red de notas por fecha de publicación | Cuenta la historia del vault en el tiempo | Medio-alto | Alta |
| I5 | Modo libro: leer una categoría de corrido, con navegación secuencial, índice lateral y progreso | Una categoría deja de ser lista y pasa a ser obra | Medio-alto | Media-alta |
| I6 | Resúmenes y «lo esencial» con Ollama local en build (sin nube): 3 bullets por post y una sinopsis por categoría | Enriquecimiento masivo, gratis y privado | Medio-alto | Media-alta |
| I7 | Ficha comparadora de terapias/enfoques (tabla interactiva por familia, a partir de los tags) | Convierte 100 notas sueltas en un mapa consultable | Medio-alto | Media-alta |
| I8 | Espejo del grafo en 3 archivos: exportar el grafo a GEXF/GraphML/JSON descargable | Investigadores y Obsidian pueden reusarlo | Medio | Media |
| I9 | «Nota aleatoria» / serendipia y «sigue leyendo» por afinidad de grafo | Descubrimiento entretenido, sesiones más largas | Medio | Media |
| I10 | Timeline visual de publicaciones y de temas (por mes y por categoría) | Da contexto y ritmo al catálogo | Medio | Media |
| I11 | Modo foco / lectura zen (oculta cromo, tipografía a medida, guarda posición) | Lectura larga sin fricción | Bajo-medio | Media |
| I12 | Export a ePub del vault o de una categoría | Tu contenido, portable y offline | Medio | Media-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.
| # | Idea | Apuesta | Impacto | Dificultad |
|---|---|---|---|---|
| M1 | MCP server del vault: exponer búsqueda, grafo y notas como herramientas para agentes | El vault se vuelve una fuente para IA, no un sitio | Alto | Alta |
| M2 | Vault como API: /api/posts.json ya existe; publicar endpoints de grafo, tags, búsqueda y relaciones documentadas | Terceros construyen sobre tu contenido | Alto | Media-alta |
| M3 | i18n bilingüe (es/en) con hreflang real (hoy descartado por prematuro) | Doble audiencia y alcance SEO | Alto | Muy alta |
| M4 | Espacio de trabajo interactivo: cliente ligero sobre el mismo grafo para editar/curar el vault desde el navegador | Deja de ser solo lectura | Medio-alto | Muy alta |
| M5 | Newsletter con generación de entregas desde el RSS y las categorías | Canal propio, lista de correo | Medio-alto | Media-alta |
| M6 | «Cite this» / BibTeX por post y DOI-like para el vault | Uso académico | Medio | Media |
| M7 | Storybook / catálogo de componentes vivo en el sitio | Documenta y luce el sistema de diseño | Bajo-medio | Media |
| M8 | Observabilidad propia: dashboard de salud del build (páginas, peso, LCP) versionado como JSON | Operación con datos, no a ojo | Medio | Media-alta |
| M9 | Modo «constelación de una consulta»: dado un tema, ilumina el subgrafo relevante y ordena una ruta de lectura | Convierte la búsqueda en un recorrido guiado | Alto | Alta |
| M10 | Changelog público automático desde los feat/fix de git, con enlaces a los posts afectados | Transparencia y narrativa de producto | Medio | Media |
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.
| Prioridad | Idea | Cuadrante | Estado | Horizonte |
|---|---|---|---|---|
| ⭐ 1 | U1 — arreglar mktemp (CI) | Alto impacto / baja dificultad | ✅ Hecho | Esta semana (Fase 0) |
| ⭐ 2 | U2 — fecha imposible | Alto valor / trivial | ✅ Hecho | Esta semana (Fase 0) |
| ⭐ 3 | U4 — reconciliar AGENTS.md con el CI | Confianza / trivial | ✅ Hecho | Esta semana (Fase 0) |
| ⭐ 4 | U3 — fecha imposible en el gate | Higiene / bajo coste | ✅ Hecho | Esta semana (Fase 0) |
| ⭐ 4 | U5 + U6 + U7 — basura, git gc e índice | Higiene / bajo coste | ✅ Hecho | Esta semana (Fase 0) |
| ⭐ 5 | G1 — vocabulario de tags | Alto / medio | 🟡 Parcial (mecanismo + informe + aplicador; variantes y familias aplicadas, 520→470; quedan 12 familias residuales e islas) | Este mes (Fase 1) |
| ⭐ 6 | G2 — huérfanos prioritarios | Alto / medio | 🟡 Parcial (herramienta; faltan 5-8 notas) | Este mes (Fase 1) |
| ⭐ 7 | G4 — PWA offline | Notable / medio | 🟡 Parcial (instalable; offline no) | Trimestre (Fase 2) |
| ⭐ 8 | G7 + G6 — backlinks + tiempo de lectura | Percepción / medio | ✅ Hechos | Trimestre (Fase 2) |
| ⭐ 9 | I2 — búsqueda semántica | Wow / alto | ✅ Hecho (canal opt-in en /search; src/lib/semantic/ LSA, sin dependencias) | Trimestre (Fase 3) |
| ⭐ 10 | I1 — «pregunta al vault» | Wow / alto | ⬜ Pendiente | Trimestre (Fase 3) |
| ⭐ 11 | I3 — podcast del vault | Wow / alto | ⬜ Pendiente | Trimestre (Fase 3) |
| ⭐ 12 | M1 — MCP del vault | Apuesta / alto | ⬜ Pendiente | Sin 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
