Skip to content

Drift

Drift is the byte-level difference between what’s currently in .claude/ and what the active profile’s source files would resolve to. Drift accrues when you (or a tool) edit files inside .claude/ directly instead of editing the profile source — the live tree pulls away from the canonical bytes.

C3P treats drift as a first-class signal. Two mechanisms surround it:

  1. The drift report — a read-only inspection produced by c3p drift and summarised in c3p status.
  2. The drift gate — a prompt or hard refusal that blocks c3p use and c3p sync when drift exists, so an unconscious swap can’t silently throw away your edits.

For each file in .claude/:

  1. Compute the resolved-and-merged bytes the active profile would produce.
  2. Compare to the bytes on disk.
  3. If they differ, mark the file as drifted; record the contributing profile in the drift report.

The check is read-only and never writes to disk.

When a swap is requested:

Drift stateInteractive (TTY)Non-interactive (CI)
No driftSwap proceeds.Swap proceeds.
Drift presentPrompt: discard / persist / abort.Refuses with exit 1 unless --on-drift=<choice> is passed.

The three choices:

  • discard — drop the drifted edits; resolve the active profile fresh and overwrite.
  • persist — write the drifted bytes back into the active profile’s source tree first, then proceed with the swap so nothing is lost.
  • abort — make no change.

The non-TTY refusal is intentional: a CI script that doesn’t pass --on-drift would otherwise hang on a hidden prompt.

Drift is not the same as a stale source. Stale source means the active profile’s source bytes have changed (e.g. via git pull) and .claude/ hasn’t picked them up yet — fixed by c3p sync. Drift means the live tree was edited directly. Status surfaces both as distinct signals.