Skip to content

Syncing Scratchpad Notes Across Machines

ctx

The Problem

You work from multiple machines: a desktop and a laptop, or a local machine and a remote dev server.

The scratchpad entries are encrypted. The ciphertext (.context/scratchpad.enc) travels with git, but the encryption key lives outside the project at ~/.ctx/.ctx.key and is never committed. Without the key on each machine, you cannot read or write entries.

How do you distribute the key and keep the scratchpad in sync?

TL;DR

ctx init                                                  # 1. generates key
scp ~/.ctx/.ctx.key user@machine-b:~/.ctx/.ctx.key        # 2. copy key
chmod 600 ~/.ctx/.ctx.key                                 # 3. secure it
# Normal git push/pull syncs the encrypted scratchpad.enc
# On conflict: ctx pad resolve → rebuild → git add + commit

Finding Your Key File

The key is always at ~/.ctx/.ctx.key — one key, one machine.

Treat the Key Like a Password

The scratchpad key is the only thing protecting your encrypted entries.

Store a backup in a secure enclave such as a password manager, and treat it with the same care you would give passwords, certificates, or API tokens.

Anyone with the key can decrypt every scratchpad entry.

Commands and Skills Used

Tool Type Purpose
ctx init CLI command Initialize context (generates the key automatically)
ctx pad add CLI command Add a scratchpad entry
ctx pad rm CLI command Remove a scratchpad entry
ctx pad edit CLI command Edit a scratchpad entry
ctx pad resolve CLI command Show both sides of a merge conflict
ctx pad merge CLI command Merge entries from other scratchpad files
ctx pad import CLI command Bulk-import lines from a file
ctx pad export CLI command Export blob entries to a directory
scp Shell Copy the key file between machines
git push / git pull Shell Sync the encrypted file via git
/ctx-pad Skill Natural language interface to pad commands

The Workflow

Step 1: Initialize on Machine A

Run ctx init on your first machine. The key is created automatically at ~/.ctx/.ctx.key:

ctx init
# ...
# Created ~/.ctx/.ctx.key (0600)
# Created .context/scratchpad.enc

The key lives outside the project directory and is never committed. The .enc file is tracked in git.

Key Folder Change (v0.7.0+)

If you built ctx from source or upgraded past v0.6.0, the key location changed to ~/.ctx/.ctx.key. Check these legacy folders and copy your key manually:

# Old locations (pick whichever exists)
ls ~/.local/ctx/keys/        # pre-v0.7.0 user-level
ls .context/.ctx.key         # pre-v0.6.0 project-local

# Copy to the new location
mkdir -p ~/.ctx && chmod 700 ~/.ctx
cp <old-key-path> ~/.ctx/.ctx.key
chmod 600 ~/.ctx/.ctx.key

Step 2: Copy the Key to Machine B

Use any secure transfer method. The key is always at ~/.ctx/.ctx.key:

# scp — create the target directory first
ssh user@machine-b "mkdir -p ~/.ctx && chmod 700 ~/.ctx"
scp ~/.ctx/.ctx.key user@machine-b:~/.ctx/.ctx.key

# Or use a password manager, USB drive, etc.

Set permissions on Machine B:

chmod 600 ~/.ctx/.ctx.key

Secure the Transfer

The key is a raw 256-bit AES key. Anyone with the key can decrypt the scratchpad. Use an encrypted channel (SSH, password manager, vault).

Never paste it in plaintext over email or chat.

Step 3: Normal Push/Pull Workflow

The encrypted file is committed, so standard git sync works:

# Machine A: add entries and push
ctx pad add "staging API key: sk-test-abc123"
git add .context/scratchpad.enc
git commit -m "Update scratchpad"
git push

# Machine B: pull and read
git pull
ctx pad
#   1. staging API key: sk-test-abc123

Both machines have the same key, so both can decrypt the same .enc file.

Step 4: Read and Write from Either Machine

Once the key is distributed, all ctx pad commands work identically on both machines. Entries added on Machine A are visible on Machine B after a git pull, and vice versa.

Step 5: Handle Merge Conflicts

If both machines add entries between syncs, pulling will create a merge conflict on .context/scratchpad.enc. Git cannot merge binary (encrypted) content automatically.

The fastest approach is ctx pad merge: It reads both conflict sides, deduplicates, and writes the union:

# Extract theirs to a temp file, then merge it in
git show :3:.context/scratchpad.enc > /tmp/theirs.enc
git checkout --ours .context/scratchpad.enc
ctx pad merge /tmp/theirs.enc

# Done: Commit the resolved scratchpad:
git add .context/scratchpad.enc
git commit -m "Resolve scratchpad merge conflict"

Alternatively, use ctx pad resolve to inspect both sides manually:

ctx pad resolve
# === Ours (this machine) ===
#   1. staging API key: sk-test-abc123
#   2. check DNS after deploy
#
# === Theirs (incoming) ===
#   1. staging API key: sk-test-abc123
#   2. new endpoint: api.example.com/v2

Then reconstruct the merged scratchpad:

# Start fresh with all entries from both sides
ctx pad add "staging API key: sk-test-abc123"
ctx pad add "check DNS after deploy"
ctx pad add "new endpoint: api.example.com/v2"

# Mark the conflict resolved
git add .context/scratchpad.enc
git commit -m "Resolve scratchpad merge conflict"

Merge Conflict Walkthrough

Here's a full scenario showing how conflicts arise and how to resolve them:

1. Both machines start in sync (1 entry):

Machine A: 1. staging API key: sk-test-abc123
Machine B: 1. staging API key: sk-test-abc123

2. Both add entries independently:

Machine A adds: "check DNS after deploy"
Machine B adds: "new endpoint: api.example.com/v2"

3. Machine A pushes first. Machine B pulls and gets a conflict:

git pull
# CONFLICT (content): Merge conflict in .context/scratchpad.enc

4. Machine B runs ctx pad resolve:

ctx pad resolve
# === Ours ===
#   1. staging API key: sk-test-abc123
#   2. new endpoint: api.example.com/v2
#
# === Theirs ===
#   1. staging API key: sk-test-abc123
#   2. check DNS after deploy

5. Rebuild with entries from both sides and commit:

# Clear and rebuild (or use the skill to guide you)
ctx pad add "staging API key: sk-test-abc123"
ctx pad add "check DNS after deploy"
ctx pad add "new endpoint: api.example.com/v2"

git add .context/scratchpad.enc
git commit -m "Merge scratchpad: keep entries from both machines"

Conversational Approach

When working with an AI assistant, you can resolve conflicts naturally:

You: "I have a scratchpad merge conflict. Can you resolve it?"

Agent: "Let me extract theirs and merge it in."
       [runs git show :3:.context/scratchpad.enc > /tmp/theirs.enc]
       [runs git checkout --ours .context/scratchpad.enc]
       [runs ctx pad merge /tmp/theirs.enc]
       "Merged 2 new entries (1 duplicate skipped). Want me to
       commit the resolution?"

Tips

  • Back up the key: If you lose it, you lose access to all encrypted entries. Store a copy in your password manager.
  • One key per project: Each ctx init generates a unique key. Don't reuse keys across projects.
  • Keys work in worktrees: Because the key lives at ~/.ctx/.ctx.key (outside the project), git worktrees on the same machine share the key automatically. No special setup needed.
  • Plaintext fallback for non-sensitive projects: If encryption adds friction and you have nothing sensitive, set scratchpad_encrypt: false in .ctxrc. Merge conflicts become trivial text merges.
  • Never commit the key: The key is stored outside the project at ~/.ctx/.ctx.key and should never be copied into the repository.

Next Up

Hook Output Patterns →: Choose the right output pattern for your Claude Code hooks.

See Also