Un grafo dentro de otro: cómo federar subgrafos en un grafo de conocimiento
Sesión con Claude Code sobre el grafo de gobernanza TI del CERN: si un grafo puede referenciar a otro como nodo-portal y previsualizar sus nodos abiertos, si conviene una base de datos junto a git, cómo llevarlo a código con Spec Kit y tests primero, y cómo dejar la composición en un solo sitio con una navegación que permita volver. Termina con la feature publicada en sus repos.
Sí que puedo con base real: he revisado el repo cern-it-governance-graph y el código del toolkit quartz-okf (el clon local está al día con el SHA fijado en okf/quartz-okf.ref). Y sí, esto sería una función de quartz-okf, no del repo del CERN — y la buena noticia es que el motor ya tiene la mitad de la fontanería puesta.
Respuesta corta
Se puede, y encaja sorprendentemente bien con la arquitectura actual. Lo divido en las dos partes que planteas:
1. Nodo especial que referencia otro grafo
Esto es casi gratis, porque el motor no tiene vocabulario propio — dibuja lo que declare el perfil:
- Hoy mismo, solo con config: añades un tipo
graph(osubgraph) enokf.config.mjs, con su color y su radio propio (radius.byTypeya existe precisamente para que "una raíz sea grande porque es la raíz"). Creas una notatype: graphen el corpus padre y las demás notas la enlazan por# Topologycomo cualquier otra. Cero cambios de motor. - El salto "entrar al subgrafo" ya está medio hecho: el explorer ya soporta que un modo cargue otro grafo (
mode.graph,quartz-okf-explorer/src/assets/explorer.html:212-263), con fetch perezoso y caché (CACHE_GRAFOS). Extenderlo para que un nodo declareproperties.graphy al hacer clic se haga swap del grafo en sitio es una extensión pequeña de esa misma maquinaria. - Además el indexador del explorer ya honra un
urlpor nodo si viene en el JSON (url: n.url || ("/" + id)), así que un nodo puede apuntar al explorer de otro sitio publicado sin tocar nada del cliente.
2. Nodos "open" del subgrafo previsualizados en la jerarquía superior
Esto sí es una feature nueva: federación en build time. Pero el esquema okf-graph/v1 ya trae los ganchos que necesita:
- El bundle de cada grafo es un artefacto público y estático (
okf-graph.json), y ya lleva un campositecon su URL canónica (core/lib/graph.js:126) — justo lo que hace falta para componer URLs absolutas hacia el sitio hijo. - La visibilidad se declara igual que ya declaras
entornoostatusen el grafo del CERN: unpropertyGroupconvisibility: openen el frontmatter del corpus hijo, proyectado aproperties.
El paso nuevo sería un bloque federation en okf.config.mjs del padre, tipo:
export const federation = {
subgraphs: [{
node: "it-governance", // la nota type: graph del corpus padre
graph: "https://cern.zetesis.xyz/static/okf-graph.json",
preview: { property: "visibility", value: "open" },
edge: "Contains", // portal → nodos abiertos
}],
}
En build: descargar el JSON hijo, filtrar los nodos open, prefijar los slugs (it-governance:sso-keycloak — los slugs son relativos al corpus y dos corpus pueden colisionar), sintetizar el url absoluto con el site del hijo, y colgarlos del nodo portal con la arista elegida. Al hacerse en build no hay problema de CORS, y el explorer los pinta y enlaza sin cambios.
Esfuerzo y riesgos
El grueso es un módulo de federación en core/lib (~100–150 líneas) más el render especial del nodo-grafo en el explorer (doble anillo o glifo). Los dos puntos delicados: colisión de slugs (se resuelve con el prefijo) y el acoplamiento de versiones — el padre se hornea con la foto del hijo en el momento del build, así que un push al hijo no refresca el preview del padre hasta que el padre rebuildee (un cron o un webhook de Pages lo arregla).
Decías que eran 2 preguntas — si la segunda era otra distinta de estas dos partes, dispara.
Buena pregunta, y tengo contexto histórico relevante: ya hiciste un spike serio con SurrealDB en Graphmarks (retirado). Mi valoración: sí es viable, con una condición arquitectónica innegociable — y los motivos por los que Surreal cayó en Graphmarks casi no aplican aquí, aunque uno sí.
El patrón: git como verdad, la BBDD como proyección derivada
Funciona limpio si la BBDD es un índice materializado que siempre se puede reconstruir desde git, nunca un segundo escritor. Es exactamente el patrón que ya usas en Zetesis Search (Typesense indexa, Payload/git es la verdad). Aplicado a quartz-okf:
- El contrato de intercambio sigue siendo el bundle (
okf-graph.json, que ya llevasource_headysite). Un pasookf ingestlee bundles y hace upsert idempotente clavado a esesource_head— la BBDD nunca parsea markdown, solo consume bundles. - La vía estática (Pages) sigue funcionando entera sin la BBDD. Lo nuevo es aditivo y degradable.
- Reconstrucción total posible en cualquier momento: wipe + re-ingesta de los bundles registrados. Si eso deja de ser cierto, ya tienes dos fuentes de verdad.
La línea roja: la "cierta información" que quieras mover define todo. Si es derivada (el grafo, índices, consultas cruzadas), limpio. Si es autorada (notas, aristas, el flag visibility: open de la conversación anterior), guardarla solo en la BBDD rompe la premisa — git dejaría de ser verdad del grafo. Si necesitas edición en vivo (una UI de curación, por ejemplo), el camino de escritura tiene que acabar en un commit (un bot que abre PR); la BBDD solo cachea el estado pendiente.
Qué te compra, sobre todo para la federación
Aquí es donde brilla: la federación de subgrafos que diseñamos ayer deja de ser un merge en build time. Ingestas N bundles en un store y el "preview de nodos open en el padre" pasa a ser una query — y desaparece el acoplamiento de versiones que señalé como riesgo: un push al grafo hijo dispara su ingest (webhook) y el padre lo ve al momento, sin rebuild. Consultas cruzadas entre grafos ("todo lo que en cualquier grafo cumple CIS v8") salen gratis.
SurrealDB en concreto
Lo que mató el spike de Graphmarks fue el wasm embebido en navegador: la 3.x entera rota en browser (indxdb sin publicar, pánico 'time not implemented', su CI de wasm comentado). Nada de eso aplica a un Surreal servidor en devcontainer/K8s. Y el modelo encaja de verdad: tu topología tipada mapea 1:1 a RELATE y las traversals (->governs->service) son idiomáticas, no CTEs recursivas.
Lo que sí viaja del spike: la salud del upstream (equipo pequeño, la 3.x salió con roturas graves que tú mismo reportaste). Y operativamente sería un stateful nuevo [en el clúster] con historia de backup propia — CNPG no te vale (es Postgres-only), sería export de Surreal o volumen RocksDB con K8up.
La alternativa conservadora es Postgres/CNPG (ya operado, ya respaldado) con las traversals a pico y pala — pero conociendo tu criterio, para un índice reconstruible desde git el riesgo de Surreal es bajo por diseño: si la BBDD se rompe o el upstream decepciona, la tiras y re-ingestas en otra cosa. Es el escenario ideal para probar un motor joven, porque no custodia nada irrecuperable.
Devcontainer
Sin fricción: imagen oficial surrealdb/surrealdb (no Bitnami, cumple la regla) como servicio del compose del devcontainer, y el okf ingest corre dentro como el resto del tooling. Para prod, chart propio o manifest simple [en el repo de GitOps] cuando llegue el momento.
Resumen: sí, con git como verdad y la BBDD como proyección re-ingestable desde los bundles. Surreal es defendible justo porque aquí es desechable; la condición es no dejar que jamás guarde nada que no pueda regenerarse de git o volver a git como commit.
Hecho. En resumen:
- El grafo de PAFE es
PAFE-Portal/wiki/— otro consumidor dequartz-okf(perfil "Wiki PAFE": book, author, concept, protocol, instrument, topic, claim, guide, report). Al vivir la feature en el toolkit, adoptarla ahí es bumpear suokf/quartz-okf.refy declarar el bloque de federación en suokf.config.mjs— nada que implementar por duplicado. - El caso de uso encaja bien: libros o temas como subgrafos con nodo-portal en el grafo general de la wiki, exponiendo en open sus concepts y claims principales.
Tengo el terreno mapeado: quartz-okf ya tiene suite node --test (core/test con graph, topology, exporter, rules...), no tiene CI, y Spec Kit ya está en casa — specify instalado en ~/.local/bin y .specify/ con constitution.md en [otros tres repos]. Así que no es adoptar una herramienta nueva, es llevar la que ya usas al toolkit. Mi propuesta:
Sí a Spec Kit, con quartz-okf como piloto de la metodología OKF
La feature vive en el toolkit, así que el .specify/ va en quartz-okf, no en el CERN ni en PAFE. Los consumidores solo bumpean el ref. La constitución se siembra con las reglas de la casa que ya aplicas a mano: tests verticales antes de implementar, functional core / imperative shell (decisiones puras en core/lib, I/O en el exporter y el emitter), cero comentarios salvo un WHY, conventional commits con scope por paquete. Esa constitución es la parte que luego "se documenta como metodología".
Plan por fases
Fase 0 — Metodología (medio día): specify init en quartz-okf, constitución, y /speckit.specify con el diseño que ya tenemos (nodo-portal + federación open + BBDD como fase opcional). De ahí salen /speckit.plan y /speckit.tasks. Documentación: un docs/METHODOLOGY.md público en el toolkit (registro seco, es OSS) que explique el flujo spec → plan → tasks → tests verticales → implementación, y una línea en developer.md (el CLAUDE.md de la casa) si lo elevamos a estándar para todos los grafos OKF.
Fase 1 — Nodo-portal (config-only, sin tocar motor): tipo graph en el okf.config.mjs del CERN con color y radio propio. Sirve para validar la UX antes de escribir código y demuestra que el perfil ya lo soporta.
Fase 2 — Federación en core/lib (el grueso): módulo federation.js puro (dado un grafo padre + bundles hijos + reglas → grafo fusionado con slugs prefijados y URLs absolutas) con sus tests en core/test escritos antes; el fetch de bundles va en la cáscara del exporter. Luego el render del nodo-grafo y el "entrar al subgrafo" en el explorer, reutilizando CACHE_GRAFOS.
Fase 3 — Adopción: bump del ref en el CERN (okf/build-site.sh local, verificando la línea knowledge graph: N notes, M edges), después en la wiki de PAFE dentro de su devcontainer.
Fase 4 — opcional: okf ingest a SurrealDB servidor en devcontainer, cuando la federación estática se quede corta.
Una cosa que añadiría en Fase 0: un workflow de CI mínimo que corra npm test en quartz-okf — hoy no hay ninguno, y con Spec Kit generando tasks a partir de tests, un repo sin CI pierde la mitad del valor.
Si te cuadra, arranco por la Fase 0: specify init, constitución y el spec de la feature, para que lo revises antes de que se genere ningún plan.
El plan está en el repositorio, en la rama local 001-subgraph-federation de quartz-okf, escrito con Spec Kit y sin commitear nada — lo revisas y decides.
Qué hay ahora en quartz-okf
Metodología (Fase 0, hecha):
specify initejecutado:.specify/(plantillas, scripts) y los skills/speckit-*en.claude/skills/..specify/memory/constitution.mdv1.0.0 — siete principios que ya aplicabas a mano: git como verdad y bundle como contrato, functional core / effectful shell, tests primero verticales (obligatorios; anula el "opcional" de la plantilla), el motor no lleva vocabulario, sin fallos silenciosos, comentarios solo WHY, esquema aditivo y pinning por SHA.docs/METHODOLOGY.md(público, seco),CLAUDE.mddel repo (con las trampas descubiertas) y un enlace en el README.
La feature specs/001-subgraph-federation/:
spec.md— 3 user stories (federar en build P1, entrar/volver en el explorer P2, drift y fallos duros P3), 13 requisitos, criterios medibles.research.md— lo que ya existe en el motor, las decisiones D1–D9 con alternativas rechazadas, impacto en consumidores.data-model.md— bloquefederationdeokf.config.mjs, campos nuevos deokf-graph/v1(baseUrl,subgraph,federated,url), tabla de códigos de error, firmas del módulo puro y del emitter.plan.md— Constitution Check principio a principio, estructura por fichero real, orden de implementación razonado y riesgos.tasks.md— 32 tareas test-first en 6 fases: CI (el repo no tiene) → caracterizar y extraerderiveInverseEdges+baseUrl→ módulocore/lib/federation.jsy shell del emitter → explorer → drift → adopción en CERN y PAFE.
Dos cosas que descubrí leyendo el código y cambian el diseño
siteen el bundle es un título, no una URL (el emitter metepageTitle, el exporterbranding.site). Te dije lo contrario en la conversación anterior; el plan introducebaseUrldesdeconfiguration.baseUrlde Quartz.- El
distdel explorer no se commitea — lo compila cada consumidor en su build (prepare: tsup). Se editasrc/, y un error de TypeScript ensrc/index.tsrompe a todos los consumidores a la vez (por eso el plan dejaindex.tscomo passthrough y toda la lógica enexplorer.html).
Lo único que necesito de ti
Una decisión, marcada como [NEEDS CLARIFICATION] en el spec: cuál es el primer corpus padre. Tu ejemplo pide un cern-graph paraguas nuevo con un portal hacia cern-it-governance-graph; la alternativa es partir la wiki de PAFE en subgrafos. Con eso resuelto, el siguiente paso es /speckit-implement sobre tasks.md (o /speckit-clarify si quieres pasarle una vuelta antes). La BBDD queda como 002-bundle-ingest, fuera de esta feature a propósito.
Decisión registrada; el spec ya no tiene marcadores abiertos.
Qué cambió:
spec.md: nueva secciónClarifications › Session 2026-08-30con la pregunta y tu respuesta, y la assumption reescrita: primer padre = repo nuevocern-graph, primer hijo =cern-it-governance-graph, la wiki de PAFE llega después sin federación.tasks.md(Fase 6, orden invertido a propósito): T029 el hijo primero —cern-it-governance-graphbumpea el ref (así publicabaseUrl: https://cern.zetesis.xyz), añade el propertyGroupvisibilityy marca como open los hubs y los servicios que un lector del CERN general querría ver (SSO, WLCG IAM, OC5, el departamento IT); T030 el padre —Zetesis-Labs/cern-graph, público y MIT, creado desde el esqueleto del hijo (okf/, D3 enquartz/static,quartz.config.yaml, workflow de deploy), con un corpus paraguas pequeño (CERN, Council, sectores, departamento IT) y la nota-portaltype: graphapuntando al bundle del hijo. He dejado anotado que la exposición pública sigue la regla de la casa […], no el proxy naranja.research.md: tabla de consumidores con el rol de cada uno (hijo / padre nuevo / después).
Siguiente paso cuando quieras: /speckit-implement en quartz-okf (rama 001-subgraph-federation, todo sin commitear todavía), empezando por T001 (CI) y la Fase 2 de caracterización.
Implementación hecha y verificada end-to-end. Todo está en local, sin push — el siguiente paso es tuyo.
Qué se ha construido (toolkit quartz-okf, rama 001-subgraph-federation, 8 commits por scope)
- Core (
core/lib/federation.js, puro):validateFederationConfig,federateGraph,absolutiseChildGraph,subgraphId;deriveInverseEdgesextraído debuildGraphtras un test de caracterización que lo pinó byte a byte. - Emitter (
plugins/quartz-okf/dist/index.js): publicabaseUrlysource_head(elbuild-site.shexportaOKF_SOURCE_HEAD, porque Quartz compila desde una copia fuera del repo), acepta el bloquefederation, descarga los hijos confetchBundleinyectable, falla en estricto con el id del subgrafo en el mensaje, y escribestatic/okf-subgraphs/<id>.json. - Explorer: doble anillo y etiqueta fija en portales, anillo discontinuo y badge en federados, botón "Explorar subgrafo" en el panel de lectura, pila con "← Volver" que restaura el padre con el portal seleccionado, y
?graph=<id>. - 57 tests en verde, sin red. Hallazgo útil: el plugin
quartz-okfimporta../../lib/index.js, así que solo funciona en el layout que monta el harness; el test lo monta igual (test/assemble.js), que es lo que ejecutan los consumidores. - CI nuevo (
npm testen push/PR), READMEs de ambos plugins actualizados,tasks.mdmarcado.
Verificación real (no solo tests)
Construí el hijo con el toolkit local y lo serví en :8765; creé el padre cern-graph (8 notas: CERN, Council, DG, SPC, sector RCS, IT department, portal topics/it-governance, fuente) y lo compilé contra el hijo servido: federation: it-governance ← 274 notes, 18 previewed (011e3ea) → 26 nodos, 72 aristas, 0 sin resolver. En Chrome recorrí el spec completo: portal con doble anillo rodeado de 18 federados con anillo discontinuo, panel de lectura con "Explorar subgrafo", salto al hijo (274 nodos, modos ocultos, ruta "CERN › CERN IT Governance"), vuelta con el portal seleccionado, y el deep link ?graph=it-governance. Sin errores de consola.
Un aviso honesto: los clics sintéticos del navegador automatizado sobre nodos del canvas se tragan como arrastre y dejan la simulación caliente; con doble clic o el buscador va. Es comportamiento previo del explorer, no de este cambio.
Estado por repositorio
| Repo | Estado |
|---|---|
| quartz-okf | rama 001-subgraph-federation, 8 commits, sin push |
| cern-it-governance-graph | rama feat/federation-open-notes (1 commit, sin push): propertyGroup visibility, 18 notas open, OKF_SOURCE_HEAD; ref restaurado a 9249934 |
| cern-graph | repo git solo local (1 commit), no existe en GitHub; okf/quartz-okf.ref = local-dev (placeholder); dominio provisional cern-graph.zetesis.xyz |
Lo que queda y necesita tu OK
- Push de
001-subgraph-federationy PR enquartz-okf(T028). - Tras el merge: bump del ref en el hijo y push de su rama; crear
Zetesis-Labs/cern-graphdesde el local con el ref real y la URL publicada del hijo, y exponerlo por la regla de la casa […]. Falta que decidas el dominio del padre. - PAFE wiki: solo bump del ref, en su devcontainer (T031).
Si me dices "push y PR", arranco por el punto 1.
Entendido, dos frentes: navegación más intuitiva y, sobre todo, que la composición sea un solo sitio — ahora mismo el padre republica el grafo del hijo pero las páginas de las notas federadas siguen viviendo en el sitio del hijo (y el build necesitaba al hijo servido). Eso hay que rediseñarlo: el padre debe montar el bundle del hijo (notas + grafo) dentro de su propio sitio, obtenido del repo del hijo a un commit fijado, igual que se fija el toolkit. Antes de tocar nada leo las piezas que faltan (exportador, git, frontmatter, harness y las constantes del explorer).
Hecho: la composición ya es un solo sitio y la navegación está rehecha. Todo verificado en local y commiteado (sin push).
Qué cambió
Composición sin segundo servicio. El padre ya no lee nada del sitio del hijo. Un paso nuevo, okf-federate, corre antes de Quartz: obtiene el corpus hijo de su repositorio git a un commit fijado (repo + ref, igual que se fija el toolkit), lo exporta con su propio perfil, rechaza hijos que no pasan su validación, monta sus 274 notas como páginas del padre bajo /it-governance/… y deja el grafo y un manifiesto como artefactos de build. El emitter compone desde ahí. Resultado: apagué el servidor del hijo y el padre compila y navega igual — las notas federadas abren /it-governance/identity/cern-sso en el propio sitio.
Navegación (lo que no era intuitivo y ahora sí):
- Doble clic en el portal entra en su grafo; la misma acción aparece en la barra de relaciones al seleccionarlo y en el panel de lectura. El tooltip dice cómo entrar.
- Dentro del subgrafo el explorer es el del hijo: sus colores, sus etiquetas y sus 12 modos (Identity & Access, The stack, …); al volver se restaura el del padre con el modo que tenías.
- La cámara se reinicia y encuadra el grafo hijo en cuanto toma forma, sin esperar a que se asiente.
- El botón atrás del navegador funciona (
?graph=it-governancepasa por el historial) y devuelve al padre con el portal seleccionado. - En el padre, los nodos federados ya se leen con el vocabulario del hijo (pastillas "Service / System", "Policy / Circular" con sus colores) en vez de
service/policya pelo.
Metodología
Todo pasó por el spec: sesión de clarificación (b) en spec.md, decisiones D10–D13 en research.md, data-model.md §6 con las formas vigentes, Fase 7 en tasks.md. Tests primero: 68 en verde, incluyendo un test de integración que crea un repo hijo real y otro que lo clona por file:// a un commit fijado.
Dos cosas que conviene que sepas
- La pestaña del Chrome automatizado estaba en una ventana oculta y ahí el navegador no despacha animaciones ni la simulación; de paso salió una mejora real: si abres el explorer en una pestaña en segundo plano, el encuadre ahora se aplica de golpe en vez de perderse.
- El padre fija el commit
544ef3edel hijo, que solo existe en la rama localfeat/federation-open-notes. Hasta que el hijo se pushee, el build del padre solo funciona conOKF_IT_REPO=../cern-it-governance-graph.
Estado
| Repo | Rama | Commits nuevos |
|---|---|---|
| quartz-okf | 001-subgraph-federation | 12 (core, quartz-okf, explorer, ci, docs) |
| cern-it-governance-graph | feat/federation-open-notes | 2 |
| cern-graph (solo local) | main | 3 |
Siguiente paso cuando quieras: push del toolkit y PR; después push del hijo y crear Zetesis-Labs/cern-graph.
Entendido: el rastro de grafos tiene que estar en la cabecera, siempre visible, y volver debe ser un clic. Lo hago así: la cabecera del panel pasa a ser una miga de pan de grafos (CERN graph › CERN IT Governance & Identity) donde cada nivel anterior es un enlace que te devuelve ahí, más un botón ‹ de "un nivel arriba"; y quito la barra "← Volver" que estaba escondida dentro del cuerpo del panel.
Hecho: la miga de grafos ya está encima del lienzo, antes de la barra de relaciones, y volver es un clic.
Qué verás ahora al entrar en un subgrafo
Una franja superior:
‹ CERN graph › CERN IT Governance & Identity Volver: ‹, el nivel anterior o el botón atrás del navegador
CERN graph(y cualquier nivel anterior) es un enlace: te devuelve a ese grafo de un salto, aunque hayas entrado varios niveles — no hay que deshacerlos uno a uno.‹sube un nivel.- El botón atrás del navegador hace lo mismo (la entrada pasa por el historial).
- Al volver, el padre aparece con el portal seleccionado y el modo que tenías; la miga desaparece en el grafo raíz porque ahí no hay camino que mostrar.
- El nivel actual va en negrita; la barra de relaciones del nodo seleccionado queda justo debajo.
La barra "← Volver" que estaba escondida dentro del panel ha desaparecido: la miga superior la sustituye.
Verificado en el navegador: entrar desde el portal → miga visible con los dos niveles → clic en «CERN graph» → vuelta al padre (26 nodos, portal seleccionado, modos del padre restaurados, miga oculta).
En el repo: recogido como FR-016 en el spec, tarea T041 cerrada, 2 commits más en quartz-okf (rama 001-subgraph-federation, ahora 14 commits sin push); 68 tests en verde.
Subo todo. Orden: primero el toolkit (rama + PR), porque los dos consumidores tienen que fijar su SHA; luego el hijo (rama + PR) y el padre (repo nuevo en GitHub). Antes, una protección: el paso de montaje en los build-site.sh debe avisar en vez de romper si el toolkit fijado aún no trae okf-federate.
Subido todo. Resumen de lo publicado:
Enlaces
| Qué | Dónde |
|---|---|
| Toolkit — PR quartz-okf#3 (rama 001-subgraph-federation, 14 commits) | https://github.com/Zetesis-Labs/quartz-okf/pull/3 — checks en verde: test, Devin Review, GitGuardian |
| Hijo — PR cern-it-governance-graph#4 (feat/federation-open-notes) | https://github.com/Zetesis-Labs/cern-it-governance-graph/pull/4 |
| Padre — repo nuevo Zetesis-Labs/cern-graph (público) | https://github.com/Zetesis-Labs/cern-graph |
Lo que dejé fijado
- Los dos consumidores apuntan al toolkit por SHA de la rama del PR (
98247dd); el padre monta al hijo en el commit5cbcd01de su rama. Como el modelo es fijar por SHA, todo es reproducible ya: verifiqué un build del padre usando solo GitHub (tarball del toolkit por SHA + clone del hijo al commit), sin nada local:mounted it-governance ← 274 notes, 18 previsualizadas, 26 nodos / 72 aristas. - El paso de montaje en los
build-site.shavisa en vez de romper si el toolkit fijado no traeokf-federate, para que ningún consumidor quede roto por orden de merge. - Sale un aviso
federation/ref-behindmientras el pin del hijo esté en una rama y no enmain: es esperado y desaparece al mergear.
Orden para cerrar la cadena (lo decides tú)
- Mergear #3 (toolkit).
- Re-fijar los refs del hijo y del padre al SHA de
main(si el merge es squash, el SHA de la rama deja de estar garantizado en el tarball) y mergear #4. - En
cern-graph: secretosCLOUDFLARE_API_TOKEN/CLOUDFLARE_ACCOUNT_ID[…], decidir el dominio (pusecern-graph.zetesis.xyzcomo provisional) y exponerlo por la regla de la casa […]. - PAFE wiki: solo bump del ref.
El primer run de deploy de cern-graph está en marcha (paso "Build con quartz-okf"); lo estoy vigilando en segundo plano y te digo hasta dónde llega en cuanto termine — lo previsible es que compile y falle en el paso de Cloudflare por falta de secretos.