Dependabot이 11월 3일부터 apm.yml의 스킬 업데이트 PR을 연다. 이 PR에는 태그와 해시만 바뀌고 새 지시문 본문은 diff에 없다. 자동 병합에서 apm을 빼고, 필수 검사에 apm install --frozen을 건다.
팀이 Claude Code나 Copilot 스킬을 같이 쓰기 시작하면 곧 버전이 갈린다. Microsoft가 공개한 APM(Agent Package Manager)은 이 문제를 npm 방식으로 푼다. apm.yml에 스킬·프롬프트·지시문 저장소를 적고, apm.lock.yaml에 커밋과 내용 해시를 고정한다. 업무 매뉴얼이 설치 파일이 됐다에서 다룬 흐름에 버전 관리가 붙었다.
GitHub 11월 3일 공지로 Dependabot 버전 업데이트가 APM을 지원한다. .github/dependabot.yml에 apm 항목 하나를 넣으면 Dependabot이 apm.yml의 git 의존성을 올리는 PR을 열고, 잠금 파일이 있으면 다시 만든다. github.com의 모든 플랜에서 쓸 수 있다.
남는 질문은 승인이다. 스킬 PR에서 바뀌는 것은 에이전트가 따를 문장이다. 승인자는 그 문장을 어디서 읽는가.
Dependabot의 APM PR은 무엇이 바뀌었는지가 아니라 바뀌었다는 사실만 보여준다
GitHub Docs 생태계 문서(11월 4일 기준)는 apm.yml의 고정 방식마다 Dependabot이 하는 일을 나눠 적었다.
| apm.yml 고정 방식 | Dependabot이 하는 일 | PR에서 바뀌는 파일 |
|---|---|---|
SemVer 태그 #v1.0.0 | 최신 SemVer 태그로 이동 | apm.yml 태그, 잠금 파일 |
| 40자 커밋 SHA | 최신 정식 릴리스 태그(프리릴리스 제외)의 커밋으로 이동, 태그명 주석 추가 | apm.yml SHA, 잠금 파일 |
브랜치 #main | 브랜치 최신 커밋으로 이동 | 잠금 파일만 |
| ref 없음 | 건너뜀 | PR 없음 |
잠금 파일은 Dependabot이 apm lock을 돌려 다시 만든다. APM 공식 문서의 apm lock 설명에 따르면 이 명령은 의존성을 내려받아 커밋 SHA와 내용 해시를 고정하지만, 파일을 배포하지도 지우지도 않고 감사(audit) 단계를 건너뛴다. 그래서 PR의 변경 파일에 .agents/skills/나 .github/ 아래 실제 지시문은 들어오지 않는다. 리뷰어 화면에는 바뀐 태그나 SHA, 잠금 파일의 커밋 값과 해시 값만 남는다.
스킬 업데이트를 판단할 근거는 우리 저장소가 아니라 스킬을 올린 업스트림 저장소에 있다.
숨은 문자 검사는 설치할 때 돌고, Dependabot은 설치하지 않는다
APM 공식 문서의 apm install 설명에 따르면 설치 때 배포할 파일에서 숨은 유니코드, 태그 문자, 양방향 재정렬(bidi override) 패턴을 찾고, 심각 등급이 나오면 그 패키지를 막고 종료 코드 1로 끝낸다. The Hacker News 2025년 3월 보도에서 Pillar Security는 Copilot과 Cursor의 규칙 파일에 폭 없는 결합 문자와 양방향 표시로 지시문을 숨기는 방법을 공개했고, GitHub은 제안을 검토하는 것은 사용자 몫이라고 답했다.
Dependabot PR은 이 검사 없이 열린다. CI에 설치 단계가 없다면 검사는 병합 뒤 누군가 apm install을 돌릴 때 처음 돈다. 눈에 보이는 문장으로 적힌 위험한 지시는 숨은 문자 검사가 잡지도 못한다.
APM 공식 문서의 apm audit 설명은 apm audit --ci를 브랜치 보호 검사로 소개하면서도, 배포 산출물을 커밋하지 않는 저장소라면 전체 설치를 돌리는 CI를 권한다. 스킬 PR의 필수 검사는 apm install --frozen으로 새 고정값을 설치해 숨은 문자를 먼저 걸러 낸 뒤 apm audit --ci를 돌리는 순서가 맞다.
코드용 자동 병합 조건은 스킬 PR을 가려내지 못한다
GitHub Docs의 Dependabot 자동 병합 예시는 dependabot/fetch-metadata가 돌려준 dependency-names와 update-type(version-update:semver-patch)으로 병합 대상을 고른다. 스킬 저장소가 v1.4.0에서 v1.4.1로 올라갈 때, 그 패치가 오타 수정인지 지시 한 줄 추가인지 버전 번호는 말해 주지 않는다. ref 없이 적은 항목과 mcp: 아래 MCP 서버, Azure DevOps에 둔 항목은 아예 건너뛰므로 Dependabot이 조용하다고 스킬이 최신인 것도 아니다.
가져갈 것
-
.github/dependabot.yml의apm항목에 별도labels(예:agent-skill)를 달았고, 자동 병합 워크플로가 이 라벨이 붙은 PR을 건너뛰는가? - apm.yml에서
#main처럼 브랜치로 고정한 스킬을 세어 봤는가? 이 스킬의 PR에는 apm.yml 변경이 없다. - 리뷰어가 apm.lock.yaml의 이전·새 커밋 SHA로 업스트림 저장소의
compare/<이전 SHA>...<새 SHA>화면을 열어 SKILL.md와*.instructions.md변경을 읽는가? - 브랜치 보호의 필수 검사에
apm install --frozen다음apm audit --ci를 돌리는 잡이 있는가? - ref 없는 항목과
mcp:서버를 올릴 담당자와 주기를 정해 두었는가?
안 되는 경우
- APM 없이 SKILL.md를 저장소에 직접 복사해 커밋하는 팀에는 해당하지 않는다. 그 구조에서는 스킬 변경이 일반 PR diff에 본문째 보인다.
- GitHub Enterprise Server는 3.24에서 지원할 예정이고 날짜는 공지에 없다.
git:맵 형태로 적은 항목도 Dependabot이 갱신하지 않는다. - 소스가 밝히지 않은 것: Dependabot의 APM PR 본문에 업스트림 릴리스 노트나 커밋 목록이 붙는지는 공지와 문서에 없다. 붙는다면 비교 화면을 여는 수고가 준다.
apm audit --ci의 숨은 문자 검사가 커밋하지 않은 산출물을 어디까지 덮는지도 문서에 분명하지 않다.
이번 주에는 CODEOWNERS에 apm.yml과 apm.lock.yaml 두 줄을 넣고 브랜치 보호의 코드 소유자 리뷰 필수를 켠다. 자동 병합 워크플로를 고치기 전이라도 스킬 PR은 업스트림 비교 화면을 읽은 소유자가 승인할 때까지 기다린다.