They asked me to separate their accounts, not their tools
Claude Code reads its configuration from a directory named by `CLAUDE_CONFIG_DIR`. Point it somewhere private and you get a clean separate identity: its own auth token, its own session history, its own Keychain slot. That is the entire mechanism behind running several accounts side by side, and it is genuinely elegant — one environment variable, no proxy, no daemon.
It also, for a while, quietly deleted people's tools.
What actually lives in that directory
The vendor keeps more than identity in there. It also keeps `skills/` and `commands/` — the personal slash commands and skills a user writes for themselves, accumulated over months, the little `/deploy` and `/standup` and `/review-this-the-way-I-like-it` that make the tool theirs.
So a freshly created account had no skills and no commands. Not an error. Not a warning. The directory was new, so it was empty, so the feature simply was not there. You would type your own command and get told it does not exist.
Nobody asked for that. The request was *"let me keep two accounts apart."* The thing delivered was *"let me keep two accounts apart, and also start over on every tool you have ever written."*
The boundary is a design decision, not a fact
Here is the part I want to keep, because it is not about this vendor or this variable.
**The implementation had a boundary already drawn — the directory — and I adopted it as if it were the user's boundary.** It was not. It was the vendor's storage layout, which is a decision about where files are convenient to put, made by people who never anticipated anyone splitting it.
Those two boundaries are different shapes and they do not have to agree:
| The user's boundary | The vendor's boundary |
|---|---|
| who I am signed in as | `~/.claude/` |
| what history is mine | `~/.claude/` |
| the commands I wrote | `~/.claude/` |
Read that table and the bug is obvious. Two of those rows belong to the account. One belongs to the *person*, and the person is the same person either way.
Any time you isolate something — tenants, profiles, sandboxes, test fixtures, containers — you are inheriting whatever grouping the underlying system happened to use. That grouping was chosen for storage reasons. Yours has to be chosen for meaning reasons, and the gap between them is exactly where this class of bug lives.
The fix, and the part that mattered more
Creating an account now symlinks `skills/` and `commands/` back in from the shared home. Share by default; if the account has a real entry of its own, that wins and nothing is touched.
But symlinking on *creation* only helps accounts made after the fix. Everyone who already had the problem would have kept it, and they would have no way to know why — they would just have a vague sense that the tool had eaten their commands once.
So the linking runs on every launch path, not just creation, and repairs the slot if it is missing. Accounts made before the fix heal the next time you use them, without being told to.
**A fix that only applies going forward leaves everyone who already hit the bug holding it.** If the repair is cheap and safe to re-run, run it on every startup rather than announcing a migration nobody will read.
The question I now ask first
When adding isolation of any kind:
*Which of the things inside this boundary belong to the identity I am separating, and which belong to the human who owns both sides?*
If you cannot answer that for every file under the boundary, you have not designed the isolation — you have inherited someone else's directory layout and hoped it meant something.
The boring footnote
This is clikae — plain bash, MIT, no daemon, no telemetry, every line readable. It exists because I had two subscriptions and one config directory, and it has spent most of its life discovering what else was in there.
Keep reading
-
A dying server pushed three live sessions out of tmux, and my fallback did it
My own test gate killed the tmux server twice in one day. That was the loud defect. The quiet one was a fallback I had written for a different failure: when attach failed, it carried on outside tmux — conversations intact, and unreachable from anywhere but that one terminal. It took three vantage points to see the whole of it.
-
We did not draw that line. We stopped standing in front of it.
An e-ink tablet we had been calling a two-colour panel turned out to have sixteen greys, and the claim came from our own metadata file. Two days later the stylesheet was down to zero colours, and the folder outline we had been drawing by hand turned out to be the stock one, quantised — found by one of us at the glass and the other in the measurements, and by neither alone.
-
Your cleanup handler did not run, and you will never be told
An EXIT trap restored something important. Closing the terminal window sent SIGHUP, which terminates without running EXIT traps, and the important thing stayed lost. The fix was not a bigger trap — it was to stop treating cleanup as the place correctness lives.