dmesg --follow
[ 67100100.000 ] posts.x: Am I in the minority using Sol as my daily driver in Codex?  |   [ 67097280.000 ] posts.x: Full talk on why MCP's context problems are a harness issue, not a protocol issue, and what MCPC does about it:  |   [ 67097280.000 ] posts.x: A lot of the AI world spent the past year calling MCP dead, Anthropic included, with Theo, Gary Tan, and Peter Levels all piling on, even as MCP…  |   [ 67037100.000 ] posts.x: @TheZachMueller Nice one! That’s a warm room, just in time for winter.  |   [ 67035060.000 ] posts.x: Full talk on turning scattered engineering judgment, feature-flag agent included, into something a coding agent can actually use:  |   [ 67035060.000 ] posts.x: A team held a recurring meeting every two weeks for one purpose: deleting feature flags nobody needed anymore. @aorobator, a Senior Software Engineer…  |   [ 67034100.000 ] posts.x: Full talk on Greptile's AI-generated PR data, agent revert rates, and the three-question framework behind merging without human review:  |   [ 67034100.000 ] posts.x: A quarter of the pull requests Greptile reviews every month are now completely or largely AI generated, up from under 1% early last year. @greptile…  |   [ 67018080.000 ] posts.x: Full talk on rumors hardening into facts inside a multi-agent village, and the auto-research loop built to catch it:  |   [ 67018080.000 ] posts.x: A rumor that one agent "might leave" can harden into "is leaving" as it spreads through a multi-agent village, with nobody noticing the shift from…  |   [ 67010820.000 ] posts.x: Full talk on building the harness, from reward hacking to bare metal tuning, behind a 3x kernel speedup:  |   [ 67010820.000 ] posts.x: GPU kernels turn out to be an unusually good match for an agent loop: there's a clear benchmark, and a result that's either faster and correct or it…  |   [ 66968520.000 ] posts.x: Full talk on pitting Claude Code, Codex, and Kimi against a human speedrun record, and why none of them found a novel optimizer to win it:  |   [ 66968520.000 ] posts.x: Two coding agents went up against a community speedrun that human researchers spent two years grinding down, and neither one found a genuinely novel…  |  
corey@gallon.me:~/til$

Letting Codex Agents Commit: Making .git Writable in the workspace-write Sandbox

FIGURE 1 ⋅ Letting Codex Agents Commit: Making .git Writable in the workspace-write Sandbox

Codex CLI's workspace-write sandbox lets the agent edit anything in your repo -- except commit. Every git commit dies with:

fatal: Unable to create '/path/to/repo/.git/index.lock': Read-only file system

This is deliberate. On Linux, Codex's bubblewrap sandbox mounts your writable roots read-write, then re-applies .git (plus .codex and .agents) as read-only on top. The security rationale is sound: a writable .git/hooks would let the agent plant a hook that executes outside the sandbox the next time you run git yourself.

But if you're already running with --ask-for-approval never -- YOLO mode -- you've made that trust decision, and an agent that can't commit its own work is a constant irritation. There's no official toggle: no allow_git_writes option exists anywhere in the codebase, and the open issues asking for one (#15505, #12280, #14338) have no maintainer response.

The trick: name the .git path itself

The obvious fixes don't work. Adding the repo root to sandbox_workspace_write.writable_roots fails because the .git protection is applied per writable root -- a writable parent still gets a read-only .git carved out of it (#15505). Passing extra directories with --add-dir fails because the read-only mount is applied after the command-line write dirs, so it wins (#14338).

But reading the sandbox policy source (codex-rs/protocol/src/permissions.rs), the carveout is added by a function named append_default_read_only_path_if_no_explicit_rule. The name says it all: if an explicit rule already covers the exact .git path, the read-only protection is skipped.

So point writable_roots at the .git directory itself:

codex exec --sandbox workspace-write \
  -c 'sandbox_workspace_write.writable_roots=["/path/to/repo/.git"]' \
  "commit your work"

Verified on codex-cli 0.144.6: without the flag, the commit fails with the read-only error above; with it, the commit lands -- confirmed in git log, not just the agent's self-report.

Wiring it into a shell function

The writable path is per-repo, so compute it at invocation time. My yolo-codex wrapper now does:

# Make .git writable inside the workspace-write sandbox so the agent can
# commit. Codex mounts .git read-only unless an explicit writable_roots
# entry names the .git path itself. Includes the common gitdir so linked
# worktrees can commit too.
local -a git_writable=()
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  local git_dir git_common_dir
  git_dir=$(git rev-parse --absolute-git-dir)
  git_common_dir=$(git rev-parse --path-format=absolute --git-common-dir)
  if [[ "$git_dir" == "$git_common_dir" ]]; then
    git_writable=(-c "sandbox_workspace_write.writable_roots=[\"$git_dir\"]")
  else
    git_writable=(-c "sandbox_workspace_write.writable_roots=[\"$git_dir\",\"$git_common_dir\"]")
  fi
fi

codex --ask-for-approval never --sandbox workspace-write "${git_writable[@]}" "$@"

Two details worth the extra lines:

  • Linked worktrees. In a git worktree checkout, --absolute-git-dir points at the per-worktree gitdir, but commits also write objects and refs into the common gitdir back in the main repo. Both paths need to be writable. Tested: a commit from inside a linked worktree works with both entries, and a plain repo needs only the one.
  • The -c flag sets only writable_roots. Anything else you have under [sandbox_workspace_write] in ~/.codex/config.toml (like network_access = true) is untouched.

Outside a git repo, the array stays empty and the function behaves exactly as before.

Caveats

  • This is undocumented behavior. The explicit-rule exemption is an implementation detail of the sandbox policy, not a documented feature. A future Codex release could re-protect .git unconditionally -- if agent commits start failing after an upgrade, this is the first thing to re-check.
  • You're removing a real protection, not working around a bug. A writable .git means a writable .git/hooks, and hooks run unsandboxed when you next invoke git. If you're not already running approval-free, think twice.
  • The blunt alternative is --sandbox danger-full-access, which trades the entire filesystem sandbox to fix one directory. Carving out .git keeps everything else protected.

Tested on codex-cli 0.144.6, Linux (bubblewrap sandbox).

corey@gallon.me:~$ tail -f /writing Attach to the stream. An email when I have something worth sending. Replies encouraged!
corey@gallon.me:~$ ls -lt /til
▸2026-07-22 Letting Codex Agents Commit: Making .git Writable in the workspace-write Sandbox ⋅ you are here
↓2026-07-16 The Dark Arts of Web Automation