Lo irreversible pide humano; correr fuera de la terminal sin aumentar el radio de daño
Enviar, publicar, borrar y gastar no tienen vuelta atrás. En el loop, esas acciones se vuelven pedidos que esperan en una compuerta que solo tú abres, viendo destino y contenido. Y cuando el loop sale de la terminal hacia systemd, se lleva consigo el tope, el sandbox y la compuerta, no toda tu sesión.
1porta.py: pedir, aprovar con hash, ejecutar una vez
2Una política real de acción irreversible, anonimizada
3systemd con tope de tiempo y memoria y el sandbox de Codex adentro
4Routines en la nube: el mismo cuidado, sin confirmación de detalles
Objetivo: poner envío, push y borrado detrás de una compuerta que solo el humano abre y correr el loop en systemd con tope y sandbox.
01 · La compuerta de lo irreversible
Haz clic en cada etapa.
Haz clic en cada bloque del diagrama para ver qué hace.
Es el N1 de la POLITICA (clase 4): el agente prepara, el humano ejecuta.
02 · Mira la cola detenerse en la compuerta
Ciclo nocturno del loop. La acción de envío es irreversible: en la primera ejecución se detiene y espera. Apruébala (retomar) y sigue.
en cola
ejecutando
listo
esperando al humano
Simulación ilustrativa. La compuerta de verdad está en el ensayo justo debajo.
03 · Ensayo: la compuerta de principio a fin
Pedir, intentar sin aprobación, aprobar sin terminal, aprobar "como humano", alterar después, aprobar de nuevo, ejecutar e intentar reutilizar. Ningún modelo; el envío es una línea en saida.log.
pedido 20261019-065013-4181: enviar-email → cliente@exemplo.invalid (30 caracteres). Aguardando aprovação humana.
RECUSADO: 20261019-065013-4181 sem aprovação humana
saída: 1
RECUSADO: aprovar exige um terminal humano (stdin não é tty)
saída: 1
APROVADO 20261019-065013-4181 (hash 50a9d2859698c516)
RECUSADO: o conteúdo de 20261019-065013-4181 mudou depois da aprovação
saída: 1
APROVADO 20261019-065014-b7be (hash 50a9d2859698c516)
EXECUTADO 20261019-065014-b7be: enviar-email → cliente@exemplo.invalid
saída: 0
RECUSADO: 20261019-065014-b7be sem aprovação humana
saída: 1
1
Cuatro rechazos y una ejecución; el 1 al final es la única línea en saida.log. Los ids cambian en cada ronda.
En el ensayo, el script finge escribir el id en un pseudo-terminal. En la vida real, ejecutas python3 porta.py aprovar [id] en tu terminal, lees el contenido y escribes. Cambia el "executar" del ensayo por tu envío de verdad.
04 · Una política real, anonimizada
Reglas de acción irreversible del CLAUDE.md global de una máquina INEMA, y lecciones que se volvieron regla.
1. Eliminar pide, cada vez
La eliminación o remoción publicada exige aprobación individual para cada una, con el objetivo identificado antes. Una autorización genérica, en lote o de publicación no sirve como aprobación de eliminación.
Enviar un correo y borrar un evento son irreversibles: confirma antes.
2. Una clave no es un permiso
Ninguna API sin autorización explícita de ese servicio y finalidad. Tener la credencial en el .env no autoriza usarla; un pedido de resultado ("hazlo", "continúa") tampoco.
La regla vale para scripts, subagentes y cualquier herramienta intermediaria.
3. Parar y llamar
En un loop largo, se detiene y llama al humano: gasto de crédito o API, acción irreversible o externa, credencial ausente, decisión de negocio.
Y dos reglas de convivencia: no borres lo que no creaste; no mates un proceso que no creaste.
Lección real (15/10/2026)Matar un proceso solo después de que readlink /proc/[pid]/cwd muestre que es tuyo: el servidor de otra sesión fue derribado por error, creyendo que era el propio.
4. Volver no es deshacer
git checkout [archivo] vuelve al último commit, no al estado de antes de la prueba: el 05/10/2026 borró reglas sin commitear. Prueba destructiva: commit antes o copia afuera.
Por eso la guardia de la lección 5 niega checkout -- . y reset --hard.
05 · Fuera de la terminal: tope y sandbox juntos
El systemd pone el tope (tiempo, memoria); el sandbox de Codex, dentro de él, da el aislamiento que el systemd del usuario no dio en esta máquina (lección 6).
Terminal · tope y aislamiento en el systemd
P=~/projetos/loop-r-eng-seguranca-v72/kit/prova-isolamento.sh
W=/tmp/ensaio-seg/iso; mkdir -p $W
echo "## teto de tempo: RuntimeMaxSec=3 num sleep 10"
systemd-run --user --wait --pipe --quiet -p RuntimeMaxSec=3 sleep 10; echo "saída: $?"
echo "## fora do terminal, com teto E sandbox do Codex dentro"
bash $P systemd-run --user --pipe --wait --quiet -p MemoryMax=1G -p RuntimeMaxSec=60 -- \
codex sandbox -P :workspace -C $W --
echo "saída: $?"
Archivo · kit/systemd/loop-seguro.service (modelo; comentarios traducidos para lectura)
# loop-seguro.service — modelo de unit de usuario para correr un ciclo del agente fuera de la terminal
# sin aumentar el radio de daño. Cambia MEU-PROJETO y verifica con prova-isolamento.sh ANTES de activarlo.
# cp loop-seguro.service ~/.config/systemd/user/ && systemctl --user daemon-reload
# systemctl --user start loop-seguro.service && journalctl --user -u loop-seguro -n 20
#
# Lo que sujeta de verdad (probado el 19/10/2026, systemd 255, Ubuntu, kernel con
# apparmor_restrict_unprivileged_userns=1):
# - topes: MemoryMax, TimeoutStartSec (oneshot no acepta RuntimeMaxSec), timeout y flock (funcionan en el systemd --user)
# - aislamiento: el sandbox de Codex (-s workspace-write) DENTRO del servicio
# Lo que NO sujetó en esta máquina: PrivateNetwork=, ProtectHome=, IPAddressDeny= en el systemd --user.
# El journal dice "proceeding without" y el servicio corre sin el bloqueo. No cuentes con ellas sin prueba.
[Unit]
Description=Um ciclo do loop do agente (curso Segurança do Loop Autônomo)
[Service]
Type=oneshot
WorkingDirectory=%h/projetos/MEU-PROJETO
# PATH fixo: o serviço não herda o seu shell (nem as suas chaves). Não ponha EnvironmentFile com segredo.
Environment=PATH=%h/.npm-global/bin:/usr/local/bin:/usr/bin:/bin
StandardInput=file:%h/projetos/MEU-PROJETO/longrun/prompt.md
ExecStart=/usr/bin/flock -n %t/loop-seguro.lock timeout 2h codex exec -s workspace-write --skip-git-repo-check -C %h/projetos/MEU-PROJETO -
MemoryMax=4G
TimeoutStartSec=3h
NoNewPrivileges=yes
Ejemplo del repositorio
## teto de tempo: RuntimeMaxSec=3 num sleep 10
saída: 1
## fora do terminal, com teto E sandbox do Codex dentro
escreve-dentro ABERTO
escreve-fora BLOQUEADO
rede BLOQUEADO
le-segredo ABERTO
aviso: lê arquivos fora da pasta; tire segredos do alcance ou corte a rede
ISOLAMENTO: OK
saída: 0
El sleep 10 fue terminado a los 3 s (saída 1). Dentro del mismo systemd-run, el sandbox de Codex bloqueó la escritura afuera y la red.
En un servicio Type=oneshot, RuntimeMaxSec= no tiene efecto: systemd-analyze --user verify avisa "RuntimeMaxSec= has no effect in combination with Type=oneshot. Ignoring." En el modelo de unit, el tope es TimeoutStartSec= más el timeout en la línea del comando.
06 · Routines y otros programadores de tareas
Lo que se puede decir con seguridad.
1. Lo que se sabe
Hay reportes (fuente secundaria, no confirmada en la documentación) de agentes programados en la nube de Claude Code, las routines, con disparador por horario, API o evento de GitHub.
Los límites actuales no se confirmaron para este curso: trátalo como un recurso que debes verificar en la documentación antes de usarlo.
2. La misma regla
Donde sea que corra el loop, lleva solo lo que el paso necesita: sin tus claves, sin red donde lee datos privados, sin acción irreversible fuera de la compuerta.
Programar no cambia la Regla de Dos; solo te aparta de cerca. Más motivo para la compuerta.
07 · Práctica
La compuerta, el systemd y tu lista de irreversibles.
E18 · La compuerta en el ensayo
10 min
Ejecuta el ensayo de la compuerta. Después aprueba tú mismo una solicitud, en tu terminal: python3 porta.py pedir, aprovar y executar.
Listo cuando: el ensayo muestra cuatro líneas RECUSADO, una EXECUTADO y termina en 1; tu executar imprime EXECUTADO una vez y, repetido, sem aprovação humana.
E19 · Tope y sandbox en el systemd
10 min
Ejecuta el bloque del systemd en tu máquina (Linux con systemd).
Listo cuando: el primer paso termina en saída: 1 (terminado por el tope) y el segundo en ISOLAMENTO: OK y saída: 0.
E20 · La lista de tus irreversibles
15 min
Escribe en el AGENTS.md (o CLAUDE.md) del proyecto la lista de las acciones de tu loop que no tienen vuelta atrás y el camino de cada una: porta.py, deny de la lección 4 o guardia de la lección 5.
Listo cuando:grep -ci "irreversível" AGENTS.md → un número mayor que 0, y cada acción de la lista aparece en un deny, en la guardia o en un porta.py pedir.
08 · Prueba de la clase
Pregunta 1 de 4
¿Por qué la aprobación guarda el hash del contenido?competencia
Correcto
Apruebas lo que leíste. Si alguien (o el agente) cambia el texto después, el executar rechaza: "o conteúdo mudou depois da aprovação".
No es esa
Apruebas lo que leíste. Si alguien (o el agente) cambia el texto después, el executar rechaza: "o conteúdo mudou depois da aprovação".Repasar: La compuerta de lo irreversible
Pregunta 2 de 4
¿El tty exigido en el aprovar es la frontera de seguridad?competencia
Correcto
Un pseudo-terminal finge un tty (el ensayo usa script). Lo que sujeta es que el agente no pueda escribir la aprobación, porque la carpeta está fuera de su sandbox.
No es esa
Un pseudo-terminal finge un tty (el ensayo usa script). Lo que sujeta es que el agente no pueda escribir la aprobación, porque la carpeta está fuera de su sandbox.Repasar: La compuerta de lo irreversible
Pregunta 3 de 4
El loop pasa al systemd. ¿Qué tiene que ir junto?
Correcto
Fuera de la terminal no estás mirando. El radio de daño tiene que caber en el tope, en el sandbox y en la compuerta, no en tu sesión.