ai-rules handbook worktree + develop 자동 병합

worktree + develop 자동 병합

`scripts/sync.mjs --apply` 는 각 target 프로젝트의 working tree 에 규칙 파일을 직접 쓴다. 이 때문에 다음 문제가 있었다.

changes docs/changes/2026-04-15-sync-auto-merge.md

Context

scripts/sync.mjs --apply 는 각 target 프로젝트의 working tree 에 규칙 파일을 직접 쓴다. 이 때문에 다음 문제가 있었다.

  1. 작업 중 오염 — target 프로젝트에서 feature 브랜치 작업 중이면 sync 결과물이 그 working tree 에 섞여 들어간다. 사용자가 stash 를 잊고 커밋하면 엉뚱한 변경이 commit 에 포함된다.
  2. 이력 부재 — 언제 어떤 규칙이 배포됐는지 git 이력에 남지 않는다 (sync-status.json 은 JSON 메타만).
  3. 병합 마찰 — 수동 PR 로 바꾸면 "열어만 두고 까먹는" 현실 문제가 발생한다.

Decision

ai-rules 가 자기 자신에게 sync 할 때 (self-sync) 한정으로 아래 흐름을 적용한다.

  1. .claude/sync-tool-allowlistscripts/sync.mjs 가 등록되어 있으면 예외 경로 활성화
  2. target 의 .git/worktrees-sync/{timestamp} 에 worktree 생성 (본체 working tree 미변경)
  3. worktree 안에서 파일 쓰기 + add + commit (chore(sync): apply ai-rules@{sha})
  4. 본체 developff-only 병합 + push
  5. push 실패 시 로컬 develop 을 병합 전 SHA 로 reset --hard 로 롤백
  6. 병합·push 실패는 feature 브랜치를 살려두고 gh pr create 로 PR 폴백

적용 범위는 ai-rules 프로젝트 자기 자신 에 한정한다. 다른 target 프로젝트 (projectName !== 'ai-rules') 는 기존 직접 복사 경로 유지.

Rationale

  • sync 는 결정론적 스크립트 — LLM 추론이 개입하지 않는다. "빌드 산출물 배포" 범주로 취급할 수 있다.
  • develop 직접 병합은 일반 에이전트 금지 대상 — 하지만 화이트리스트 (.claude/sync-tool-allowlist) 로 예외를 명시적으로 허용하면, 규칙 체계를 깨지 않고 결정론적 배포만 자동화할 수 있다.
  • 왜 PR 폴백이 아니라 자동 병합이 기본인가 — PR 방식은 "열어만 두고 까먹는" 현실 문제가 있다. 규칙 파일의 성격상 빠르게 반영돼야 하며, 충돌은 드물다. 충돌이 있을 때만 PR 폴백으로 전환한다.

Scope

  • 포함: ai-rules → ai-rules 자기 자신 sync (self-sync)
  • 제외: 다른 target 프로젝트 sync, 다른 배포 스크립트, LLM 추론이 개입하는 도구

다른 프로젝트에 워크트리 모드를 확장할지는 별도 PR 에서 판단 한다. 프로젝트마다 develop 운영 방식, push 권한, hook 구성이 달라 일괄 적용이 적절하지 않다.

Safeguards

  1. 화이트리스트 게이트.claude/sync-tool-allowlist 없거나 호출자 미등록 시 worktree 모드 진입 자체를 하지 않는다 (= 기존 직접 복사 경로).
  2. preflight 검증 — git repo / origin / develop 브랜치 / fetch 성공 모두 통과해야 worktree 모드 진입. main/master 만 있는 프로젝트는 거부.
  3. 본체 dirty 거부 — target 본체 working tree 가 dirty 면 develop checkout 불가로 보고 중단한다 (사용자가 직접 처리할 시점).
  4. ff-only 제한merge --ff-only 만 허용. rebase·--no-ff 자동 시도 없음.
  5. push 실패 롤백 — push 가 rejected 되면 로컬 develop 을 병합 전 SHA 로 reset --hard 한다.
  6. PR 폴백 — 어느 단계든 실패하면 feature 브랜치(sync/ai-rules-{timestamp}) 를 살려두고 gh pr create 로 PR 생성. gh 가 없으면 브랜치 이름을 로그로 남김.
  7. cleanup 보장 — worktree 제거는 try/finally 에서 수행. git worktree remove --force 실패 시 디렉토리 직접 삭제 후 worktree prune.
  8. 원래 브랜치 복원 — 본체 checkout 을 develop 으로 옮겼을 때, 작업 완료 후 finally 에서 원래 브랜치로 되돌린다.

Alternatives Considered

  • B안 — PR 까지만 생성 (자동 병합 없음): 안전하지만 "PR 열어만 두고 까먹는" 현실 문제가 해결되지 않는다. 규칙 파일이 늦게 반영되면 애초에 이 도구의 존재 이유가 옅어진다. 기각.
  • C안 — 모든 target 에 일괄 적용: target 마다 develop 정책, hook, CI 가 다르다. 한 번에 확장하면 실패 지점이 너무 많다. 기각 (향후 개별 PR 로 평가).
  • D안 — 현 직접 복사 유지: 본 문서의 Context 에서 나열한 세 가지 문제가 해결되지 않는다. 기각.