Un PC con Windows manda tareas a una Mac y recoge ramas de git. El PC valida, enruta, vigila y publica; la Mac ejecuta con un agente de código, aislada en un worktree por trabajo. Cinco vistas: contenedores, datos, flujos con el ciclo de vida de un trabajo, despliegue y decisiones. Haz clic en una caja; reproduce un flujo para ver el recorrido.
Cada caja es una pieza que corre por separado: un script, un servicio, un repo o un sitio. Las líneas son llamadas reales: protocolo y qué viaja. La caja «ssh» agrupa la única puerta del PC hacia la Mac.
El resultado de un trabajo no es un archivo suelto sino una rama. La Mac la deja en su clon, Windows la trae por ssh, la escanea con gitleaks y recién entonces la sube. Revisar y descartar son operaciones de git, y fusionar sigue siendo una decisión de una persona.
Un ssh que espera pierde el resultado si se cierra la ventana. El supervisor del nodo vive más que la conexión: lanza el trabajo en su propio grupo de procesos, late, escribe el estado final y deja el commit. Windows solo recoge cuando le conviene.
Todo lo que va a la Mac pasa por una conexión autenticada y cifrada, sin abrir ningún puerto de red nuevo. Hasta el puente conversacional escucha solo en loopback y se alcanza con curl dentro de ese mismo ssh, además de una firma HMAC por petición.
Ni los archivos JSON ni history.db declaran claves foráneas. Los vínculos se resuelven por convención: el mismo id de trabajo en spec, status y job; el path de la transcripción entre files, msgs y agents (collect.py: db_load); y origin_session del ledger contra el id de sesión, con que el visor marca qué sesiones mandaron trabajos a otro nodo (build.py: remote_jobs_by_session).
No hay servidor central ni base de datos que operar: el PC corre tres procesos residentes y la Mac los suyos como servicios de usuario. Lo único que vive en internet son dos sitios de Hostinger, y ambos solo reciben datos ya filtrados.
Requisitos en la Mac: bash 3.2 (el de macOS), python 3 del sistema para el supervisor y tmux. Los trabajos largos y el puente necesitan la sesión gráfica abierta al menos una vez para que el llavero esté desbloqueado.
Qué gana: otro nodo entra al reparto y al visor con una orden. Qué no gana: automatizar el alta de tmux y del puente, ni nodos Linux.
| N.º | Decisión | Por qué | Descartado |
|---|---|---|---|
| 27 | El tmux del nodo nace del arranque gráfico y nunca se crea por ssh | El llavero de macOS solo está desbloqueado en la sesión gráfica; por ssh, claude y git aparecen sin sesión | Crear la sesión por ssh: nacería sin llavero. tmux-run.sh sale con 75 y avisa cómo arreglarlo |
| 29 | El nodo no hace push; Windows trae la rama, la escanea y la sube | Una sola puerta de control, en la máquina que tiene gitleaks, sobre exactamente los commits nuevos | Push desde el nodo, que no pasa por el escáner. Solo existe con ENJAMBRE_NODE_PUSH=1 |
| 209 | El push es opt-in en repos públicos | Una rama en un remoto público queda publicada al llegar, haya o no escaneo | Subir siempre. Sin «push:» en la TASK, solo los repos privados suben |
| 200 | Un supervisor en el nodo, no un ssh que espera | Windows vuelve en segundos y el resultado no depende de que la ventana siga abierta | Alargar tmux-run.sh: espera con tope de 7200 s y devuelve al final; cerrar la ventana perdía el ledger |
| 202 | Los latidos no van al ledger | El ledger mantiene «una línea por trabajo» y cuatro lectores dependen de ello | Líneas «event: heartbeat» en jobs.jsonl: obligaba a cambiar a los cuatro lectores |
| 280 | La pausa la aplica el supervisor del propio nodo | status.json conserva un único escritor; antes de cualquier TERM va un SIGCONT porque un proceso detenido no muere limpio | ssh kill -STOP directo desde el PC: dos escritores del estado |
| 237 | El puente se alcanza por ssh y curl a loopback, con firma HMAC | ssh ya autentica; la firma cubre marca de tiempo, nonce, método, ruta y hash del cuerpo, y rechaza peticiones con Origin | Escuchar en la LAN con un token: un puerto más expuesto a la red |
| 247 | El puente no edita por defecto | Trabaja en el clon principal, sin rama; una copia sucia rompe git pull --ff-only y los worktrees de los workers | Permitir ediciones siempre. Los cambios de código siguen por enjambre run (rama y revisión); --edit es por turno |
| 174 | La web recibe la instantánea por POST firmado | No hay que guardar una credencial de hosting en el PC; la casa solo sale, nada entra | SFTP con la contraseña del hosting: da acceso a todo el sitio |