A symlinked `~/.codex` or `~/.claude` turned back into a real directory
Source: Troubleshooting reference
Symptom: you hand-symlinked ~/.codex (or ~/.claude) to scratch, and some time
later it is a plain directory again holding only the managed config — while the
scratch copy sits frozen at the date the link died. Nothing logged an error.
Root cause: chezmoi manages files inside both directories (config.toml,
AGENTS.md, hooks.json, profiles, rules/, themes/, agents/ for Codex;
settings.json, skills/, hook scripts for Claude). A source directory means
chezmoi’s target state for that path is “directory” — so on the next chezmoi apply
it removes whatever is there, symlink included, and recreates a real directory with
just the managed files. Everything else is orphaned wherever the link pointed.
Confirm — a stale target next to a fresh $HOME copy is the tell:
chezmoi managed | grep -x '.codex' # non-empty ⇒ chezmoi owns this pathstat -c '%n %y' ~/.codex ~/scratch/.codex # scratch frozen, home currentFix: don’t symlink the managed directory. For Codex on a shared home,
configure a host-local runtime and run bash install/codex.sh sync-runtime.
The scratch installer no longer moves Codex children or SQLite files. For
Claude, it still supports selected unmanaged children. See
Scratch space.
Then reconcile the orphaned copy by hand — the script won’t touch it, because it cannot tell your stale data from a deliberate second install:
du -sh ~/scratch/.codex # what was orphanedThe supported CODEX_HOME boundary now includes managed-configuration sync;
see Codex host-local state.