{"definition_raw":"---\nid: claude-sync\ntitle: Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)\nschedule: \"7,22,37,52 * * * *\"\ntimeout: 120\nretry: false\nenabled: true\nnotify_on: failure\nrun_as: shell\ncommand: \"( flock -n 200 || exit 0; cd /home/lucienne/.claude && git fetch --quiet origin && BRANCH=$(git rev-parse --abbrev-ref HEAD) && DIRTY=$(git status --porcelain -- skills/ rules/ vault/ agents/ hooks/); if [ \\\"$BRANCH\\\" = \\\"master\\\" ] && [ -z \\\"$DIRTY\\\" ]; then git merge --ff-only --quiet origin/master; else echo \\\"$(date -u +%FT%TZ) SKIP-FF: branch=$BRANCH dirty_lines=$(echo -n \\\"$DIRTY\\\" | wc -l)\\\"; fi; echo \\\"$(date -u +%FT%TZ) synced: $(ls /home/lucienne/.claude/skills/ | wc -l) skills, $(ls /home/lucienne/.claude/agents/ 2>/dev/null | wc -l) agents, $(ls /home/lucienne/.claude/hooks/ 2>/dev/null | wc -l) hooks (branch=$BRANCH)\\\" ) 200>/tmp/claude-sync.lock >> /home/lucienne/workspace/logs/claude-sync.log 2>&1\"\ntags: [infrastructure, claude, sync]\nruntime_profile: direct_shell\n---\n**OVERRIDES runtime profile:** uses `direct_shell` (plain shell, no model) because the command chain never invokes the `claude` CLI or any LLM API \u2014 pure-infra task; scheduler provider env injection is a no-op (MC-4942 U12 sweep).\n\nOne-way mirror from GitHub \u2192 Luci, non-destructive. **Phase 2 (MC-698): ~/.claude/ IS now the git checkout \u2014 no rsync bridge.** Mac is the only authoritative writer to `conrelma/claude`. Luci consumes (pulls master) and authors via autopush on Stop hook.\n\n## How it works\n\nEvery 15 min (7,22,37,52 offset to stagger from git-sync / cowork-sync):\n\n1. `flock` prevents concurrent runs.\n2. `cd ~/.claude && git fetch origin` \u2014 refresh remote refs.\n3. **Dirty-check ONLY on tracked-config paths** \u2014 `skills/ rules/ vault/ agents/ hooks/`. Other tracked paths (`.mcp.json`, `env/`, `google/`) may differ per-machine and are not considered \"dirty\" for sync purposes.\n4. **Conditional merge:**\n   - If on `master` AND the tracked-config paths are clean \u2192 `git merge --ff-only origin/master`. Fast-forwards Mac's commits in. Luci-specific modifications outside tracked paths survive (ff-merge doesn't touch them unless incoming commits explicitly modify those files).\n   - Otherwise \u2192 SKIP-FF, preserving Luci's in-progress feature branch work or concurrent edits.\n5. Log counts + branch.\n\n## Why only tracked-config paths matter for the dirty check\n\nAfter MC-698 Phase 2, Luci's `~/.claude/` has legitimate local-only state in tracked paths: her `.mcp.json` (different MCPs), `env/api_keys.env` (systemd variants), `google/` (Luci's own OAuth or empty). These show as `M` or `D` in `git status` but are NOT supposed to propagate to master \u2014 they're per-machine differences that haven't been untracked yet (follow-up work).\n\nAutopush is the authority on what flows to master. It stages ONLY `skills/ agents/ hooks/ rules/`. The sync's dirty check matches that scope \u2014 if nothing in those paths is modified, a fast-forward is safe even though other noise exists.\n\n## Luci authoring\n\nShe edits in `~/.claude/skills/`, `agents/`, etc. directly. On Stop hook, `luci_autopush.sh` commits + pushes to master. Mac pulls via session-start hook.\n\n## Related\n\n- MC-633 Phase 1: original sync setup\n- MC-698 Phase 2 (this): ~/.claude-repo/ bridge retired. ~/.claude/ is the git checkout.\n- MC-713: luci_autopush.sh (Stop hook auto-push)\n- Follow-up (not yet ticketed): untrack more per-machine paths (`.mcp.json`, `google/`, Luci-only `env/` files) to reduce git-status noise.\n","id":"claude-sync","last_run":{"duration_s":1.542341,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413861.log","output":"","started_at":"2026-06-13T06:07:00.552640+02:00","status":"completed"},"next_run":"2026-06-13 06:22","next_run_iso":"2026-06-13T06:22:00+02:00","runs":[{"duration_s":1.542341,"finished_at":"2026-06-13T06:07:02.100032+02:00","id":413861,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413861.log","output":"","started_at":"2026-06-13T06:07:00.552640+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.628432,"finished_at":"2026-06-13T05:52:02.194968+02:00","id":413808,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413808.log","output":"","started_at":"2026-06-13T05:52:00.561844+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.688003,"finished_at":"2026-06-13T05:37:02.242129+02:00","id":413769,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413769.log","output":"","started_at":"2026-06-13T05:37:00.549206+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.671133,"finished_at":"2026-06-13T05:22:02.197762+02:00","id":413724,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413724.log","output":"","started_at":"2026-06-13T05:22:00.521702+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.614717,"finished_at":"2026-06-13T05:07:02.174598+02:00","id":413685,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413685.log","output":"","started_at":"2026-06-13T05:07:00.555303+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.612169,"finished_at":"2026-06-13T04:52:02.147297+02:00","id":413638,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413638.log","output":"","started_at":"2026-06-13T04:52:00.530907+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.650035,"finished_at":"2026-06-13T04:37:02.180939+02:00","id":413598,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413598.log","output":"","started_at":"2026-06-13T04:37:00.527168+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.639618,"finished_at":"2026-06-13T04:22:02.202099+02:00","id":413551,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413551.log","output":"","started_at":"2026-06-13T04:22:00.557758+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.635943,"finished_at":"2026-06-13T04:07:02.177286+02:00","id":413510,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413510.log","output":"","started_at":"2026-06-13T04:07:00.531666+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.646173,"finished_at":"2026-06-13T03:52:02.202288+02:00","id":413461,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413461.log","output":"","started_at":"2026-06-13T03:52:00.551366+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.585882,"finished_at":"2026-06-13T03:37:02.163027+02:00","id":413421,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413421.log","output":"","started_at":"2026-06-13T03:37:00.572182+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.689575,"finished_at":"2026-06-13T03:22:02.245955+02:00","id":413374,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413374.log","output":"","started_at":"2026-06-13T03:22:00.551898+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.637768,"finished_at":"2026-06-13T03:07:01.979375+02:00","id":413335,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413335.log","output":"","started_at":"2026-06-13T03:07:00.336381+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.664861,"finished_at":"2026-06-13T02:52:02.198335+02:00","id":413282,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413282.log","output":"","started_at":"2026-06-13T02:52:00.528473+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.605459,"finished_at":"2026-06-13T02:37:02.173611+02:00","id":413243,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413243.log","output":"","started_at":"2026-06-13T02:37:00.565045+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.583876,"finished_at":"2026-06-13T02:22:02.166393+02:00","id":413197,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413197.log","output":"","started_at":"2026-06-13T02:22:00.578095+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.675139,"finished_at":"2026-06-13T02:07:02.210493+02:00","id":413158,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413158.log","output":"","started_at":"2026-06-13T02:07:00.530197+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.621218,"finished_at":"2026-06-13T01:52:02.167020+02:00","id":413107,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413107.log","output":"","started_at":"2026-06-13T01:52:00.541970+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.69267,"finished_at":"2026-06-13T01:37:02.284696+02:00","id":413068,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413068.log","output":"","started_at":"2026-06-13T01:37:00.587629+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"},{"duration_s":1.648752,"finished_at":"2026-06-13T01:22:02.202442+02:00","id":413023,"log_path":"/home/lucienne/workspace/logs/task-runs/claude-sync/413023.log","output":"","started_at":"2026-06-13T01:22:00.549652+02:00","status":"completed","task_id":"claude-sync","task_name":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"}],"runs_limit":20,"schedule":"7,22,37,52 * * * *","schedule_label":{"description":"Every hour at :07, :22, :37, :52","is_custom":false,"label":"Hourly","sort":2,"sort_time":""},"stats":{"avg_duration":1.6382205991379308,"completed":696,"failed":0,"timeout":0,"total":696},"task":{"_description":"**OVERRIDES runtime profile:** uses `direct_shell` (plain shell, no model) because the command chain never invokes the `claude` CLI or any LLM API \u2014 pure-infra task; scheduler provider env injection is a no-op (MC-4942 U12 sweep).\n\nOne-way mirror from GitHub \u2192 Luci, non-destructive. **Phase 2 (MC-698): ~/.claude/ IS now the git checkout \u2014 no rsync bridge.** Mac is the only authoritative writer to `conrelma/claude`. Luci consumes (pulls master) and authors via autopush on Stop hook.\n\n## How it works\n\nEvery 15 min (7,22,37,52 offset to stagger from git-sync / cowork-sync):\n\n1. `flock` prevents concurrent runs.\n2. `cd ~/.claude && git fetch origin` \u2014 refresh remote refs.\n3. **Dirty-check ONLY on tracked-config paths** \u2014 `skills/ rules/ vault/ agents/ hooks/`. Other tracked paths (`.mcp.json`, `env/`, `google/`) may differ per-machine and are not considered \"dirty\" for sync purposes.\n4. **Conditional merge:**\n   - If on `master` AND the tracked-config paths are clean \u2192 `git merge --ff-only origin/master`. Fast-forwards Mac's commits in. Luci-specific modifications outside tracked paths survive (ff-merge doesn't touch them unless incoming commits explicitly modify those files).\n   - Otherwise \u2192 SKIP-FF, preserving Luci's in-progress feature branch work or concurrent edits.\n5. Log counts + branch.\n\n## Why only tracked-config paths matter for the dirty check\n\nAfter MC-698 Phase 2, Luci's `~/.claude/` has legitimate local-only state in tracked paths: her `.mcp.json` (different MCPs), `env/api_keys.env` (systemd variants), `google/` (Luci's own OAuth or empty). These show as `M` or `D` in `git status` but are NOT supposed to propagate to master \u2014 they're per-machine differences that haven't been untracked yet (follow-up work).\n\nAutopush is the authority on what flows to master. It stages ONLY `skills/ agents/ hooks/ rules/`. The sync's dirty check matches that scope \u2014 if nothing in those paths is modified, a fast-forward is safe even though other noise exists.\n\n## Luci authoring\n\nShe edits in `~/.claude/skills/`, `agents/`, etc. directly. On Stop hook, `luci_autopush.sh` commits + pushes to master. Mac pulls via session-start hook.\n\n## Related\n\n- MC-633 Phase 1: original sync setup\n- MC-698 Phase 2 (this): ~/.claude-repo/ bridge retired. ~/.claude/ is the git checkout.\n- MC-713: luci_autopush.sh (Stop hook auto-push)\n- Follow-up (not yet ticketed): untrack more per-machine paths (`.mcp.json`, `google/`, Luci-only `env/` files) to reduce git-status noise.","_file":"claude-sync.md","_path":"/home/lucienne/workspace/tasks/claude-sync.md","command":"( flock -n 200 || exit 0; cd /home/lucienne/.claude && git fetch --quiet origin && BRANCH=$(git rev-parse --abbrev-ref HEAD) && DIRTY=$(git status --porcelain -- skills/ rules/ vault/ agents/ hooks/); if [ \"$BRANCH\" = \"master\" ] && [ -z \"$DIRTY\" ]; then git merge --ff-only --quiet origin/master; else echo \"$(date -u +%FT%TZ) SKIP-FF: branch=$BRANCH dirty_lines=$(echo -n \"$DIRTY\" | wc -l)\"; fi; echo \"$(date -u +%FT%TZ) synced: $(ls /home/lucienne/.claude/skills/ | wc -l) skills, $(ls /home/lucienne/.claude/agents/ 2>/dev/null | wc -l) agents, $(ls /home/lucienne/.claude/hooks/ 2>/dev/null | wc -l) hooks (branch=$BRANCH)\" ) 200>/tmp/claude-sync.lock >> /home/lucienne/workspace/logs/claude-sync.log 2>&1","enabled":true,"id":"claude-sync","notify_on":"failure","retry":false,"run_as":"shell","runtime_profile":"direct_shell","schedule":"7,22,37,52 * * * *","tags":["infrastructure","claude","sync"],"timeout":120,"title":"Sync ~/.claude from conrelma/claude repo (pull-only, Mac is source of truth)"}}
