Compare commits

...
5 Commits
Author SHA1 Message Date
fernando 856995db1b skill: documentar contrato de acceso SSH al clúster administrado
CI / test-and-build (push) Successful in 12s
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.
2026-08-19 00:16:29 -06:00
fernando 4dbdc15988 docs: formalizar decisiones de arquitectura (ADR) y enlazarlas desde el README
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.
2026-08-19 00:16:23 -06:00
fernando f638a9e314 docs(manuales): pulir redacción del manual de acceso al servicio Git
Aclara el prerrequisito de VPN, ajusta el ejemplo de nombre de llave y hace explícito que cada miembro completa su propia verificación.
2026-08-19 00:16:19 -06:00
fernando a5644be3fc chore: ignorar directorio local de memorias temporales
/memorias/ se usa como bitácora de trabajo fuera del repositorio (ver CLAUDE.md) y no debe versionarse.
2026-08-19 00:16:12 -06:00
fernando e7d2ad374a manuales(RUN-20260819-BF6DC8): Configurar acceso SSH al clúster administrado 2026-08-18 23:58:18 -06:00
6 changed files with 245 additions and 4 deletions
+49
View File
@@ -0,0 +1,49 @@
---
name: acceso-cluster
description: Cómo conectarse por SSH al clúster que este equipo administra (host mcps y otros que se agreguen) desde cualquier sesión de IA lanzada en este repositorio. Úsala siempre que una tarea requiera ejecutar comandos en el clúster, diagnosticar algo en vivo, o cuando alguien pida conectarse a un host administrado.
---
# Acceso SSH al clúster administrado
## Alcance
Esta skill documenta cómo llegar al **clúster** que el comité administra (el host, no la herramienta). Es la contraparte operativa de [`docs/ADR.md`](../../../docs/ADR.md): las decisiones de diseño de `clusterlog` (la herramienta) están en `docs/adr/`; el conocimiento de cómo alcanzar y tratar el clúster real vive aquí y en el manual asociado.
Se carga automáticamente en cualquier sesión de Claude Code iniciada en este repositorio, sin importar qué miembro del comité la lance, para que todas las IAs usen el mismo contrato de conexión.
## Contrato de conexión (obligatorio)
- **Nunca construya la conexión a mano.** No arme comandos del tipo `ssh -i ~/.ssh/<llave> usuario@ip`. Use siempre el alias corto:
```bash
ssh <alias>
```
donde `<alias>` es uno de los definidos en el [inventario](#inventario-de-hosts) más abajo (por ejemplo, `ssh mcps`).
- **La identidad (llave, usuario, host real, puerto) nunca vive en este repositorio.** Cada administrador la resuelve en su propio `~/.ssh/config`, local y no versionado. Ese archivo es lo único que traduce el alias compartido a los datos personales de conexión. Ver [el manual de configuración](../../../content/manuales/) para la plantilla.
- Si un alias no existe o la conexión falla, **no adivine** IP, usuario ni ruta de llave. Dígale al usuario qué alias faltó y remítalo al manual de configuración; no intente "resolverlo" con valores inventados.
- **Nunca lea, imprima, copie ni pegue el contenido de una llave privada**, ni siquiera para depurar. `ssh -v <alias>` es suficiente para diagnosticar sin exponer material sensible.
- Antes de ejecutar cualquier comando contra un host real, **anuncie qué va a correr**. Prefiera primero comandos de sólo lectura/diagnóstico (`uptime`, `systemctl status`, `df -h`, logs) sobre cualquier cosa que cambie estado.
- **Nunca ejecute un comando destructivo o que cambie estado en el clúster sin confirmación explícita del usuario en esa sesión**, aunque parezca una tarea rutinaria. Esto aplica con más fuerza que el nivel de autonomía general de la sesión, porque el radio de impacto es un sistema compartido, no este repositorio.
- Si la sesión hizo un cambio real en el clúster, ese cambio se documenta como una memoria de `clusterlog` (ver `AGENTS.md` / `CLAUDE.md`) — esta skill sólo gobierna *cómo llegar*, no cómo registrar lo que se hizo.
## Inventario de hosts
Tabla compartida y sin secretos: alias, para qué sirve, y notas de riesgo. **No incluya aquí IP, usuario, puerto ni ruta de llave** — eso es personal y va en el `~/.ssh/config` de cada quien.
| Alias | Rol | Notas | Riesgo |
|---|---|---|---|
| `mcps` | Host/entrada principal del clúster administrado. | El mismo acceso se reutiliza para el servicio Git interno (`git.mcps-epcm.org:2222`); ver [manual de acceso a Git](../../../content/manuales/2026-08-18-run-20260818-ba0a96-configurar-acceso-al-servicio-git.md). | Por confirmar con el comité. |
Cuando el clúster incorpore un nuevo host o rol relevante, agregue una fila aquí en un pull request normal — esta tabla es la fuente compartida de qué alias existen y para qué sirve cada uno. Cada administrador, por su parte, agrega el bloque `Host` correspondiente en su propio `~/.ssh/config` (procedimiento en el manual).
## División de responsabilidades
| Vive en | Contiene | Versionado |
|---|---|---|
| Esta skill (`.claude/skills/acceso-cluster/`) | Contrato de comportamiento + inventario de alias/roles, sin secretos. | Sí, compartido. |
| `~/.ssh/config` de cada administrador | Host real, usuario, puerto, ruta de llave por alias. | No, local y personal. |
| [Manual de configuración](../../../content/manuales/) | Procedimiento paso a paso para que una persona arme su `~/.ssh/config` por primera vez. | Sí, compartido (el procedimiento; no los valores personales). |
Si al operar el clúster aparece un dato de conexión que no encaja en esta división (por ejemplo, un salto por bastión, un puerto no estándar), decídalo con el comité y refléjelo en el inventario de arriba y en la plantilla del manual — no lo resuelva ad hoc dentro de una sesión.
+1
View File
@@ -1,3 +1,4 @@
/memorias/
/public/ /public/
/bin/ /bin/
/themes/zola.386/ /themes/zola.386/
+1
View File
@@ -175,6 +175,7 @@ docs/ decisiones arquitectónicas y operación
- [`SECURITY.md`](SECURITY.md): modelo de confianza y despliegue recomendado. - [`SECURITY.md`](SECURITY.md): modelo de confianza y despliegue recomendado.
- [`THEME_COMPATIBILITY.md`](THEME_COMPATIBILITY.md): estrategia para `zola.386`. - [`THEME_COMPATIBILITY.md`](THEME_COMPATIBILITY.md): estrategia para `zola.386`.
- [`docs/WEEKLY_REVIEW.md`](docs/WEEKLY_REVIEW.md): guion de la reunión semanal. - [`docs/WEEKLY_REVIEW.md`](docs/WEEKLY_REVIEW.md): guion de la reunión semanal.
- [`docs/ADR.md`](docs/ADR.md): decisiones de diseño de **clusterlog** (la herramienta), no del clúster que administra; formato, campos y ejemplo. Registros en [`docs/adr/`](docs/adr/), sin equivalente en la UI del sitio ni en la CLI.
- [`VALIDATION_REPORT.md`](VALIDATION_REPORT.md): pruebas ejecutadas, límites y controles pendientes. - [`VALIDATION_REPORT.md`](VALIDATION_REPORT.md): pruebas ejecutadas, límites y controles pendientes.
- [`RELEASE_NOTES.md`](RELEASE_NOTES.md): alcance de la entrega 0.1.0. - [`RELEASE_NOTES.md`](RELEASE_NOTES.md): alcance de la entrega 0.1.0.
@@ -22,10 +22,10 @@ author_fingerprint = "SHA256:JhN1Tt4jYqWoJIznDJ6QkMAiOR6HFHr3xLz9aBJqmPg"
## Prerrequisitos ## Prerrequisitos
- Su cuenta en el servicio Git ya está creada; recibió por correo el usuario y una contraseña temporal. - Su cuenta en el servicio Git ya está creada; recibió por correo el usuario y una contraseña temporal.
- Acceso de red al clúster ya configurado (el mismo que usa para `ssh mcps` y los demás hosts internos). - Su acceso a la VPN del clúster ya configurado (el mismo que usa para `ssh mcps` y los demás servicios internos).
- Su llave SSH personal, la misma que ya usa para acceder al clúster. No hace falta crear una llave nueva. - Su llave SSH personal, la misma que ya usa para acceder al clúster. No hace falta crear una llave nueva.
El servicio Git vive en la misma infraestructura que el host `mcps`, pero es un servicio aparte (Gitea, detrás de un proxy HTTPS) con su propio inicio de sesión web y su propio puerto SSH — no es lo mismo que iniciar sesión con `ssh mcps`. El servicio Git vive en la misma infraestructura que el clúster con su propio inicio de sesión web y su propio puerto SSH, por lo que no es lo mismo que iniciar sesión con `ssh mcps`.
## 1. Iniciar sesión y cambiar la contraseña ## 1. Iniciar sesión y cambiar la contraseña
@@ -43,7 +43,7 @@ La contraseña sólo sirve para la interfaz web. Clonar, subir o bajar cambios p
``` ```
2. En la interfaz web: avatar → **Configuración** → **Llaves SSH / GPG** → **Agregar llave**. 2. En la interfaz web: avatar → **Configuración** → **Llaves SSH / GPG** → **Agregar llave**.
3. Péguela completa (empieza con `ssh-ed25519` o `ssh-rsa`), póngale un nombre que la identifique (por ejemplo, el nombre de su equipo) y guarde. 3. Péguela completa (empieza con `ssh-ed25519` o `ssh-rsa`), póngale un nombre que la identifique (por ejemplo, usuario@equipo) y guarde.
## 3. Confirmar que la llave quedó activa ## 3. Confirmar que la llave quedó activa
@@ -77,7 +77,7 @@ Si el clonado termina sin errores y `git log` muestra los últimos commits, su a
- `git clone ssh://git@git.mcps-epcm.org:2222/fernando/clusterlogs.git` termina sin errores. - `git clone ssh://git@git.mcps-epcm.org:2222/fernando/clusterlogs.git` termina sin errores.
- `cd clusterlogs && git log --oneline -3` muestra commits reales del repositorio. - `cd clusterlogs && git log --oneline -3` muestra commits reales del repositorio.
Avíseme cuando complete estos tres puntos para marcarlo en la reunión. Cada miembro debe completar estos tres puntos para marcarlo en la reunión.
## Solución de problemas ## Solución de problemas
@@ -0,0 +1,77 @@
+++
title = "Configurar acceso SSH al clúster administrado"
description = "Definir su alias personal en ~/.ssh/config para conectarse al clúster (mcps) sin exponer llaves ni rutas personales en el repositorio."
date = 2026-08-19T05:58:18Z
authors = ["gen"]
slug = "run-20260819-bf6dc8-configurar-acceso-ssh-al-cluster-administrado"
template = "page.html"
weight = 15
[taxonomies]
categories = ["manuales"]
tags = ["acceso", "cluster", "ssh"]
systems = ["cluster"]
[extra]
id = "RUN-20260819-BF6DC8"
kind = "manuales"
author_id = "gen"
author_fingerprint = "SHA256:JhN1Tt4jYqWoJIznDJ6QkMAiOR6HFHr3xLz9aBJqmPg"
+++
## Prerrequisitos
- Ya es administrador registrado en clusterlog y tiene su llave SSH personal (la misma de siempre; no hace falta crear una nueva).
- Ya tiene acceso de red/VPN al clúster.
- Un *owner* u otro miembro del comité le confirmó, fuera de este repositorio, el usuario, el host o IP real y el puerto para conectarse. Esos datos son personales/locales y **no están documentados aquí** — sólo el procedimiento para guardarlos.
## Por qué esto no vive en el repositorio
El repositorio guarda el contrato compartido de cómo conectarse (alias, roles, qué evitar) en la skill [`acceso-cluster`](../../.claude/skills/acceso-cluster/SKILL.md), para que cualquier IA lanzada desde aquí — la suya o la de otro miembro del comité — se comporte igual. Lo que varía por persona (llave, usuario, host real, puerto) vive únicamente en su `~/.ssh/config` local, nunca en Git.
## 1. Agregar su alias en `~/.ssh/config`
Abra (o cree) `~/.ssh/config` y agregue un bloque `Host` por cada alias listado en el inventario de la skill. Para el alias principal `mcps`:
```sshconfig
Host mcps
HostName <host-o-ip-real-que-le-confirmaron>
User <su-usuario>
Port <puerto-si-no-es-22>
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
```
Reemplace `<host-o-ip-real-que-le-confirmaron>` y `<su-usuario>` por los datos que le dieron; no los pida ni los busque en este repositorio. Ajuste la ruta de `IdentityFile` si usa una llave distinta a la registrada en `clusterlog`.
## 2. Confirmar la conexión
```bash
ssh mcps
```
Debe llegar directo a una sesión de shell en el clúster, sin que le pida contraseña. Si en cambio ve `Permission denied (publickey)` o `Could not resolve hostname`, revise la sección de solución de problemas.
## 3. Cómo lo usa un agente de IA
Cualquier IA (Claude Code u otra) lanzada desde este repositorio debe ejecutar `ssh mcps` — o el alias que corresponda — y nunca construir la conexión a mano con `-i` y una ruta de llave. Ese contrato completo, incluyendo qué comandos evitar y cuándo pedir confirmación antes de actuar sobre el clúster, está en la skill `acceso-cluster`, que se carga sola en cada sesión de Claude Code iniciada aquí. Este manual sólo cubre la configuración local que hace posible que ese contrato funcione igual para todos.
## Verificación
- `ssh mcps` conecta sin pedir contraseña y sin errores.
- `ssh -v mcps` (si hace falta depurar) muestra que ofreció la llave correcta, sin haber impreso ni copiado su contenido.
- Una IA lanzada desde este repositorio, al pedirle conectarse al clúster, usa `ssh mcps` por su cuenta en vez de preguntar por una ruta de llave o una IP.
## Mantenimiento
Cuando el clúster incorpore un host o alias nuevo, dos pasos separados:
1. Alguien agrega la fila correspondiente (alias, rol, notas) al inventario compartido en `acceso-cluster/SKILL.md`, vía pull request normal.
2. Cada administrador agrega su propio bloque `Host` para ese alias en su `~/.ssh/config` local, con sus datos reales.
## Solución de problemas
- **`Permission denied (publickey)`**: confirme que `IdentityFile` en su bloque `Host` apunta a la llave privada correcta y que esa llave está registrada como administrador en `clusterlog` (`clusterlog --ssh-key ... identity`). Revise también `ssh-add -l` si usa un agente.
- **`Could not resolve hostname` / tiempo de espera agotado**: confirme `HostName` y que tiene la VPN o red de administración activa.
- **Le pide contraseña en vez de usar la llave**: revise que `User` y `Port` en el bloque `Host` sean los que le confirmaron, y que la llave pública esté autorizada en ese host.
- **Un agente de IA intenta armar `ssh -i ...` en vez de usar el alias**: es una señal de que la skill `acceso-cluster` no se cargó o fue ignorada; repórtelo, no complete la conexión manualmente en su lugar dentro de la sesión.
+113
View File
@@ -0,0 +1,113 @@
# Decisiones de arquitectura (ADR)
## Alcance
Un ADR (*Architecture Decision Record*) documenta una decisión de diseño sobre **clusterlog**: la herramienta, su modelo de datos, su CLI, su proyección estática y su cadena de confianza. No es el lugar para decisiones operativas del clúster que administra el equipo (topología de nodos, políticas de red, capacidad, etc.); esas pertenecen a **Manuales** o **Memorias** dentro del sitio.
Un ADR se justifica cuando la decisión:
- es costosa o difícil de revertir;
- afecta el modelo de datos, la identidad/firma, o el contrato de la CLI;
- descarta una alternativa razonable por un motivo que no es obvio leyendo el código;
- va a ser preguntada de nuevo en el futuro ("¿por qué no usamos X?").
No se justifica para elección de librerías internas reversibles, estilo de código, o correcciones de bugs — eso va en el mensaje de commit o, si amerita contexto, en una memoria.
## Dónde viven y cómo se gestionan
- Los archivos están en [`docs/adr/`](adr/), uno por decisión.
- **No se ven en la UI del sitio ni se gestionan con la CLI de `clusterlog`.** `docs/adr/` no forma parte de `content/` (lo que Zola proyecta) y no existe ningún comando `clusterlog adr *`. Son Markdown plano, editado a mano, versionado y revisado como el resto del repositorio.
- Se crean, discuten y aprueban por revisión de código normal (pull request), igual que cualquier otro cambio al repositorio.
## Nombre de archivo
```text
docs/adr/NNNN-titulo-en-kebab-case.md
```
- `NNNN`: número secuencial de 4 dígitos, sin reutilizar ni renumerar al superar un ADR.
- El slug es una versión corta del título en minúsculas, con guiones.
## Campos y secciones
Cada ADR sigue esta estructura, en este orden:
```markdown
# ADR-NNNN: Título de la decisión
- **Estado:** propuesta | aceptada | rechazada | reemplazada por ADR-MMMM
- **Fecha:** AAAA-MM-DD
## Contexto
## Decisión
## Consecuencias positivas
## Consecuencias negativas
## Alternativas descartadas (opcional)
## Regla de interpretación (opcional)
```
| Campo/Sección | Obligatorio | Contenido |
|---|---|---|
| Título | sí | Frase corta que nombra la decisión, no el problema. |
| Estado | sí | Uno de: `propuesta`, `aceptada`, `rechazada`, `reemplazada por ADR-MMMM`. Un ADR aceptado no se borra ni se edita para invertir la decisión; se agrega uno nuevo que lo reemplaza y se actualiza el estado del anterior. |
| Fecha | sí | Fecha en que el estado actual entró en vigor. |
| Contexto | sí | La fuerza o restricción que exige decidir: qué problema, qué tensión, qué no puede seguir igual. Sin esto, la decisión no se puede evaluar más adelante. |
| Decisión | sí | Qué se decidió, en términos concretos y verificables (no aspiracionales). |
| Consecuencias positivas | sí | Efectos deseables que se aceptan a cambio. |
| Consecuencias negativas | sí | Costos, riesgos o deuda que la decisión introduce a sabiendas. Un ADR sin consecuencias negativas es sospechoso. |
| Alternativas descartadas | no | Opciones consideradas y por qué se descartaron. Útil cuando la pregunta "¿por qué no X?" es previsible. |
| Regla de interpretación | no | Aclaración normativa para evitar que la decisión se lea de forma laxa (ver ADR-0002 como ejemplo). |
## Ejemplo
```markdown
# ADR-0004: Límite de tamaño para eventos JSON individuales
- **Estado:** aceptada
- **Fecha:** 2026-08-18
## Contexto
Los eventos de `data/review-events/` y `data/task-events/` son archivos JSON
inmutables, uno por evento. Nada impide hoy que un evento incluya un adjunto
grande o un volcado de log completo, lo que degradaría `clusterlog sync` y
ensuciaría el historial Git con blobs pesados.
## Decisión
- Cada archivo de evento se limita a 64 KB.
- La CLI rechaza la escritura si el JSON serializado excede el límite,
con un mensaje que indica el tamaño real y el máximo permitido.
- El límite se valida antes de firmar o comitear, nunca después.
## Consecuencias positivas
- El historial Git permanece liviano y rápido de clonar.
- `clusterlog sync` tiene un tiempo de ejecución más predecible.
- Fuerza a resumir en vez de adjuntar evidencia extensa.
## Consecuencias negativas
- Evidencia grande (logs completos, capturas) debe vivir fuera del evento
y referenciarse por enlace o ticket.
- El límite es arbitrario y puede requerir ajuste con el uso real.
## Alternativas descartadas
- Sin límite: expone el repositorio a crecer sin control y a bloquear CI.
- Comprimir el evento: complica la lectura directa con herramientas
estándar de Git, que es una propiedad central de ADR-0001.
```
## Relación con otros tipos de contenido
- **ADR**: por qué el software está diseñado así. Vive en `docs/adr/`, no se sincroniza al sitio.
- **Manual** (`content/manuales/`): cómo ejecutar un procedimiento repetible sobre el clúster o la bitácora. Sí se publica en el sitio.
- **Memoria**: qué se hizo, cuándo, por quién, con qué validación y reversión, en una sesión concreta. Sí se publica en el sitio.
Si al escribir una memoria o un manual surge una decisión de diseño reutilizable que no está documentada, es señal de que falta un ADR — no de que deba explicarse de nuevo cada vez.