make templates ya no descarga un tarball aparte: extrae las plantillas
del binario ya descargado con "clusterlog templates extract" (ver
ADR-0006 del motor). fetch-engine.sh se simplifica a un solo modo
(binario); ya no hay asset de plantillas que descargar ni checksum
aparte que verificar para eso.
Probado de extremo a extremo contra el release v0.2.0 real: fetch del
binario, extracción de plantillas, sync, validate --require-zola y
zola build sobre el contenido real de MCPS, todo limpio.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
El intento anterior (correr cada celda por nombre, sin --all) también
aborta en el runner real ("Parsing files..." → "could not execute
command: aborted") — el problema no era --all. --dry-run sí funciona en
ese runner (nunca ejecuta nada él mismo), pero escribe el script
resuelto a stderr, no a stdout: el primer intento de "| bash" no
ejecutaba nada porque el pipe sólo captura stdout, y lo que se veía en
pantalla era stderr yendo directo a la terminal. Corregido con "2>&1
>/dev/null | bash". Probado localmente de extremo a extremo: las 4
celdas ejecutan de verdad (incluye verify-head devolviendo valid:true
real, no sólo el texto del comando).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
El log real del runner confirmó que el crash ("could not execute
command: aborted") ocurre justo al entrar a la UI interactiva
multi-tarea de "runme run --all" (mensajes "Initializing..."/"Parsing
files..."), no en una celda en particular — --log/--log-file ni
siquiera alcanzan a escribir nada. No se pudo reproducir en local pese
a varios intentos (stdin/stdout no interactivos, CI=true, TERM=dumb).
scripts/runme-ci.sh corre cada celda ci-safe por su nombre exacto, sin
--all: --dry-run ya había confirmado que esa forma no dispara la UI
multi-tarea. Makefile y RUNBOOK.md actualizados para reflejarlo.
Probado localmente de extremo a extremo, las 4 celdas en verde.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
El job runme fallaba en el runner real con "could not execute command:
aborted" justo al iniciar "runme run", algo que no se pudo reproducir
localmente (incluso forzando stdin/stdout no interactivos) — probable
diferencia de cómo act_runner en modo nativo/host expone el proceso
frente a una sesión interactiva. Se agrega CI=true y TERM=dumb al job
(convención estándar que muchas TUIs respetan) y --log/--log-file a
runme-ci para que, si vuelve a fallar, el paso de diagnóstico imprima
el log real en vez de repetir el ciclo de adivinar a ciegas.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
source_sha256 en data/generated/site_state.json incluye la ruta
absoluta del checkout (sourceDigest hashea path+contenido), así que
difiere entre el checkout donde se commiteó y el checkout de un job de
CI en otra ruta, aunque el contenido sea idéntico. El job
validate-and-build ya corría sync antes de validate en el mismo
checkout; el job runme no, y por eso runme-check fallaba con
generated_state_stale. Reproducido localmente clonando a otra ruta
antes de aplicar el fix, y confirmado limpio después.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Los comandos de ejemplo "podman inspect ... --format '{{range
.Config.Env}}{{println .}}{{end}}'" son sintaxis de Go templates, no de
Tera, pero Zola igual intenta interpretarlos como expresiones Tera al
renderizar la página — zola check fallaba con "Found `}}` but expected
identifier". Encontrado por la propia CI al validar --require-zola tras
la conversión a instancia (antes nunca se había corrido zola check
sobre este contenido en CI con la ruta real). Envueltos en {% raw %}.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Retira el código del motor (cmd/, internal/, go.mod, templates/,
examples/, scripts de desarrollo Go) — vive ahora en
https://github.com/fenandosr/clusterlog (release v0.1.0). Este
repositorio conserva únicamente content/, data/, config/ y zola.toml:
los datos reales de esta instancia (MCPS).
Se agrega .clusterlog-version (fija v0.1.0) y scripts/fetch-engine.sh,
que descarga el binario y las plantillas del motor por versión fijada
verificando su checksum contra el release. Makefile y
.gitea/workflows/ci.yml se adaptan para descargar en vez de compilar.
RUNBOOK.md y runbooks/ se recortan a las celdas que sí operan sobre
datos reales de esta instancia (sync-check, validate-local, site-build,
review-mine, verify-head); el ciclo de desarrollo del motor mismo
(build/test/vet) vive en su propio repositorio.
Se preserva toda la historia existente: éste es un commit nuevo, no una
reescritura. Ver docs/adr/0005-motor-instancia.md en el repositorio del
motor para el contexto completo de la separación.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sin la portada, zola build fallaba en toda instancia recién creada:
get_url no podía resolver @/_index.md desde section.html. Encontrado
al probar bootstrap-instance de extremo a extremo (zola build real,
no sólo validate --skip-zola) para sembrar el repo motor.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Primer paso hacia separar el motor (herramienta genérica) de cada
instancia (contenido de un deployment): Version deja de ser const para
poder inyectarse con -ldflags en `make build` (git describe, sin tags
aún), y el comando nuevo bootstrap-instance genera el esqueleto mínimo
de una instancia (zola.toml, content/<sección>/_index.md, admins.json
vacío, .clusterlog-version) reusando saveAdmins() en vez de duplicar su
formato. Documentado en CLI.md; el empaquetado de templates/tema y el
CI de instancia quedan para cuando el motor publique releases.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Agrega RUNBOOK.md y runbooks/ (fuera de content/, para no interferir con
la publicación de Zola), con reglas de nombres/etiquetas/aislamiento de
celdas mutantes verificadas por clusterlog validate. Instalación pinneada
a v3.17.4 con checksum verificado (scripts/runme-install.sh), un job de
CI separado (.gitea/workflows/ci.yml) que sólo corre celdas ci-safe, y la
decisión documentada en docs/adr/0004-runme-sidecar.md y docs/RUNME.md.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Documenta el flujo cuando ya existe un owner: quién debe correr el comando, cómo pasar la llave pública del nuevo administrador y cómo verificar el alta.
Fija cómo debe conectarse cualquier IA lanzada desde este repositorio: usar el alias local (ssh mcps), nunca construir la conexión con -i y una ruta de llave, y separar el inventario compartido de hosts (sin secretos) de la identidad personal en ~/.ssh/config de cada administrador.
docs/ADR.md documenta alcance, campos, secciones y un ejemplo para docs/adr/. Deja explícito que son decisiones sobre clusterlog (la herramienta), no sobre el clúster administrado, y que no tienen equivalente en la UI ni en la CLI.
El if: a nivel de step no está corriendo de forma confiable en este
runner (act_runner v0.2.13, modo host): el paso 'Publicar en producción'
nunca se ejecutó en 5 corridas distintas, con o sin condición, con o sin
&&, sin dejar ningún rastro en el log. Se fusiona build + condicional +
rsync en un solo step con el if en bash, que sí es determinista.
Confirmado con dos runs reales: sin importar cuál sea, el último step
de la lista nunca se ejecuta ni deja rastro en el log (ni siquiera como
omitido) en este runner (act_runner v0.2.13, modo host). Se agrega un
paso trivial después de 'Publicar en producción' para que éste deje de
ser el último y sí se ejecute.
El paso de rsync a producción no se ejecutó en el primer run exitoso ni
dejó rastro de 'omitido' en el log, a diferencia del paso condicional de
firmas en PR. Se envuelve la condición en ${{ }} (forma explícita) y se
agrega un paso previo que imprime github.ref/event_name/ref_name reales
en este runner, para confirmar si el valor difiere de lo esperado.
El sandbox de scripts/e2e-local.sh resetea data/admins.json a solo los
administradores ficticios de la prueba, pero no limpiaba content/manuales
ni content/documentacion. En cuanto existió una página real ahí con un
autor real (no ficticio), la validación interna del script fallaba con
'autor no registrado'. Ahora se limpian igual que memorias/tareas/proyectos.
install-action falla en el runner de Gitea Actions en modo host: reporta
runner.os='linux' (minúsculas) y la acción sólo reconoce 'Linux'. Se
reemplaza por una descarga directa del tarball de la release fijada.
.github/workflows/ci.yml nunca corrió: Gitea Actions busca los workflows
en .gitea/workflows/, no en .github/workflows/, y además no había ningún
runner registrado en la instancia (0 workflow_runs históricos).
Se registró un runner en modo host en mcps-hpc-01 (mismo binario
act_runner, sin Docker-in-Docker) y se agregó un paso de publicación al
final del pipeline: en push a main, hace rsync de public/ a
/opt/clusterlog/public/, que sirve un contenedor nginx en mcps-net
detrás de Caddy en clusterlog.mcps-epcm.org.
También corrige base_url en zola.toml, que seguía apuntando al dominio
de ejemplo.
Auditoría: ninguna plantilla local usa una sola clase de Bootstrap
(.btn/.navbar/.row/.span*/.modal, cero coincidencias); ops.css ya
redefine todo lo que sí se usa (.container, .badge, code/pre). El
site.scss del tema (que importaba bootstrap.css + bootstrap-responsive.css
+ style.css, ~103 KB) se reemplaza en bootstrap-theme.sh por un reset
mínimo propio que cubre solo lo que ops.css necesita.
site.css pasa de 103.5 KB a 605 B; public/ de 672 KB a 572 KB. Sin
cambio visual (verificado página por página con Playwright) ni de
tiempo de build.
zola.386 trae JS de bootstrap/jquery, íconos y las fuentes DOS, pero
ninguna plantilla local los referencia; se publicaban igual porque
static/ se copia tal cual. Reubica los 3 CSS que compile_sass sí
necesita a vendor/ (fuera de static/) y descarta el resto.
public/ pasa de 1268 KB / 110 archivos a 672 KB / 58 archivos, sin
cambio visual ni de tiempo de build (~0.3s).
Reemplaza la paleta oscura teal/marino por el azul DOS + gris con
bordes biselados del tema original, cambia el resaltado de código a
vitesse-black para que combine con los chips <code> en negro, y
sustituye la fuente pixelada Fixedsys por Share Tech Mono
(autohospedada) para mantener el aire retro sin sacrificar
legibilidad. También cambia el prompt decorativo del header de
"C:\CLUSTER>" a "root@cluster:~#".