본문으로 건너뛰기
JSL107's Tech Note
돌아가기

AI 개발환경 자동 동기화의 안전 기준

11분 분량이 글 고치기
목차 · 7

저장소를 복제해도 개발 환경까지 그대로 따라오지는 않아요. 대화형 AI 코딩 도구와 코드 중심 AI 개발 도구의 플러그인, MCP, skills, agents, 전역 규칙은 저장소 밖에 있는 각 도구의 홈 디렉터리에 남아 있기 때문이에요.

이 문제를 해결하려고 세 차례에 걸쳐 변경하면서 수동 이식 스크립트를 주기적 스냅샷과 협업 메신저 승인을 거치는 복원 방식으로 확장했어요. 홈 디렉터리 전체를 복사하는 대신 재현에 필요한 자산만 골라내고, 인증 정보와 실행 상태는 제외하는 것이 핵심이었어요.

문제: 저장소 밖의 개발환경은 새 PC로 따라오지 않는다

대화형 AI 코딩 도구 환경을 새 PC로 옮길 때는 세 가지 문제가 있었어요. 플러그인과 MCP 설정이 사용자 홈의 도구별 설정 파일에 있어서 git clone만으로는 복원할 수 없었어요. skills/agents/의 상당수는 다른 디렉터리를 가리키는 심볼릭 링크라 단순히 복사하면 새 PC에서 링크가 끊어졌고, hooks 명령에는 /Users/<사용자> 형태의 절대경로도 들어 있었어요.

코드 중심 AI 개발 도구는 문제가 더 복잡했어요. 도구 홈 디렉터리 안에 옮겨야 할 자산과 옮기면 안 되는 데이터가 뒤섞여 있었어요.

세션과 패키지 캐시는 수 GB에 달했지만 실제로 옮겨야 할 자산은 수 MB에 불과했어요. 디렉터리 전체를 복사하면 불필요한 데이터와 인증 토큰까지 함께 옮겨지고, 새 PC의 런타임이 관리해야 할 영역마저 덮어쓸 수 있었어요.

수동 export 스크립트를 만든 뒤에도 문제는 남았어요. 실행을 잊으면 스냅샷이 금세 낡았고, 여러 PC를 오가며 쓰다 보면 한쪽에서 바꾼 내용이 다른 쪽에 반영되지 않았어요.

접근 1: 대화형 AI 코딩 도구 환경을 목록과 자산으로 분리했다

첫 번째 변경에서는 대화형 AI 코딩 도구 환경을 내보내는 export와 새 PC에 적용하는 bootstrap 스크립트를 추가했어요.

export는 마켓플레이스 출처와 활성 플러그인 ID, 사용자 범위 MCP 정의, hooks를 스냅샷 명세 파일에 기록해요. skills/, agents/, commands/, hooks/는 심볼릭 링크를 따라가 원본 파일을 복사했어요. 새 PC에 없는 원본 경로에 의존하지 않게 하려는 조치였어요.

MCP의 환경 변수와 헤더 값은 키 이름과 관계없이 ${KEY} 형태의 플레이스홀더로 바꿨어요. 필요한 환경 변수와 재인증 항목은 별도의 비밀정보 확인 문서에 기록했어요. Cookie, DSN, ACCESS_CODE처럼 이름만으로 비밀값인지 판단하기 어려운 항목까지 놓치지 않으려는 선택이었어요.

bootstrap은 환경을 아래 순서로 복원해요.

  1. 마켓플레이스 등록
  2. 플러그인 설치
  3. MCP 등록
  4. skills·agents·commands 등 자산 복사
  5. 명시적으로 요청한 경우에만 hooks 적용

플레이스홀더에 필요한 환경 변수가 없으면 해당 MCP만 건너뛰고 이유를 출력해요. 실제 비밀값이 들어간 실행 인자와 화면 표시용 인자도 분리해서 정상 로그와 --dry-run 출력에는 플레이스홀더만 남겼어요.

대상 파일이 이미 있으면 타임스탬프를 붙인 백업 파일로 보존해요. hooks는 세션마다 실행되는 코드라 기본 복원 대상에서 제외했어요. hooks 포함 옵션을 지정해야 적용하며, 기존 hooks를 바꾸려면 교체 옵션까지 명시해야 해요. 적용할 때는 이전 PC의 홈 경로를 현재 홈 경로로 치환해요.

원본 환경의 권한 설정과 기본 실행 모드도 옮기지 않았어요. 기존 PC의 승인 우회 설정이 새 PC로 복사돼 처음부터 승인 게이트가 해제되는 상황을 막기 위해서였어요.

접근 2: 코드 중심 AI 개발 도구는 allowlist 방식으로 확장했다

두 번째 변경에서는 같은 흐름을 코드 중심 AI 개발 도구로 확장하고, 스크립트 이름도 두 도구를 함께 다루는 환경 내보내기 스크립트와 복원 스크립트로 바꿨어요.

코드 중심 AI 개발 도구 설정의 기준은 TOML 형식의 설정 파일이지만 별도의 TOML 의존성은 추가하지 않았어요. 새 PC에서 pnpm install을 실행하기 전에도 쓸 수 있도록 도구 CLI의 JSON 출력을 활용했어요.

ai-dev-cli plugin marketplace list --json
ai-dev-cli plugin list --json
ai-dev-cli mcp list --json

코드 중심 AI 개발 도구에서는 allowlist에 포함된 agents/, skills/, rules/, 전역 지침 파일만 복사했어요. 두 도구가 skills, agents라는 같은 디렉터리 이름을 쓰기 때문에 산출물은 대화형 도구용 디렉터리와 코드 중심 도구용 디렉터리로 나눴어요.

새 PC가 직접 관리해야 할 항목에는 다음과 같은 제외 규칙을 적용했어요.

제외한 항목은 조용히 버리지 않고 이유와 함께 출력했어요. 자동화에서는 항목이 “없다”는 것과 “정책에 따라 제외했다”는 것을 구분할 수 있어야 하니까요.

HTTP MCP의 bearer token은 실제 값 대신 환경 변수 이름만 남겼고, 일반 HTTP header 값도 플레이스홀더로 치환했어요. 다만 도구 CLI가 모든 header 복원 옵션을 제공하지 않으면 MCP를 등록한 뒤 TOML 설정 파일을 수동으로 보완하라는 경고를 표시해요.

두 AI 개발 도구 중 하나만 설치된 PC도 고려했어요. CLI가 없으면 해당 도구의 플러그인과 MCP 등록은 건너뛰지만, 복사할 수 있는 자산은 계속 복원해요.

접근 3: 스냅샷은 자동화하고 복원은 승인받았다

수동 스크립트만으로는 스냅샷이 최신 상태인지 보장할 수 없었어요. 세 번째 변경에서는 기존 cron 시스템에 두 가지 작업을 연결했어요.

두 AI 개발 도구의 홈 디렉터리
↓ 선별·마스킹·링크 실체화
비공개 스냅샷 저장소
↓ 새 커밋 해시 감지
협업 메신저 승인
↓ 승인 커밋 해시 재검증
백업 후 bootstrap

스냅샷 생성 작업은 매주 금요일 19시에 실행돼요. 비공개 저장소를 clone하거나 pull --ff-only로 갱신한 뒤 export를 실행하고, 관리 대상 파일이 바뀌었을 때만 commit과 push를 수행해요. 저장소 origin이 설정과 다르거나 자격 증명 경고가 발견되면 push하지 않아요.

스냅샷 적용 작업은 매일 10시에 새 스냅샷이 있는지 확인해요. 다음 조건에 해당하면 적용하지 않고 이유를 로그에 남겨요.

새 스냅샷을 발견해도 바로 적용하지 않고 협업 메신저에 승인 카드를 만들어요. 카드에는 생성 PC와 시각, 복원할 플러그인·MCP·자산 수, 기존 파일의 백업, hooks를 적용하지 않는다는 사실을 표시해요.

승인한 스냅샷과 적용할 스냅샷을 묶었다

승인을 기다리는 동안 저장소 HEAD가 바뀌면 사용자가 확인한 스냅샷과 실제 적용 대상이 달라질 수 있어요. 초기 구현도 승인 payload의 커밋 해시는 검증했지만 정작 적용할 때는 현재 HEAD를 사용하는 문제가 있었어요.

이 문제를 고쳐 preview를 생성할 때 승인 대상 커밋 해시를 저장하고, 승인 후에는 applyApprovedSnapshot(expectedRevision)을 호출하도록 계약을 바꿨어요. bootstrap 직전에 현재 HEAD와 승인 커밋 해시를 다시 대조하며, working tree가 변경됐거나 커밋 해시가 다르면 실행을 중단하고 재승인을 요구해요.

복원 중 발생한 경고도 성공 메시지에 반영했어요. bootstrap이 프로세스 종료 코드 0을 반환하더라도 일부 MCP가 누락되면 주의 N건 블록을 출력할 수 있어요. 적용 작업은 이 블록과 stderr를 수집하고, 경고가 없을 때만 적용 완료 커밋 해시를 로컬 상태 파일에 기록해요. 경고가 있으면 완료로 처리하지 않으므로 같은 스냅샷을 다시 승인해 재시도할 수 있어요.

이 구조가 복원 과정을 트랜잭션으로 바꾸는 것은 아니에요. 파일을 복사하다 실패해도 자동으로 롤백하지는 않아요. 대신 백업을 남기고 부분 성공을 최종 성공으로 기록하지 않는 데 초점을 맞췄어요.

보안은 “복사하지 않을 것”에서 시작했다

이 작업에서 보안의 핵심은 암호화가 아니라 제외 정책이었어요. 인증 파일과 세션 기록, 개인 기억, 캐시는 스냅샷 대상에서 제외했고, MCP의 환경 변수와 header 값은 플레이스홀더로 바꿨어요. cron 자식 프로세스에는 전체 애플리케이션 환경 변수를 넘기지 않고 기본 allowlist와 스냅샷 명세가 요구하는 값만 전달했어요. 자동 스냅샷은 credential warning이 하나라도 있으면 비공개 저장소에도 push하지 않아요.

다만 수동 export에는 한계가 있어요. URL이나 args에 직접 들어간 자격 증명은 안전하게 재구성하기 어려워 자동으로 제거하지 않고 경고만 표시해요. 수동 산출물도 그대로 공유해서는 안 되며, 경고를 확인하고 비공개 저장소를 사용해야 해요. 테스트에서는 알려진 토큰 패턴과 실제 개인 접근 토큰 문자열이 유출되지 않았지만, 이를 모든 입력과 실패 경로에서 유출이 없다는 완전한 보장으로 받아들여서는 안 돼요.

결과: 복원 절차를 기억하는 대신 검증 가능한 경로를 만들었다

임시 HOME과 도구별 홈 환경 변수를 새 PC처럼 격리해 검증한 결과, 대화형 AI 코딩 도구의 여러 마켓플레이스와 플러그인, MCP, 수백 개의 자산을 복원했어요. 심볼릭 링크는 남지 않았고, hooks에 있던 기존 홈 경로도 치환됐어요.

코드 중심 AI 개발 도구까지 확장해 검증했을 때는 여러 마켓플레이스와 플러그인, MCP를 비롯해 다수의 agents, skills, rules, 전역 지침 파일이 격리 홈에 복원됐어요. 실제 홈의 MCP 상태가 바뀌지 않은 것도 확인했어요. 커밋 해시 불일치와 dirty working tree, 게이트 비활성화, credential warning, origin 불일치, 경고 파싱 같은 실패 경로도 테스트했어요.

그 결과 수작업은 “무엇을 설치했는지 기억해 다시 구성하는 일”에서 “필요한 인증 정보를 입력하고 확인한 스냅샷을 승인하는 일”로 줄었어요. 특히 두 PC를 계속 오갈 때 한쪽의 변경 사항을 주기적으로 스냅샷으로 만들고, 다른 쪽에서 승인해 적용할 수 있는 경로가 생겼어요.

아직 검증하지 못한 범위도 있어요. 실제로 서로 다른 물리 PC와 OS를 사용한 검증, 실제 비공개 저장소의 clone·pull·push, 협업 메신저 카드 생성부터 승인과 bootstrap까지 이어지는 전체 E2E는 수행하지 않았어요. 적용 cron은 대상 PC에 애플리케이션이 이미 설치돼 부팅된 뒤에야 작동하므로, 처음 설치할 때는 bootstrap을 한 번 직접 실행해야 해요.

이번 작업의 결론은 홈 디렉터리를 더 잘 복사하는 방법이 아니었어요. 개발 환경을 재현 가능한 자산과 재발급해야 할 인증, 옮기지 말아야 할 실행 상태로 나누고, 자동화가 로컬 환경을 바꾸는 순간 사용자 승인과 정확한 버전 검증을 다시 거치는 것이었어요.


이 글 고치기
이 글 공유하기:

이전 글
계획을 성과로 오인하지 않는 근거 기반 자동 회고 설계