What happens
scripts/claude-sync writes a timestamped .bak-<ts> copy whenever a context's
settings.json or CLAUDE.md differs from what it is about to write, and
nothing ever removes them. 26 had accumulated across the three contexts by
2026-08-23 — from roughly one day of iterating on the fragments. Purged by hand
today; that is not a fix.
Two separate problems
1. Most backups are spurious. The drift check is a byte comparison
(diff -q), but Claude Code rewrites settings.json continuously and reorders
its keys as it goes. So a context that is semantically identical to the repo
still trips the check and produces a backup on every single sync. Confirmed on
~/.claude-exxo-personal: the "drift" was purely key order.
Fix: compare semantically before deciding anything drifted — jq -S (or
jq -cS) on both sides for JSON, so reordering alone never triggers a backup.
The .mcpServers merge added on 2026-08-23 already does exactly this, and for
exactly this reason — the settings path should follow it.
2. Real backups still need a retention policy. Even with (1) fixed,
genuine drift will still produce backups, and they are worth keeping: they are
the only record of a hand-edit that a sync overwrote. So retention should not
be zero. Options, roughly in order of preference:
- prune on write, keeping the N most recent per file (N=3?);
- an age cutoff (anything older than ~14 days);
- an explicit
claude-sync --prune-backups, which is the least useful because
it only works if someone remembers to run it — the same failure mode that
let 26 pile up.
Why it matters beyond tidiness
settings.json carries no secrets today, so these are harmless clutter. But the
backup mechanism is generic, and the neighbouring .claude.json does hold
live bearer tokens — which is precisely why the MCP merge was written to never
produce a .bak at all. Anything that later extends backups to that file would
be scattering timestamped copies of credentials around $HOME. Worth writing
the retention rule down before that question comes up rather than after.
Context
Fell out of #44 (repo-managed MCP servers + vendored Mantine materials), where
a single claude-sync run produced five more backups, all verified to be strict
subsets of what replaced them.
What happens
scripts/claude-syncwrites a timestamped.bak-<ts>copy whenever a context'ssettings.jsonorCLAUDE.mddiffers from what it is about to write, andnothing ever removes them. 26 had accumulated across the three contexts by
2026-08-23 — from roughly one day of iterating on the fragments. Purged by hand
today; that is not a fix.
Two separate problems
1. Most backups are spurious. The drift check is a byte comparison
(
diff -q), but Claude Code rewritessettings.jsoncontinuously and reordersits keys as it goes. So a context that is semantically identical to the repo
still trips the check and produces a backup on every single sync. Confirmed on
~/.claude-exxo-personal: the "drift" was purely key order.Fix: compare semantically before deciding anything drifted —
jq -S(orjq -cS) on both sides for JSON, so reordering alone never triggers a backup.The
.mcpServersmerge added on 2026-08-23 already does exactly this, and forexactly this reason — the settings path should follow it.
2. Real backups still need a retention policy. Even with (1) fixed,
genuine drift will still produce backups, and they are worth keeping: they are
the only record of a hand-edit that a sync overwrote. So retention should not
be zero. Options, roughly in order of preference:
claude-sync --prune-backups, which is the least useful becauseit only works if someone remembers to run it — the same failure mode that
let 26 pile up.
Why it matters beyond tidiness
settings.jsoncarries no secrets today, so these are harmless clutter. But thebackup mechanism is generic, and the neighbouring
.claude.jsondoes holdlive bearer tokens — which is precisely why the MCP merge was written to never
produce a
.bakat all. Anything that later extends backups to that file wouldbe scattering timestamped copies of credentials around
$HOME. Worth writingthe retention rule down before that question comes up rather than after.
Context
Fell out of #44 (repo-managed MCP servers + vendored Mantine materials), where
a single
claude-syncrun produced five more backups, all verified to be strictsubsets of what replaced them.