Cursor Origin API 변경에 대비하는 에이전트 식별과 PR 병합 점검법
2026년 10월 9일에는 작업 주체의 식별 방식이, 8일에는 브랜치와 스택 관계가 맞지 않는 PR의 병합 조건이 바뀌었다. Origin 연동팀이 먼저 살펴볼 곳은 봇 분류 코드와 자동 병합의 실패 처리다.
개정 1판 · 최근 고침: Origin 공식 변경 로그와 API 계약을 대조하고 행위자 식별·대리 실행·스택 병합의 이관 점검 원고를 추가했습니다. · 고침 기록 보기
Origin API 연동자를 위한 Early Beta 변경 해설입니다. 가상 PR 사례·테스트 계획·코드는 설명용이며 실제 API 호출이나 고객 장애의 관찰 결과가 아닙니다.
Origin 연동팀이 먼저 확인할 범위
코드를 검토하는 봇이 갑자기 활동 집계에서 사라지거나, 어제까지 통과하던 병합 요청이 HTTP 400으로 돌아온다면 개발팀은 인증과 서버 상태부터 확인하기 쉽다. 그러나 연동 대상의 데이터 계약이 바뀐 경우에는 정상적인 응답을 기존 프로그램이 잘못 해석하고 있을 수 있다. Cursor Origin을 연결한 대시보드와 병합 봇은 이번 변경에서 이 가능성을 먼저 확인할 필요가 있다.
Origin은 Cursor가 제공하는 코드 저장·협업용 Git 서비스다. 저장소 호스팅, GitHub 미러링, PR 검토와 병합 등을 지원하며 현재 Early Beta 단계다. 따라서 이번 소식의 직접적인 대상은 Origin API를 사용하는 연동이다. Cursor 편집기 전체 사용자에게 새 코딩 기능이 일괄 배포됐다는 의미로 읽으면 범위가 달라진다. Origin 공식 소개
이 글에서는 공식 변경 사항을 짚은 뒤, 이를 기존 프로그램에 적용하는 방법을 제안한다. 아래 가상 사례와 점검 절차는 마탑의 적용 제안이며 실제 고객의 장애 사례나 실행 결과가 아니다.
이 절의 근거 S171
먼저 알아둘 두 날짜의 변경
10월 9일 변경은 PR·리뷰·댓글·반응의 행위자 표시에 관한 것이다. Cursor가 수행한 작업을 공용 앱 식별자인 origin-cursor-managed-actor로 묶던 부분에서 실제 서비스 계정을 드러내도록 바뀌었다. 계정은 serviceAccount.id와 type으로 구분한다. Cursor 자체 앱은 app으로 나타나며 사용자가 서비스 계정을 통해 행동한 경우에는 performedVia에 그 경로가 담긴다. 웹훅과 check run은 이미 계정을 구분하고 있었다. 10월 9일 Origin API 변경 로그
10월 8일에는 병합 거부 조건이 추가됐다. 병합 도착점의 base가 다른 열린 PR 또는 초안 PR의 head인 경우를 보자. 해당 PR과 스택 관계가 없으면 FailedPrecondition, HTTP 400으로 거부되고 아무것도 병합되지 않는다. 스택에서는 실제 병합이 도착하는 base가 판단 기준이다. 기본 브랜치에는 예외가 있다. 활성 push_branch 규칙 집합의 deletion 규칙이 includedRefNames로 지정한 브랜치도 예외에 해당한다. mergeability 응답에는 needs_restack이 표시된다. 10월 8일 Origin API 변경 로그
변경 로그가 안내하는 대응은 기존 공용 식별자 비교를 계정 ID 또는 유형 판별로 옮기고 병합 문제는 base를 소유한 PR을 먼저 병합하거나 적절한 부모 PR과 연결하는 것이다. 두 변경 모두 호환성을 깨는 항목으로 분류돼 있다. Origin API 변경 로그
이 절의 근거 S170
| 날짜 | 변경 | 이관 방향 |
|---|---|---|
| 2026-10-09 | 공용 앱 ID 대신 serviceAccount 계정 ID·type을 표시 | serviceAccount.id 또는 type으로 분류하고 performedVia를 보존 |
| 2026-10-08 | 다른 열린·초안 PR의 head가 실제 도착 base이며 스택 관계가 없으면 HTTP 400, 병합 없음 | base를 소유한 PR을 먼저 병합하거나 parentPullRequest 연결 검토 |
표를 글로 읽기
10월 9일 행위자 식별 변경과 10월 8일 스택 관계가 없는 병합 거부 조건을 나란히 보여주는 표다.
화면에 보이는 이름과 프로그램이 비교할 키를 나눈다
첫 점검 대상은 저장소 안의 origin-cursor-managed-actor 문자열이다. API 클라이언트뿐 아니라 알림 라우팅, 데이터베이스 변환, 통계 쿼리, 테스트 fixture까지 함께 찾는 것이 좋다. 같은 문자열이 여러 곳에 흩어져 있다면 한 곳만 고쳐서는 데이터 수집은 살아나도 보고서의 분류는 계속 틀릴 수 있다.
마탑의 권장 설계는 식별, 분류, 표시를 각각 맡기는 것이다. 특정 계정의 활동을 이어 붙이는 데에는 ID를 쓰고 제품별 활동을 집계할 때는 유형을 쓰며 사람에게 읽기 좋은 이름은 화면에 표시한다. 예를 들어 같은 이름으로 표시되는 작업을 하나의 계정으로 합치면 서로 다른 자동화의 이력이 뒤섞일 수 있다. 반대로 특정 계정 ID만으로 제품 전체를 집계하면 새 계정이 생겼을 때 누락될 수 있다.
공식 레퍼런스의 서비스 계정 유형에는 bugbot, automations, agent_serve, agent, grok_bot, env_builds가 있다. 유형은 추가되거나 비어 있을 수 있으므로 알 수 없는 값을 오류로 취급하지 않도록 안내한다. PR 목록의 author 필터에는 응답에서 받은 sa_… 또는 app_… ID를 사용할 수 있다. Origin API의 행위자와 PR 목록 계약
다음 JavaScript 예시는 응답에서 행위자의 기본 키를 추출한다. 특정 제품명을 모두 나열하지 않아도 계정 식별을 계속할 수 있도록 구성했다.
function actorKey(actor) {
if (actor?.user?.id) return `user:${actor.user.id}`;
if (actor?.serviceAccount?.id) {
return `serviceAccount:${actor.serviceAccount.id}`;
}
if (actor?.app?.id) return `app:${actor.app.id}`;
return null;
}이 절의 근거 S172
미분류 행위자와 원본 유형을 남기는 이유
이는 완성된 보안 판정 코드가 아니다. 응답을 저장하는 애플리케이션의 작은 보조 함수다. null은 이름을 임의로 만들어 채우기보다 별도의 미분류 상태로 처리하는 편이 낫다. 또 수집기가 모르는 유형을 받았다고 이벤트 전체를 버리지 말고 식별 가능한 ID와 원래 유형을 보존하는 방식을 검토할 수 있다. 그래야 나중에 분류 규칙을 추가했을 때 수집 당시의 정보를 다시 활용할 수 있다.
이 절의 근거 S172
사람의 행동과 행동을 도운 도구를 따로 기록한다
행위자를 정규화할 때 특히 조심할 부분은 대리 실행이다. 사용자가 앱을 통해 댓글을 작성했다면 원래 사용자를 지우고 앱 이름으로 덮어쓰는 방식은 감사 기록을 단순화하는 대신 중요한 맥락을 잃는다.
Cursor의 대리 실행 문서는 행위자 필드가 사용자를 나타내며 performedVia.app에 앱 정보가 들어갈 수 있다고 설명한다. 이 정보는 해당 필드가 나타내는 행동에 귀속된다. 댓글 작성자의 대리 실행 정보로 나중의 편집자를 알아낼 수는 없다. 또한 performedVia가 없다는 사실만으로 모든 경우에 직접 실행이라고 확정할 수도 없다. 위임 정보가 제공되지 않은 경우에도 빠질 수 있기 때문이다. Acting on behalf of users
이를 바탕으로 사내 로그에는 ‘행위자 ID’, ‘대리 실행 경로’, ‘행동 종류’를 별도로 두는 방법을 권한다. 예를 들어 댓글 작성과 댓글 수정은 서로 다른 사건으로 취급하고 원래 작성자를 수정 행위자로 재활용하지 않는다. 이는 Origin만을 위한 특수한 보고서 설계가 아니라 자동화와 사람의 작업이 섞이는 시스템에서 유용한 기본 원칙이다.
가상의 운영팀이 매주 ‘사람이 작성한 PR’과 ‘자동화가 작성한 PR’을 집계한다고 해보자. 기존 보고서가 앱 표시 이름만 보았다면 새 구조를 적용한 다음 주에 두 집계가 갑자기 달라질 수 있다. 이때 증가분을 곧바로 자동화 성과로 발표해서는 안 된다. 같은 자료를 구형 규칙과 신형 규칙으로 각각 분류해 차이가 실제 활동 변화인지 분류 변경인지 확인해야 한다.
과거 데이터를 새 이름으로 전부 덮어쓰는 것도 피하는 편이 좋다. 보관 기간과 개인정보 최소화 원칙은 팀의 기존 정책을 따르되, 적어도 집계 결과만 남겨 원인을 영구히 잃는 상황은 막을 필요가 있다. 수집 시점과 분류 규칙의 버전을 함께 남기면 이전 보고서와 숫자가 다른 이유를 설명하기 쉽다.
이 절의 근거 S173
그림을 글로 읽기
행위자 응답에서 계정 식별, 제품 분류, 화면 표시로 갈라지고 대리 실행 경로를 별도 기록으로 남기는 도식이다.
needs_restack을 재시도 대기열로만 보내지 않는다
병합 쪽 문제는 가상의 두 PR로 생각하면 명확하다. PR 41이 결제 모듈의 기초 변경이고 PR 42가 그 위에 붙는 화면 변경이라고 하자. 42의 base가 41의 head 브랜치를 가리키지만 서비스에 저장된 두 PR의 연결 관계가 없다면, 운영자는 ‘함께 검토하는 연속 작업’으로 생각하고 시스템은 별개의 PR로 볼 수 있다.
이때 동일한 병합 요청을 잠시 뒤 다시 보내는 방식은 관계 불일치를 해결하지 못한다. 담당자는 최종 도착 브랜치, 실제 의존성, 먼저 병합해도 되는 변경의 범위를 확인해야 한다. 두 작업이 의존 관계라면 스택 연결을 검토하고 독립 작업이라면 잘못된 base 설정이나 브랜치 구성을 고치는 편이 맞다. 응답 이름에 restack이 들어간다고 모든 상황에서 같은 Git 명령을 자동 실행하는 것은 위험하다.
API의 parentPullRequest 변경은 PR 간 연결만 수정하며 브랜치를 재작성하지 않는다. base를 함께 보내지 않으면 base도 그 요청 때문에 바뀌지 않는다. 부모 선택자는 number, id, clear: true 중 하나만 지정한다. 또한 앞서 언급한 보호 예외에서 모든 브랜치를 가리키는 ~ALL 같은 패턴은 인정되지 않는다. Update Pull Request와 Merge Pull Request 레퍼런스
부모 PR 번호를 설정하는 요청 본문은 다음처럼 짧다. 아래는 PR 42를 41에 연결하려는 경우의 문서 기반 예시이며 실제 저장소에 요청하지 않았다.
PATCH /v1/origin/repos/OWNER/REPO/pulls/42
Content-Type: application/json
{"parentPullRequest":{"number":"41"}}이 절의 근거 S172
그림을 글로 읽기
병합 도착 base 확인에서 열린·초안 PR의 head와 스택 관계 및 보호 예외를 점검하고, needs_restack이면 사람 검토와 재확인으로 이어지는 도식이다.
연결 뒤에는 실제 병합 범위를 다시 확인한다
짧은 요청이라고 영향도 작은 것은 아니다. API는 스택의 특정 PR을 병합할 때 스택 루트부터 해당 PR까지의 미병합 PR들을 함께 반영한다. 따라서 연결 전후에는 대상 목록과 도착 브랜치를 다시 읽어 검토해야 한다. Merge Pull Request와 Get Pull Request Mergeability
운영 관점에서는 병합 실패 메시지에 PR 번호만 보여주기보다 ‘어느 변경들과 함께 어디로 병합하려 했는지’를 같이 보여주는 편이 유용하다. 담당자가 화면을 여러 번 오가며 관계를 추측하지 않아도 되기 때문이다. 보호 규칙을 새로 추가해 오류만 없애는 방식은 추천하기 어렵다. 브랜치 보호는 팀 정책으로 결정하고 자동화의 모델이 잘못된 경우에는 그 모델부터 고쳐야 한다.
이 절의 근거 S172
사전 확인과 실제 병합 사이의 시간도 테스트한다
Origin 릴리스 노트는 병합 가능 여부를 조회하는 preview API와 예상 head 커밋을 이용한 확인을 설명한다. 이후에는 병합 가능성 응답에 평가한 head 커밋을 포함하고 현재 base를 기준으로 테스트 병합을 준비하는 기능도 소개했다. 즉 사전 조회가 어느 상태를 대상으로 한 판단인지 확인할 수 있는 단서가 있다. Origin 공식 릴리스 노트
마탑의 권장 흐름은 조회, 판단, 실행, 재확인을 한 작업으로 취급하는 것이다. 사전 조회가 끝난 뒤 다른 개발자가 코드를 밀어 넣을 수 있으므로, 조회 성공을 무기한 유효한 허가증처럼 저장하지 않는다. 사람이 승인하는 과정이 길어질수록 최종 실행 직전에 다시 확인할 필요가 커진다.
상태 화면도 이를 반영해야 한다. ‘병합 가능’ 옆에 평가 시점을 표시하고 새 코드가 올라왔다는 사실을 알게 되면 오래된 결과를 그대로 녹색으로 유지하지 않는 식이다. 실패 결과를 처리할 때는 통신 재시도가 필요한지, 데이터 재조회가 필요한지, 사람이 관계를 결정해야 하는지를 나눈다. 모든 실패를 빨간색 알림 하나로 묶으면 담당자는 매번 같은 조사 과정을 반복하게 된다.
이 절의 근거 S174
기존 연동에 적용할 테스트 계획
다음 항목은 배포 전 검증을 위한 제안이다. 팀의 테스트 저장소와 비식별 fixture를 이용하고 실제 운영 PR의 관계를 임의로 바꾸어 확인하지 않는 것이 좋다.
1. 수집 경로를 끝까지 비교한다. 같은 종류의 작업에 대해 API로 읽은 결과와 웹훅을 처리한 결과가 내부 저장 형식에서 어떻게 달라지는지 확인한다. 수집 성공 여부뿐 아니라 이후 알림·집계에 들어가는 키까지 살펴본다.
2. 낯선 행위자를 넣어본다. 일반 사용자, 앱, 서비스 계정, 처음 보는 유형, 정보가 빠진 행위자를 각각 fixture로 만든다. 알려진 값만 통과시키는 분기 때문에 전체 이벤트가 사라지는지 점검한다.
3. 대리 실행을 별도 사례로 둔다. 사용자와 도구가 함께 나타날 때 원래 사용자가 보존되는지 확인한다. 댓글 작성과 수정을 같은 행동으로 취급하는 코드가 없는지도 살펴본다.
4. 병합 대상의 관계를 조합한다. 기본 브랜치로 가는 독립 PR, 의존 PR과 제대로 연결된 경우, 다른 PR 브랜치를 base로 삼지만 연결되지 않은 경우를 구분한다. 실패가 예상되는 경우에는 대상 브랜치가 바뀌지 않았는지도 확인한다.
5. 변경 도중의 상태를 만든다. 사전 확인 후 head 또는 base가 움직이는 경우, 부모 PR의 상태가 달라지는 경우를 시험한다. 오래된 화면을 믿고 실행하는 경로와, 실패 뒤 같은 요청만 반복하는 경로를 찾는다.
6. 통계를 병행 계산한다. 전환 전후 집계를 일정 기간 함께 계산하고 차이가 생기는 레코드를 추적한다. 오류율뿐 아니라 미분류 건수와 분류 비율도 살펴야 조용한 누락을 찾을 수 있다.
회귀 테스트의 성공 기준은 ‘새 응답이 예외 없이 파싱된다’에서 끝나지 않는다. 누가 한 일인지 유지되고 잘못된 병합을 시도하지 않으며 멈췄을 때 담당자가 이유를 이해할 수 있어야 한다. 기존 테스트에 이 세 관점을 더하면 스키마 변경 대응이 운영 품질 개선으로 이어진다.
이 절의 근거 S172
| 상황 | 확인할 결과 |
|---|---|
| 처음 보는 serviceAccount.type | 이벤트와 ID·원래 유형이 보존되고 미분류 상태를 추적할 수 있다 |
| 사용자와 performedVia가 함께 존재 | 원래 사용자와 도구 경로를 별도로 남긴다 |
| 다른 열린 PR head가 base, 스택 관계·예외 없음 | needs_restack 및 HTTP 400, 대상 브랜치는 병합으로 바뀌지 않는다 |
| 사전 조회 뒤 head·base 또는 부모 상태 변경 | 오래된 조회를 승인처럼 재사용하지 않고 최신 대상과 상태를 확인한다 |
| GitHub 미러 저장소 | GitHub가 PR 원본임을 유지하고 네이티브 Origin 병합 경로와 구분한다 |
표를 글로 읽기
낯선 행위자와 대리 실행, 스택 관계 불일치, 사전 조회 이후 변경, 미러 저장소에서 각각 확인할 결과를 정리한 표다.
팀마다 대응의 깊이는 달라도 된다
Origin API로 활동을 읽어 통계만 만드는 팀은 행위자 정규화와 기존 수치의 연속성을 먼저 볼 수 있다. 기능을 한꺼번에 바꾸기보다 수집 원본과 분류 결과를 비교하는 방식이 부담이 적다. 자동 병합을 하지 않는다면 스택 관계를 수정하는 쓰기 권한까지 확대할 이유는 없다.
반대로 PR을 생성하고 병합까지 수행하는 플랫폼팀은 실패 처리와 승인 화면을 우선 확인하는 편이 낫다. 어떤 기준으로 부모를 선택하고 병합 대상이 늘어났을 때 누구에게 보여주며 자동으로 해결하지 못하는 상태를 어디서 멈출지 정해야 한다. 작은 테스트가 통과했다는 이유만으로 모든 저장소에 즉시 적용하기보다는 영향이 제한된 저장소부터 관찰할 수 있다.
GitHub를 미러링해 쓰는 팀은 저장소의 작업 경로부터 구분해야 한다. 공식 PR 안내에 따르면 미러링 저장소의 PR은 GitHub가 원본이며 연결된 클라우드 에이전트도 GitHub PR을 만든다. 화면에 Origin 저장소가 보인다는 이유만으로 네이티브 Origin용 병합 흐름을 적용해서는 안 된다. Origin의 PR와 미러링 안내
신규 연동을 만드는 팀이라면 설정 위치와 인증 모델도 함께 확인하자. 공식 안내는 비공개 Origin 앱을 만들어 API를 연결하고 앱 JWT와 installation access token을 사용한다고 설명한다. 이번 호환성 변경을 해결하려고 인증 자체를 임의로 바꾸기보다는, 기존 연동의 설치 범위와 필요한 작업을 먼저 목록화하는 편이 좋다. Origin Apps
이번 주의 우선순위
팀이 당장 잡을 수 있는 작업은 두 가지다. 공용 행위자 ID에 의존한 코드를 찾아 계정과 대리 실행의 의미를 보존하도록 바꾸고 병합 자동화가 브랜치 이름과 PR 관계를 함께 검토하도록 만드는 것이다. 새 필드를 추가하는 데서 끝내지 말고 정보가 낯설거나 관계가 어긋났을 때 프로그램이 어떻게 멈추는지도 확인해야 한다.
Origin이 Early Beta라는 조건은 변경을 무시할 이유도, 곧바로 전면 도입할 이유도 되지 않는다. 이미 연결한 팀은 자신의 코드가 의존하는 계약을 점검하고 도입을 검토하는 팀은 운영 부담까지 시험하면 된다. 이번 두 변경을 계기로 수집·판단·실행을 각각 살펴보면, 다음 API 변경이 왔을 때 수정할 곳과 검증할 범위도 훨씬 선명해질 것이다.
이 절의 근거 S172
근거 출처 7건
- [1] 10월 8·9일 breaking changes의 행위자와 병합 조건
Origin API Changelog (외부)
Cursor Docs · 2026-10-09 - [2] Early Beta Git forge의 제공 범위
Origin (외부)
Cursor Docs - [3] 행위자·PR 목록·부모 연결·병합·mergeability 계약
Origin API reference (외부)
Cursor Docs - [4] 사용자 행위자와 대리 실행 귀속·정보 누락 의미
Acting on behalf of users (외부)
Cursor Docs - [5] preview mergeability와 평가 head, test merge ref
Origin release notes (외부)
Cursor Docs - [6] 네이티브 Origin과 GitHub 미러의 PR 원본 구분
Pull requests (외부)
Cursor Docs - [7] 비공개 앱·app JWT·installation access token
Origin Apps (외부)
Cursor Docs
함께 읽기
- 검토 게이트와 병합: 기록에서 머지 큐까지 (개념 뼈대 · PR 검토 게이트와 병합 대기열)
- 도메인 경계와 영향 범위 CI: 작은 변경을 작게 검증하기 (개념 뼈대 · 변경 영향과 회귀 테스트)
- 에이전트와 도구 사용 (개념 뼈대 · 에이전트와 도구 사용)