feat(runme): integrar Runme como sidecar de documentación ejecutable
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>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# Runbooks ejecutables
|
||||
|
||||
Esta carpeta vive **fuera** de `content/`, así que Zola nunca la construye ni
|
||||
la publica (confirmado en `zola.toml`: no hay `content_dir` alterno). Es la
|
||||
razón por la que aquí sí se pueden usar atributos de celda de Runme sin
|
||||
arriesgar el front matter TOML ni el resaltado de sintaxis que sí usa
|
||||
`content/manuales/`.
|
||||
|
||||
## Cómo abrir un runbook
|
||||
|
||||
- **Como notebook (Runme, VS Code):** instale la extensión recomendada en
|
||||
[`.vscode/extensions.json`](../.vscode/extensions.json) (`stateful.runme`) y
|
||||
abra el archivo `.md` normalmente; VS Code lo mostrará como notebook.
|
||||
- **Como Markdown normal:** clic derecho sobre la pestaña → "Reopen Editor
|
||||
With..." → "Text Editor". Ningún runbook depende de estar en modo notebook
|
||||
para ser legible o copiable.
|
||||
- **Por CLI:** `runme run --filename runbooks/<archivo>.md <nombre-de-celda>`.
|
||||
- **Sin Runme instalado:** copie el bloque de comando y ejecútelo en su
|
||||
terminal; ninguna celda usa sintaxis que no sea shell/`make`/`clusterlog`
|
||||
normal.
|
||||
|
||||
## Convención de nombres
|
||||
|
||||
`kebab-case`, prefijo de proyecto, único en **todo** el repositorio (no sólo
|
||||
dentro de un archivo): `clusterlog-build`, `clusterlog-validate-local`,
|
||||
`clusterlog-review-mine`. `clusterlog validate` (ver
|
||||
`internal/clusterlog/runbooks.go`) falla si dos celdas repiten un nombre.
|
||||
|
||||
## Taxonomía de etiquetas
|
||||
|
||||
Toda celda debe declarar al menos una etiqueta de cada categoría:
|
||||
|
||||
| Categoría | Valores | Obligatoria |
|
||||
|---|---|---|
|
||||
| Audiencia | `role-developer`, `role-operator`, `role-reviewer`, `role-owner` | sí |
|
||||
| Entorno | `env-local`, `env-ci`, `env-staging`, `env-production` | sí |
|
||||
| Riesgo | `risk-read-only`, `risk-mutating`, `risk-destructive` | sí |
|
||||
| Ejecución automatizada | `ci-safe`, `manual-only` | no (pero mutuamente excluyente con `risk-mutating`/`risk-destructive`) |
|
||||
|
||||
Una celda `risk-mutating` o `risk-destructive` **debe** llevar
|
||||
`manual-only`, `"interactive":"true"` y `"excludeFromRunAll":true`, y
|
||||
**no puede** llevar `ci-safe` al mismo tiempo. `clusterlog validate` hace
|
||||
cumplir esto — no es sólo una convención de estilo.
|
||||
|
||||
## Qué no va en una celda
|
||||
|
||||
Ver la sección "Runme no contiene lógica de negocio" del ADR
|
||||
[`docs/adr/0004-runme-sidecar.md`](../docs/adr/0004-runme-sidecar.md). En
|
||||
resumen: una celda invoca `make`, `./bin/clusterlog` o un script existente; no
|
||||
reimplementa validación, autorización, rollback ni gestión de secretos.
|
||||
@@ -0,0 +1,99 @@
|
||||
# <Título del runbook>
|
||||
|
||||
> Copie este archivo, renómbrelo en `kebab-case` y borre los comentarios
|
||||
> `> así`. No borre las secciones: si alguna no aplica, escriba "No aplica" y
|
||||
> explique por qué en una línea.
|
||||
|
||||
## Título
|
||||
|
||||
`<slug-del-runbook>`
|
||||
|
||||
## Propósito
|
||||
|
||||
> Qué logra este runbook en una o dos frases. Si no puede explicarlo en dos
|
||||
> frases, probablemente son dos runbooks.
|
||||
|
||||
## Propietario
|
||||
|
||||
> Rol o persona responsable de mantenerlo actualizado.
|
||||
|
||||
## Audiencia
|
||||
|
||||
> Uno o más de: `role-developer`, `role-operator`, `role-reviewer`, `role-owner`.
|
||||
|
||||
## Entornos permitidos
|
||||
|
||||
> Uno o más de: `env-local`, `env-ci`, `env-staging`, `env-production`.
|
||||
|
||||
## Clasificación de riesgo
|
||||
|
||||
> `risk-read-only`, `risk-mutating` o `risk-destructive`, por celda — no
|
||||
> necesariamente una sola clasificación para todo el documento.
|
||||
|
||||
## Prerrequisitos
|
||||
|
||||
> Herramientas, variables de entorno, accesos y estado previo necesarios.
|
||||
> Distinga:
|
||||
> - **Observación**: qué debe ser cierto antes de empezar.
|
||||
> - **Hipótesis**: qué se espera que pase, si aplica (para runbooks de
|
||||
> diagnóstico).
|
||||
|
||||
## Variables requeridas
|
||||
|
||||
> Nombre, propósito y si es secreta (nunca ponga el valor aquí; use
|
||||
> `.env.example` como referencia de nombres).
|
||||
|
||||
## Preflight
|
||||
|
||||
> Celda de sólo lectura que confirma que el entorno está listo, sin instalar
|
||||
> ni mutar nada.
|
||||
|
||||
```sh {"name":"template-preflight-example","tag":"role-developer,env-local,risk-read-only,ci-safe","interactive":"false"}
|
||||
echo "reemplace esto por una comprobación real de prerrequisitos"
|
||||
```
|
||||
|
||||
## Procedimiento
|
||||
|
||||
> Distinga explícitamente:
|
||||
> - **Acción**: qué comando se ejecuta.
|
||||
> - **Resultado esperado**: qué debería observarse si funcionó.
|
||||
|
||||
Ejemplo de celda de sólo lectura (segura para CI):
|
||||
|
||||
```sh {"name":"template-safe-example","tag":"role-developer,env-local,risk-read-only,ci-safe","interactive":"false"}
|
||||
echo "una celda de sólo lectura va aquí"
|
||||
```
|
||||
|
||||
Ejemplo conceptual de celda que muta estado (nunca copie literalmente sin
|
||||
adaptar prerrequisitos y validación):
|
||||
|
||||
```sh {"name":"template-mutating-example","tag":"role-operator,env-production,risk-mutating,manual-only","interactive":"true","excludeFromRunAll":true}
|
||||
echo "una celda que muta estado real va aquí; nunca risk-mutating + ci-safe"
|
||||
```
|
||||
|
||||
## Validación
|
||||
|
||||
> Cómo se confirma que el resultado observado es el esperado. Comandos
|
||||
> concretos, no "revisar que todo esté bien".
|
||||
|
||||
## Rollback
|
||||
|
||||
> Cómo revertir, si aplica. Si no hay reversión directa, dígalo explícitamente
|
||||
> y describa el procedimiento de corrección manual.
|
||||
|
||||
## Registro en Clusterlog
|
||||
|
||||
> Qué memoria, tarea o commit debe generarse fuera de Runme como evidencia
|
||||
> canónica de que esto se ejecutó.
|
||||
|
||||
## Evidencia
|
||||
|
||||
> Qué guardar como prueba (salida JSON, SHA de commit, ID de memoria).
|
||||
|
||||
## Referencias
|
||||
|
||||
> Enlaces a `CLI.md`, `SECURITY.md`, ADRs u otros runbooks relacionados.
|
||||
|
||||
## Limitaciones
|
||||
|
||||
> Qué este runbook explícitamente no cubre, y por qué.
|
||||
@@ -0,0 +1,89 @@
|
||||
# Ciclo de desarrollo de clusterlog
|
||||
|
||||
Propósito: correr el mismo ciclo que `AGENTS.md` pide "antes de entregar",
|
||||
como notebook en vez de copiar/pegar bloques sueltos. Todas las celdas de
|
||||
este documento envuelven targets existentes de `Makefile`; ninguna reimplementa
|
||||
lo que ya hace `go test`, `go vet` o `clusterlog`.
|
||||
|
||||
## Prerrequisitos
|
||||
|
||||
- Go 1.23+, Git con firmas SSH.
|
||||
- Para las celdas con Zola: binario `zola` en `PATH` (opcional; las celdas de
|
||||
`validate`/`sync` no lo requieren).
|
||||
|
||||
## Formato
|
||||
|
||||
```sh {"name":"clusterlog-gofmt-check","tag":"role-developer,env-local,risk-read-only,ci-safe","interactive":"false"}
|
||||
test -z "$(gofmt -l cmd internal)"
|
||||
```
|
||||
|
||||
## Pruebas y análisis estático
|
||||
|
||||
```sh {"name":"clusterlog-vet","tag":"role-developer,env-local,risk-read-only,ci-safe","interactive":"false"}
|
||||
go vet ./...
|
||||
```
|
||||
|
||||
```sh {"name":"clusterlog-test-race","tag":"role-developer,env-local,risk-read-only,ci-safe","interactive":"false"}
|
||||
go test -race ./...
|
||||
```
|
||||
|
||||
## Compilar y proyectar
|
||||
|
||||
```sh {"name":"clusterlog-dev-build","tag":"role-developer,env-local,risk-read-only,ci-safe","interactive":"false"}
|
||||
make build
|
||||
```
|
||||
|
||||
```sh {"name":"clusterlog-dev-sync","tag":"role-developer,env-local,risk-mutating,manual-only","interactive":"true","excludeFromRunAll":true}
|
||||
# Escribe data/generated/site_state.json. Revise el diff antes de confirmar
|
||||
# cualquier commit que incluya ese archivo regenerado.
|
||||
make sync
|
||||
git diff --stat -- data/generated/site_state.json
|
||||
```
|
||||
|
||||
### Prerrequisitos de `clusterlog-dev-sync`
|
||||
|
||||
- Haber corrido `clusterlog-dev-build` en esta sesión (o tener `bin/clusterlog`
|
||||
ya compilado).
|
||||
|
||||
### Validación posterior
|
||||
|
||||
```sh {"name":"clusterlog-dev-sync-check","tag":"role-developer,env-local,risk-read-only,ci-safe","interactive":"false"}
|
||||
make sync-check
|
||||
```
|
||||
|
||||
### Rollback
|
||||
|
||||
`data/generated/site_state.json` es 100% regenerable desde el contenido
|
||||
fuente (`content/`, `data/admins.json`, `data/*-events/`). Si `make sync`
|
||||
produjo un diff no deseado, descarte el archivo con
|
||||
`git checkout -- data/generated/site_state.json` y no lo incluya en el commit.
|
||||
|
||||
## Validar
|
||||
|
||||
```sh {"name":"clusterlog-dev-validate-local","tag":"role-developer,env-local,risk-read-only,ci-safe","interactive":"false"}
|
||||
make validate-local
|
||||
```
|
||||
|
||||
## Flujo completo local (equivalente a CI, sin Zola)
|
||||
|
||||
```sh {"name":"clusterlog-dev-smoke","tag":"role-developer,env-local,risk-read-only,ci-safe","interactive":"false"}
|
||||
make build
|
||||
./bin/clusterlog --root . sync --check
|
||||
./bin/clusterlog --root . validate --skip-zola
|
||||
./scripts/smoke.sh
|
||||
```
|
||||
|
||||
## Registro en Clusterlog
|
||||
|
||||
Ninguna celda de este runbook crea memorias, tareas ni commits. Si el
|
||||
trabajo de la sesión amerita una memoria, hágalo con el flujo normal descrito
|
||||
en `AGENTS.md` (`clusterlog memory create --from-json`, con `--dry-run` antes
|
||||
de `--commit`) — fuera de Runme, con su propia llave.
|
||||
|
||||
## Limitaciones
|
||||
|
||||
- `clusterlog-dev-sync` está marcado `manual-only` a propósito: regenera un
|
||||
archivo versionado y su diff debe revisarse antes de confirmarlo.
|
||||
- Este runbook no incluye `make site`/`zola build`: ver
|
||||
[`RUNBOOK.md`](../RUNBOOK.md#comprobaciones-rápidas) para por qué esa celda
|
||||
vive ahí y no se duplica aquí.
|
||||
@@ -0,0 +1,120 @@
|
||||
# Reunión semanal de revisión — versión ejecutable
|
||||
|
||||
Este runbook es el complemento ejecutable de
|
||||
[`docs/WEEKLY_REVIEW.md`](../docs/WEEKLY_REVIEW.md), que conserva la agenda y
|
||||
el criterio de la reunión. Los comandos de preparación y cierre viven aquí
|
||||
una sola vez; `docs/WEEKLY_REVIEW.md` enlaza a este archivo en vez de repetir
|
||||
los bloques de shell.
|
||||
|
||||
## Propósito
|
||||
|
||||
Preparar y cerrar la reunión semanal sin copiar comandos a mano.
|
||||
|
||||
## Propietario
|
||||
|
||||
Cada administrador ejecuta su propia preparación con su propia llave.
|
||||
|
||||
## Audiencia
|
||||
|
||||
`role-reviewer`, `role-owner`.
|
||||
|
||||
## Entornos permitidos
|
||||
|
||||
`env-local` únicamente. Ningún comando de este runbook debe correr en CI:
|
||||
todos requieren identidad SSH personal o mutan la cola de revisión.
|
||||
|
||||
## Clasificación de riesgo
|
||||
|
||||
Preparación: `risk-read-only`. Marcar una revisión: `risk-mutating`.
|
||||
|
||||
## Prerrequisitos
|
||||
|
||||
- `CLUSTERLOG_SSH_KEY` apuntando a su llave pública registrada.
|
||||
- Haber leído las memorias pendientes antes de marcarlas.
|
||||
|
||||
## Variables requeridas
|
||||
|
||||
- `CLUSTERLOG_SSH_KEY`: ruta a su llave pública.
|
||||
- `MEM_ID`: el `entry_id` exacto de la memoria que va a marcar (por ejemplo
|
||||
`MEM-20260825-ABC123`), sólo para la celda de cierre.
|
||||
|
||||
## Preflight
|
||||
|
||||
```sh {"name":"weekly-review-identity","tag":"role-reviewer,env-local,risk-read-only","interactive":"false"}
|
||||
: "${CLUSTERLOG_SSH_KEY:?defina CLUSTERLOG_SSH_KEY}"
|
||||
./bin/clusterlog --root . --json --ssh-key "$CLUSTERLOG_SSH_KEY" identity
|
||||
```
|
||||
|
||||
## Procedimiento
|
||||
|
||||
### 1. Preparación individual
|
||||
|
||||
```sh {"name":"weekly-review-pending","tag":"role-reviewer,env-local,risk-read-only","interactive":"false"}
|
||||
: "${CLUSTERLOG_SSH_KEY:?defina CLUSTERLOG_SSH_KEY}"
|
||||
./bin/clusterlog --root . --json --ssh-key "$CLUSTERLOG_SSH_KEY" review list --mine
|
||||
```
|
||||
|
||||
```sh {"name":"weekly-review-my-tasks","tag":"role-reviewer,env-local,risk-read-only","interactive":"false"}
|
||||
: "${CLUSTERLOG_SSH_KEY:?defina CLUSTERLOG_SSH_KEY}"
|
||||
./bin/clusterlog --root . --json --ssh-key "$CLUSTERLOG_SSH_KEY" task list --mine
|
||||
```
|
||||
|
||||
### 2. Marcar una memoria como revisada (durante o después de la reunión)
|
||||
|
||||
```sh {"name":"weekly-review-mark","tag":"role-reviewer,env-production,risk-mutating,manual-only","interactive":"true","excludeFromRunAll":true}
|
||||
: "${CLUSTERLOG_SSH_KEY:?defina CLUSTERLOG_SSH_KEY}"
|
||||
: "${MEM_ID:?defina MEM_ID con el entry_id exacto de la memoria, por ejemplo MEM-20260825-ABC123}"
|
||||
./bin/clusterlog --root . --json --commit --ssh-key "$CLUSTERLOG_SSH_KEY" \
|
||||
review mark "$MEM_ID" --note "Revisado en reunión semanal"
|
||||
```
|
||||
|
||||
Prerrequisito adicional de esta celda: haber leído y entendido la memoria
|
||||
completa, no sólo su título. `env-production` porque un `--commit` exitoso
|
||||
queda en el historial de Git compartido — no es una operación de laboratorio.
|
||||
|
||||
### 3. Cierre
|
||||
|
||||
```sh {"name":"weekly-review-close-check","tag":"role-owner,env-local,risk-read-only,ci-safe","interactive":"false"}
|
||||
make sync-check
|
||||
```
|
||||
|
||||
```sh {"name":"weekly-review-close-validate","tag":"role-owner,env-local,risk-read-only,ci-safe","interactive":"false"}
|
||||
make validate-local
|
||||
```
|
||||
|
||||
```sh {"name":"weekly-review-close-verify","tag":"role-owner,env-local,risk-read-only,ci-safe","interactive":"false"}
|
||||
./bin/clusterlog --root . verify commit HEAD
|
||||
```
|
||||
|
||||
## Validación
|
||||
|
||||
`review list --mine` debe quedar vacío (o con causa y fecha de seguimiento
|
||||
documentada aparte, según `docs/WEEKLY_REVIEW.md`).
|
||||
|
||||
## Rollback
|
||||
|
||||
`review mark` no tiene reversión directa: agrega un evento inmutable en
|
||||
`data/review-events/`. Si se marcó por error, no se edita el evento; se
|
||||
documenta el error en la siguiente memoria y se decide en equipo si se
|
||||
requiere una excepción de política (ver "Preguntas de gobierno" en
|
||||
`HOJA_DE_PROYECTO.md`).
|
||||
|
||||
## Registro en Clusterlog
|
||||
|
||||
`review mark --commit` ya deja su propio commit firmado; no hace falta una
|
||||
memoria adicional sólo por marcar una revisión.
|
||||
|
||||
## Evidencia
|
||||
|
||||
Salida JSON de `review mark` (contiene el hash de contenido revisado) y el
|
||||
SHA del commit que produce.
|
||||
|
||||
## Referencias
|
||||
|
||||
- [`docs/WEEKLY_REVIEW.md`](../docs/WEEKLY_REVIEW.md)
|
||||
- [`CLI.md`](../CLI.md), sección 7 (Revisión).
|
||||
|
||||
## Limitaciones
|
||||
|
||||
Ninguna celda de este runbook es `ci-safe`: todas requieren una llave SSH
|
||||
personal o mutan estado compartido. Esto es intencional, no una omisión.
|
||||
Reference in New Issue
Block a user