# Laptop Auto-Sync Setup
## Current Status
**MacBook laptop is NOT auto-syncing** (as of Feb 23, 2026)
### What's Currently Configured
**Desktop (iMac)** - FULL AUTO-SYNC ✓
- Config: Git repo with hourly auto-commit/push via launchd
- Sessions: `~/.claude/projects/` symlinked to iCloud (auto-sync)
**Laptop (MacBook)** - MANUAL ONLY ⚠️
- Config: Git repo exists, but NO auto-push (receive-only)
- Can manually push/pull
- Last synced: Feb 23, 2026 (14:00)
- Sessions: `~/.claude/projects/` is a **regular directory**, NOT symlinked to iCloud
- Sessions created on laptop stay LOCAL
- Sessions from desktop DON'T sync to laptop
### What This Means
**If you create a new skill on laptop:**
- ❌ Will NOT auto-push to GitHub
- ❌ Will NOT appear on desktop automatically
- ✓ Can manually push with: `cd ~/.claude && git add -A && git commit -m "sync" && git push origin main`
**If you have a conversation on laptop:**
- ❌ Session transcript stays LOCAL (projects/ is not synced)
- ❌ Desktop will NOT see this conversation
**If you have a conversation on desktop:**
- ✓ Desktop auto-pushes config to GitHub
- ✓ Desktop auto-syncs sessions to iCloud
- ❌ Laptop won't see changes unless you manually `git pull` or set up iCloud symlink
---
## Setup Requirements
To enable auto-sync on laptop (matching desktop setup), need:
### 1. Directories
```bash
mkdir -p ~/.local/bin
mkdir -p ~/.local/state/claude-config-sync
```
### 2. Sync Script
Create `~/.local/bin/claude-config-sync.sh` with:
- `git add -A` (with 50MB file size guard)
- `git commit -m "auto-sync"` (only if changes exist)
- `git pull --rebase` (after commit - critical order!)
- `git push origin main` (with proper error logging)
- Write timestamp to `last-successful-sync` marker
- Rotate logs at 500 lines
### 3. LaunchD Plist
Create `~/Library/LaunchAgents/com.claude.config-sync.plist`:
- Run every 3600 seconds (1 hour)
- Run at login
- Point to the sync script
- Log stdout/stderr to `~/.local/var/log/claude-config-sync-*.log`
### 4. Session Sync (iCloud)
Symlink projects folder:
```bash
ln -s "/Users/nickyoung/Library/Mobile Documents/com~apple~CloudDocs/claude-projects" ~/.claude/projects
```
### 5. Load and Test
```bash
launchctl load ~/Library/LaunchAgents/com.claude.config-sync.plist
launchctl start com.claude.config-sync
# Wait and verify it actually ran
tail ~/.local/state/claude-config-sync/sync.log
cat ~/.local/state/claude-config-sync/last-successful-sync
```
---
## Critical Lessons from Feb 2026 Incidents
See [[config-sync]] knowledge file for full incident history.
**Two silent failures in Feb 2026:**
1. **Feb 9**: 266 MB backup zip committed. Push errors swallowed by `2>/dev/null`. 28 commits accumulated locally over 4 weeks.
2. **Feb 17**: Script was pulling BEFORE committing. `git pull --rebase` fails when unstaged changes exist, causing abort. Errors logged hourly to `/tmp/` (cleared on reboot), but nobody read them.
**Fixes applied (must implement on laptop):**
- Commit FIRST, then pull, then push (order matters!)
- 50 MB file size guard (unstage large files automatically)
- Log to persistent location (`~/.local/state/`, not `/tmp/`)
- Write `last-successful-sync` marker file
- Health check in `/morning-review` (alerts if sync stale >6h)
---
## Testing Protocol
**Before trusting the automation:**
1. ✓ Create the files carefully (adapt from obsidian-backup pattern)
2. ✓ Run script manually to verify it works
3. ✓ Load launchd agent
4. ✓ Monitor for 24-48 hours:
- Check `~/.local/state/claude-config-sync/sync.log`
- Check `last-successful-sync` timestamp
- Verify commits appear on GitHub
- Check for errors: `grep ERROR sync.log`
5. ✓ Only then trust it
**Verification loop principle:** Every automated system must surface health status in an existing daily workflow. Don't rely on users checking logs.
---
## Related
- See `~/.claude/knowledge/config-sync.md` for complete architecture
- Desktop sync reference: `~/.claude/bin/backup-obsidian-vault.sh`
- Desktop plist reference: `~/.claude/bin/com.nickyoung.obsidian-backup.plist`