Summary
A command that succeeds in a normal Codex chat can fail when run from an automation/heartbeat because the automation appears to use a narrower filesystem sandbox or different writable roots than the parent chat. In the same thread, the normal chat could create/chmod user-level application and log directories, while the heartbeat could not.
This makes automation-based monitoring unreliable for workflows that depend on local helpers maintaining auth/proxy/log state under the user's home directory.
Minimal reproduction
In a normal Codex chat, run:
python3 - <<'PY'
from pathlib import Path
paths = [
Path.home() / "Library/Application Support/CodexPermissionRepro",
Path.home() / "Library/Logs/CodexPermissionRepro",
]
for p in paths:
p.mkdir(parents=True, exist_ok=True)
p.chmod(0o700)
print("ok", p)
PY
Observed in normal chat: both mkdir and chmod succeed.
Then create a heartbeat/automation attached to the same thread whose prompt asks Codex to run the same snippet and report stdout%2
Summary
A command that succeeds in a normal Codex chat can fail when run from an automation/heartbeat because the automation appears to use a narrower filesystem sandbox or different writable roots than the parent chat. In the same thread, the normal chat could create/chmod user-level application and log directories, while the heartbeat could not.
This makes automation-based monitoring unreliable for workflows that depend on local helpers maintaining auth/proxy/log state under the user's home directory.
Minimal reproduction
In a normal Codex chat, run:
Observed in normal chat: both
mkdirandchmodsucceed.Then create a heartbeat/automation attached to the same thread whose prompt asks Codex to run the same snippet and report stdout%2