# 크로스플랫폼 동기화 블루프린트 — GitHub를 "허브"로 쓰기 (iOS ↔ Mac ↔ Windows)
오늘 4VPN(macOS)에 만든 "critical-incidents.json → GitHub → 클라우드 Claude 라우틴" 패턴을
그대로 일반화한 설계도. 세 플랫폼(4VPN macOS, 자매 iOS 앱, 6VPN Windows)이 서로 실시간
소켓 연결 없이도 **GitHub 저장소 하나를 공유 디스크처럼** 써서 데이터를 주고받는 방식이다.
## 핵심 아이디어
각 플랫폼은 서로를 직접 모른다. 대신 전부 **같은 비공개 GitHub 저장소** 하나만 안다.
iOS 앱 ──push/pull──┐ │ Mac(4VPN) ──push/pull─┼──▶ GitHub 비공개 저장소 (source of truth) │ Windows(6VPN)──push/pull┘
- 각자 자기 로컬 상태를 JSON으로 내보내 저장소의 자기 폴더에 커밋·푸시
- 각자 주기적으로 저장소를 pull해서 "다른 플랫폼이 바꾼 것"을 자기 로컬 DB에 반영
- 진짜 실시간이 필요 없는 데이터(차단 규칙·스케줄·프리셋 등)에 적합 — 초 단위 실시간 동기화가
필요하면 이 방식 대신 별도 백엔드(Firebase 등)가 맞다. 지금 4VPN에 쓴 것도 "매일 1회"
수준의 느슨한 동기화다.
## 저장소 구조 (제안)
4vpn-sync/ ← 새 비공개 저장소(코드 저장소와 분리 추천) schema_version.json ← 스키마 버전(플랫폼 간 포맷 안 맞을 때 감지용) mac/ current.json ← Mac이 마지막으로 올린 전체 스냅샷 last_synced_from_others_at.json ios/ current.json last_synced_from_others_at.json windows/ current.json last_synced_from_others_at.json merged/ latest.json ← (선택) 세 플랫폼 병합 결과 — 병합 로직을 한 곳에서만 돌릴 때
코드 저장소(`4vpnBlocker` 등)와 **분리**를 추천 — 동기화 데이터는 계속 바뀌는 런타임 데이터라
소스 코드 히스토리를 오염시키지 않는 게 낫다. 오늘 만든 `critical-incidents.json`은
예외적으로 코드 저장소 안에 둔 것(클라우드 라우틴이 같은 저장소를 이미 보고 있어서) —
버그 리포트처럼 "그 저장소를 고치는 봇이 직접 읽어야 하는" 경우만 코드 저장소에 같이 둔다.
## 플랫폼별 구현
### 1. Mac (4VPN) — 이미 있는 패턴 재사용
`scripts/sync_critical_incidents.sh`가 정확히 이 패턴이다. 같은 구조로
`scripts/sync_blocklist_to_github.sh`를 하나 더 만들면 됨:
```bash
#!/usr/bin/env bash
set -euo pipefail
REPO_DIR="$HOME/4vpn-sync" # 별도 클론
SOURCE_DB="$HOME/Library/Application Support/VeliMac/VeliMac.store"
# 1. 로컬 DB(SwiftData) → JSON export (4VPN 안에 이미 있는 BackupService/Export 로직 재사용)
# 앱이 실행 중이면 HTTP API(localhost:17361)로 내보내기 요청하는 게 안전 —
# .store 파일을 직접 읽으면 앱이 쓰는 중일 때 손상 위험.
curl -s <http://127.0.0.1:17361/export> > "$REPO_DIR/mac/current.json"
cd "$REPO_DIR"
git add mac/current.json
git commit -m "mac sync $(date +%Y-%m-%d_%H:%M)" || true
git pull --rebase origin main
git push origin main
launchd 타이머로 하루 1~2회 실행(오늘 만든 com.rogan.4vpn.bugsync.plist와 동일한 형태,
StartInterval만 조정).
받는 쪽(다른 플랫폼이 바꾼 걸 Mac에 반영): 같은 스크립트가 push 전에 git pull을
먼저 하고, pull된 ios/current.json·windows/current.json을 읽어 4VPN의
/chat/schedule API(오늘 하루 종일 쓴 그 엔드포인트)나 전용 import 엔드포인트로 밀어
넣는다 — 이미 존재하는 프리셋 import 패턴(PremadeBlockPackService)을 그대로 쓸 수 있음.
iOS는 macOS처럼 상시 실행되는 launchd가 없다 — 대신:
URLSession으로 GitHub REST
API(PUT /repos/{owner}/{repo}/contents/ios/current.json, base64 인코딩 + 이전 sha 필요)를
직접 호출 — 별도 git 클론 없이 REST API만으로 커밋 가능(모바일에 git 클라이언트 없어도 됨).BGAppRefreshTask(Background App Refresh)로 하루 1회 정도 예약, 저장소의
mac/current.json·windows/current.json을 GET해서 diff 적용.contents:write 권한만)을
iOS Keychain에 저장 — 코드에 하드코딩 금지.BackupService 계열), export
결과를 로컬 파일 대신 이 GitHub PUT 호출로 바꾸기만 하면 됨 — 새 동기화 엔진을 새로
만들 필요 없음.Mac의 launchd에 대응하는 Windows 표준 도구는 Task Scheduler다:
# scripts/sync_blocklist_to_github.ps1
$RepoDir = "$HOME\4vpn-sync"
$Source = "$HOME\Documents\6 VPN Blocker Backup\current.json"
Copy-Item $Source "$RepoDir\windows\current.json" -Force
Set-Location $RepoDir
git add windows/current.json
git commit -m "windows sync $(Get-Date -Format yyyy-MM-dd_HH:mm)" 2>$null
git pull --rebase origin main
git push origin main
schtasks /create /tn "6VPN Sync" /tr "powershell.exe -File sync_blocklist_to_github.ps1" /sc daily /st 09:00
로 매일 1회 등록. (오늘 6VPN 백업을 iCloud로 내보내던 기존 습관과 같은 결 — 그 폴더를
GitHub로 바꾸는 것뿐.)
세 플랫폼이 동시에 다른 규칙을 추가하면 병합이 필요하다. 오늘 6VPN → 4VPN 임포트 때 쓴 원칙을 그대로 표준화하면 됨:
updatedAt을 반드시 포함.https://github.com/delight0517/4vpnBlocker (이미 존재, 비공개)scripts/sync_critical_incidents.sh + ~/Library/LaunchAgents/com.rogan.4vpn.bugsync.plist4vpn-sync)"는 아직 안 만들었음 — 실제로 진행하고
싶으면 어느 데이터부터(차단 규칙? 스케줄? 프리셋?) 동기화할지 정하고 나서, 위 Mac 스크립트
부터 먼저 만들고 Windows·iOS는 그다음 순서로 붙이는 걸 추천.
[깃허브 토큰](<https://vivid-wave.notion.site/3b26d6203eea80288530d92d7e4573f4>)