dmesg --follow
[ 66934380.000 ] posts.x: Full talk on the three brakes for PR review, from tautological tests to a retro skill that compounds:  |   [ 66934380.000 ] posts.x: More AI generated code doesn't automatically mean more throughput, it just means more PRs nobody has time to review. @mattpocockuk, Director at AI…  |   [ 66925620.000 ] posts.x: Full talk on distilling loops into versioned agent recipes, and measuring them by valued work per watt:  |   [ 66925620.000 ] posts.x: A guy named AJ once built a bot that went on Reddit for car prices and inventory, then put dealers head to head to outbid each other. That's the…  |   [ 66881460.000 ] posts.x: Full talk on how to build an LLM recommender that's bilingual in English and semantic IDs, and why that makes feeds more token-efficient than chat…  |   [ 66881460.000 ] posts.x: Recommendation systems follow the same power law scaling curve as large language models, and the field is still early on it. @devanshtandon_, a…  |   [ 66862560.000 ] posts.x: Full talk on Spotify's generative personalization system, the NEO training recipe behind it, and how they grounded their LLM judges:  |   [ 66862560.000 ] posts.x: One in four US Premium subscribers on Spotify interact with its recommendation system every day. "Teaching LLMs to Speak Spotify" is @moustaki and…  |   [ 66854760.000 ] posts.x: Full talk on Numalab, the gesture system built to give a shape display its own body language:  |   [ 66854760.000 ] posts.x: An AI's first spontaneous act, given a body instead of a chat window, was to breathe. @cyrusclarke, a researcher at MIT Media Lab, gave it that body…  |   [ 66842160.000 ] posts.x: Full talk on the six month cutoff gap and what it takes to get a coding agent to actually check its blind spots:  |   [ 66842160.000 ] posts.x: Most models are already stale the day they ship: Exa's own graph shows roughly a six month gap between a model's knowledge cutoff and its release…  |   [ 66837480.000 ] posts.x: Listened to this episode of @FoundersPodcast this morning. As is so frequently the case, immediately bought the book after finishing the episode. Ari…  |   [ 66834900.000 ] posts.x: @GeoffreyHuntley Yeah, that seems low to me.  |  
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