Skip to content

feat(pimia): modo de sandbox intermedio «workspace-write + red» para los agentes Codex - #9

Closed
galeote wants to merge 3 commits into
mainfrom
claude/nice-ramanujan-29a296
Closed

galeote wants to merge 3 commits into
mainfrom
claude/nice-ramanujan-29a296

Conversation

@galeote

@galeote galeote commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

El problema

El adaptador ACP de Codex (@agentclientprotocol/codex-acp, hoy 1.1.9) ofrece tres modos cerrados y ninguno sirve para un agente gestionado:

Modo Sandbox Red Sirve
read-only readOnly no no puede trabajar
agent (por defecto) workspaceWrite no no llega al relay
agent-full-access dangerFullAccess sí sin sandbox ninguno

Un agente gestionado necesita las dos mitades: escritura confinada al workspace y salida a la red, porque habla con el relay a través del CLI buzz, que corre como subproceso sandboxeado. Hoy Honey está en agent-full-access — funciona, pero sin confinamiento y sin preguntar.

Por qué no se arregla configurando

El adaptador manda sandboxPolicy inline en cada turn/start, así que pisa cualquier configuración global: la inyección de CODEX_CONFIG en codex_network_env es letra muerta con este adaptador. Y la tabla AgentMode es privada del módulo, con getInitialAgentMode() resolviendo contra una lista cerrada de tres. No hay palanca de protocolo.

Lo que se descartó

  • Forkear o vendorizar el adaptador — es un bundle generado de ~31 000 líneas; meterlo en el repo es justo el error del deliverer vendorizado del que sale la política de docs/UPSTREAM.md.
  • Cambiarlo desde buzz-acp/escritorio — imposible: política inline por turno + lista de modos cerrada.
  • Parchear el bundle instalado — además de frágil, peligroso aquí: el prefijo npm gestionado es ~/Library/Application Support/Buzz/node-tools, con «Buzz» literal, o sea compartido con el Buzz real que el fundador usa a diario. Escribir ahí muta la instalación de otra aplicación.

Lo que hace este PR

Un lanzador propio en scripts/codex-sandbox/ que arranca el bundle sin modificar y gira el único campo que hace falta en el cable entre el adaptador y el app-server de Codex. Con INITIAL_AGENT_MODE=agent-workspace-network, el shim traduce el modo a agent y pone networkAccess: true en las políticas workspaceWrite que cruzan. Cualquier otro valor pasa intacto.

Dos propiedades que importan:

  • Solo se toca la red. readOnly y dangerFullAccess no se ensanchan nunca; de workspaceWrite no se mueven ni writableRoots ni approvalPolicy.
  • Falla hacia menos capacidad, nunca hacia menos confinamiento. Si no puede reescribir un frame, lo reenvía tal cual: el agente se queda sin red, nunca sin sandbox.

Comprobado

just codex-sandbox-test — 17 pruebas, dos de extremo a extremo con procesos hijo reales que verifican que el frame que llega al app-server lleva networkAccess: true con el modo puesto y false sin él.

Esa prueba ya pagó su precio: el primer intento enganchaba childProcess.spawn como propiedad del módulo, y el bundle hace import { spawn } from "node:child_process" — un binding con nombre que se fija al instanciar el módulo y que ese parche no alcanzaba jamás. De ahí el gancho en ChildProcess.prototype.spawn.

Contra el bundle real: ./scripts/codex-sandbox/codex-acp --version imprime @agentclientprotocol/codex-acp 1.1.9 (el sondeo de versión del escritorio sigue contento), y con un app-server falso en CODEX_PATH se confirmó que el gancho se instala sobre el hijo real y que los frames del adaptador auténtico atraviesan el reescritor intactos.

just desktop-check en verde.

Queda una comprobación viva pendiente: arrancar a Honey en el modo nuevo y confirmar contra el relay de verdad que el CLI buzz sale a la red y que una escritura fuera del workspace se deniega. Lo anterior prueba el mecanismo, no el resultado en producción.

Migrar a Honey

Instrucciones completas en docs/UPSTREAM.md. En corto: parar la agente, poner agent_command_override a la ruta absoluta del lanzador en el checkout principal y env_vars.INITIAL_AGENT_MODE a agent-workspace-network, arrancar y confirmar la línea del shim en su stderr.

Para volver atrás: quitar el override y dejar agent-full-access.

🤖 Generated with Claude Code

galeote added 3 commits August 9, 2026 23:35
…Codex

El adaptador @agentclientprotocol/codex-acp ofrece tres modos cerrados y
ninguno sirve para un agente gestionado: `agent` confina al workspace pero
deja al CLI buzz sin red, y `agent-full-access` da red quitando el sandbox
entero. Hoy Honey corre en full-access por eso.

No se puede resolver por configuración: el adaptador manda sandboxPolicy
inline en cada turn/start, así que codex_network_env (CODEX_CONFIG) es letra
muerta, y la tabla AgentMode es privada del módulo.

Se añade un lanzador propio que arranca el bundle sin modificar y pone
networkAccess:true en las políticas workspaceWrite que cruzan hacia el
app-server de Codex, seleccionable con INITIAL_AGENT_MODE=agent-workspace-network.

No se vendoriza ni se parchea el bundle: el prefijo npm gestionado se comparte
con el Buzz real instalado en la misma máquina.

Solo se toca la red — readOnly y dangerFullAccess no se ensanchan nunca, y de
workspaceWrite no se mueven writableRoots ni approvalPolicy. Si el shim no
puede reescribir un frame lo reenvía tal cual: se pierde capacidad, nunca
confinamiento.

Divergencia documentada en docs/UPSTREAM.md, con qué vigilar en cada
actualización del adaptador y cómo migrar a Honey.

Signed-off-by: Galeote <pablogaleote@gmail.com>
`just check` no lo ejecuta nadie en CI — el workflow llama a recetas sueltas
(`just desktop-check`, `just desktop-test`…), así que la receta añadida al
agregado `check` solo corría en local.

Se añade un job propio, modelado sobre `dead-token-guard`: ubuntu, hermit,
cinco minutos. Sin filtro de rutas a propósito: el shim se rompe desde fuera
—un cambio del adaptador npm o del protocolo del app-server de Codex— no
editando `scripts/`.

Signed-off-by: Galeote <pablogaleote@gmail.com>
Los agentes gestionados se lanzan con un PATH curado. Si `dirname` no está en
él, `SELF_DIR` quedaba vacío y el lanzador moría con un «missing shim» que
apunta al sitio equivocado, escondiendo la causa real.

Se resuelve con expansión de parámetros y builtins (`cd`, `pwd`), que no
dependen del PATH. El error que sale ahora es el verdadero.

Signed-off-by: Galeote <pablogaleote@gmail.com>
@galeote

galeote commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

Descartado por decisión del fundador (2026-08-09): en vez de mantener un modo de sandbox propio para codex, seguimos el camino de upstream — el merge de desktop-v0.5.8 (PR #10) toma el revert de block/buzz#4609, con lo que las escalaciones de codex se auto-aprueban y el modo agent por defecto vuelve a ser funcional sin lanzador propio. Gracias igualmente al trabajo de esta rama: queda como referencia si algún día volvemos a necesitar granularidad.

@galeote galeote closed this Aug 9, 2026
galeote added a commit that referenced this pull request Aug 9, 2026
Decisión final del fundador sobre el primer ciclo: upstream completo.
crates/buzz-acp pasa a la versión del tag (el arnés auto-aprueba
permisos desatendidos, default bypassPermissions) en lugar de defender
el rechazo. Se descartó además el modo de sandbox propio para codex
(PR #9 cerrado): INITIAL_AGENT_MODE deja de ser necesario. La entrada
del registro pasa de «rechazado el revert» a «tomado el revert», y la
receta de «El estado fuera del repo» se actualiza (permisos, sandbox
codex y smoke test).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Galeote <pablogaleote@gmail.com>
@galeote
galeote deleted the claude/nice-ramanujan-29a296 branch August 22, 2026 11:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant